Skocz do zawartości

Kurs Arduino II - #6 - wyświetlacze 7-segmentowe


Pomocna odpowiedź

Cześć, postanowiłem zmodyfikować trochę kod, w którym zastosowaliśmy multipleksowanie wyświetlacza tak, że:

  • używając potencjometru podłączonego w roli konwertera ADC regulujemy częstotliwość odświeżania wyświetlacza (co pozwala łatwiej zaobserwować bezwładność naszego wzroku)
  • wyświetla on liczby z zakresu 1-99, a w przypadku podania nieodpowiedniej liczby / ciągu znaków program prosi nas o podanie prawidłowej wartości

Podłączenia takie same, jak w kursie. Dołączam również kod programu:

#define potentiometer A5 // Defines pin used to control the frequency

#define firstDisp 10 // Defines pins used for multiplexing method
#define secondDisp 9

#define rightDown 2 // Defines all pins (according to pinout and segments)
#define leftDown 3
#define Down 4
#define rightUp 5
#define Middle 8
#define Up 7
#define leftUp 6

int delayTime = 0; // Variable used for ADC converter measurement

byte firstNumber = 0; // Variables used to store currently displayed numbers
byte secondNumber = 0;

String receivedString = ""; // Variables used to "decode" and show number sent by user
int receivedInt = 0;
byte nextNumber = 0;

void setup() {
  Serial.begin(9600); // Initializes UART communication
  
  pinMode(firstDisp, OUTPUT); // Initializes both displays
  pinMode(secondDisp, OUTPUT);
  
  pinMode(Up, OUTPUT); // Initializes particular segments of the displays
  pinMode(leftUp, OUTPUT);
  pinMode(rightUp, OUTPUT);
  pinMode(Middle, OUTPUT);
  pinMode(Down, OUTPUT);
  pinMode(leftDown, OUTPUT);
  pinMode(rightDown, OUTPUT);

  // Initial animation
  
  digitalWrite(firstDisp, HIGH); // Turns both displays on
  digitalWrite(secondDisp, HIGH);
  
  digitalWrite(Up, HIGH); // Checks if every diode works correctly
  delay(200);
  digitalWrite(leftUp, HIGH);
  delay(200);
  digitalWrite(rightUp, HIGH);
  delay(200);
  digitalWrite(Middle, HIGH);
  delay(200);
  digitalWrite(Down, HIGH);
  delay(200);
  digitalWrite(leftDown, HIGH);
  delay(200);
  digitalWrite(rightDown, HIGH);

  delay(200);

  clearAll();
  digitalWrite(firstDisp, LOW);
  digitalWrite(secondDisp, LOW);

  Serial.println("Give any number in range 0-99 and I'll show it on the display. For 0, type zero.");
}

void loop() {
  delayTime = analogRead(potentiometer); // Reads the value from potentiometer
  delayTime = map(delayTime, 0, 1023, 5, 1000); // Converts the measurement into time in miliseconds

  if (Serial.available() > 0) { // If data has been received
    receivedString = Serial.readStringUntil("\n"); // Reads incoming data as String
      receivedInt = receivedString.toInt(); // Converts incoming data into integer
      if ((receivedInt > 0) and (receivedInt < 100)) { // If converted data is in given 10-99 range:
        Serial.println(receivedInt); // Shows given number on Serial Monitor
        secondNumber = (receivedInt % 10); // Reads the second number
        receivedInt = (receivedInt / 10); // Moves the whole number one decimal place right
        firstNumber = (receivedInt % 10); // Reads the first number
      } else {
        Serial.println("Invalid number, please, try again.");
    }
  }
  digitalWrite(firstDisp, HIGH); // First display is on
  digitalWrite(secondDisp, LOW); // Second is off
  showNumber(firstNumber); // This number is shown on first display
  delay(delayTime); // Waits for some time
  digitalWrite(firstDisp, LOW); // First display is off
  digitalWrite(secondDisp, HIGH); // Second is on
  showNumber(secondNumber); // This number is shown on second display
  delay(delayTime); // Waits for some time
}

void clearAll() { // Function that clears the display
        digitalWrite(Up, LOW);
        digitalWrite(leftUp, LOW);
        digitalWrite(rightUp, LOW);
        digitalWrite(Middle, LOW);
        digitalWrite(Down, LOW);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, LOW);
}

void showNumber(byte number) { // Function that displays given single number on the display
  switch (number) {
    case 0:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, HIGH);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, LOW);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, HIGH);
        digitalWrite(rightDown, HIGH);
    break; 
    
    case 1:
        digitalWrite(Up, LOW);
        digitalWrite(leftUp, LOW);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, LOW);
        digitalWrite(Down, LOW);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, HIGH);
    break; 
    
    case 2:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, LOW);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, HIGH);
        digitalWrite(rightDown, LOW);
    break; 
    
    case 3:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, LOW);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, HIGH);
    break; 
    
    case 4:
        digitalWrite(Up, LOW);
        digitalWrite(leftUp, HIGH);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, LOW);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, HIGH);
    break; 
    
    case 5:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, HIGH);
        digitalWrite(rightUp, LOW);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, HIGH);
    break; 
    
    case 6:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, HIGH);
        digitalWrite(rightUp, LOW);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, HIGH);
        digitalWrite(rightDown, HIGH);
    break;
   
    case 7:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, LOW);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, LOW);
        digitalWrite(Down, LOW);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, HIGH);
    break;
    
    case 8:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, HIGH);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, HIGH);
        digitalWrite(rightDown, HIGH);
    break;
    
    case 9:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, HIGH);
        digitalWrite(rightUp, HIGH);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, HIGH);
    break;

    default:
        digitalWrite(Up, HIGH);
        digitalWrite(leftUp, LOW);
        digitalWrite(rightUp, LOW);
        digitalWrite(Middle, HIGH);
        digitalWrite(Down, HIGH);
        digitalWrite(leftDown, LOW);
        digitalWrite(rightDown, LOW);
    break;
  }
}

 

Edytowano przez bujo2001
Problem wyjaśniony - brak pytania na końcu
Link do komentarza
Share on other sites

Ech... czytanie dokumentacji to strata czasu... a przecież pisze jak wół w https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/toint/

Cytat

If no valid conversion could be performed because the String doesn’t start with a integer number, a zero is returned.

Tutaj masz całą wielgaśną dyskusję na ten temat.

Link do komentarza
Share on other sites

3 godziny temu, ethanak napisał:

Ech... czytanie dokumentacji to strata czasu... a przecież pisze jak wół w https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/toint/

Tutaj masz całą wielgaśną dyskusję na ten temat.

Przecież napisałem, że usiądę do tego jak wrócę, a jeżeli ktoś może odpowiedzieć od ręki to proszę o wypowiedzenie się. Doszedłbym do tego po sprawdzeniu, co zwraca .toInt() po podaniu mu znaków innych niż liczby, a w miarę potrzeby szukał odpowiedzi w necie lub dokumentacji. Wolałem zapytać, gdyby ktoś mógł podać odpowiedź od ręki. Po co zaraz się denerwować 😉 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

2 minuty temu, bujo2001 napisał:

Doszedłbym do tego po sprawdzeniu, co zwraca .toInt() po podaniu mu znaków innych niż liczby, a w miarę potrzeby szukał odpowiedzi w necie lub dokumentacji

Chciałeś odpowiedzi na szybko to dostałeś. Następnym razem rób odwrotnie: najpierw dokumentacja, a potem eksperymenty. Bo tak jak chcesz to robić - po prostu będziesz tracić czas na sprawdzenie czegoś, co jest bardzo ładnie opisane (przy czym jest duża szansa, że jednak działa to inaczej). Po co zaraz się denerwować 😉

Zajrzałeś tam na forum Arduino? Bo po przeczytaniu powinieneś mieć gotowe rozwiązanie.

Link do komentarza
Share on other sites

2 godziny temu, ethanak napisał:

Chciałeś odpowiedzi na szybko to dostałeś. Następnym razem rób odwrotnie: najpierw dokumentacja, a potem eksperymenty. Bo tak jak chcesz to robić - po prostu będziesz tracić czas na sprawdzenie czegoś, co jest bardzo ładnie opisane (przy czym jest duża szansa, że jednak działa to inaczej). Po co zaraz się denerwować 😉

Zajrzałeś tam na forum Arduino? Bo po przeczytaniu powinieneś mieć gotowe rozwiązanie.

Tak, tak też zrobię następnymi razami. Teraz byłem w pośpiechu, a bardzo chciałem załatwić przynajmniej to jeszcze dzisiaj.

Na pewne rozwiązanie wpadłem już po tym, jak wspomniałeś, że .toInt() w przypadku wystąpienia znaku, który nie jest cyfrą, domyślnie zwraca 0. Przetestuję je i dam znać w tym wpisie.

Niezależnie od skuteczności poczytam w forach z linków. Jeszcze raz dzięki za pomoc 🙂 

Edit: Mi udało się to obejść, dodając warunek sprawdzający zero osobno, pamiętając o tym, że w odczycie poza zerem pojawia się znak \n
Poczytam jeszcze dokładniej podesłane tematy, jednak to rozwiązanie jest już skuteczne.

Edytowano przez bujo2001
Rozwiązanie problemu
Link do komentarza
Share on other sites

Witam, 

zadanie 6.3 (zmiana automatyczna, co stały ustalony czas),  umieściłem w funkcji loop poniższy kod,

for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      
      while (millis() - zapamietanyCzas <= 500UL) {
        
        digitalWrite(WYSW_1, HIGH);
        digitalWrite(WYSW_2, LOW);
        wyswietlacz(i);
        delay(10);
        
        digitalWrite(WYSW_1, LOW);
        digitalWrite(WYSW_2, HIGH);
        wyswietlacz(j);
        delay(10);
      }
      zapamietanyCzas = millis();
    }
  }

gdzie zmienna zapamietanyCzas została zadeklarowana jako 

unsigned long zapamietanyCzas = 0;

przed funkcją setup. 

Licznik ładnie działa, ale mam pytanie, takie trochę od strony metodycznej, czy można było zrealizować to zadanie bez sięgania do funkcji millis(), która jest dalej w kursie?
 

Link do komentarza
Share on other sites

@szeryf Twoje podejście jest na pewno bardziej eleganckie, ale dałoby się to zrobić bez millisa. Wystarczy, że cała pętla programu będzie chodziła np. z bardzo małym o późnieniem typu 5-10 ms, a licznik będziesz zwiększał np. tylko co 100 obiegów tej pętli 🙂

  • Lubię! 1
Link do komentarza
Share on other sites

Witam,

po wykonaniu wszystkich ćwiczeń w lekcji, podłączyłem w ramach testów poczwórny wyświetlacz 8-segmentowy o wspólnej anodzie (FJ5461BH). Podłączenia do anod zrobiłem przez takie same tranzystory jak w kursie, przy czym kolektory podłączyłem do zasilania, emitery do anod, a bazy przez rezystor 10k do pinów Arduino. Wgrałem pierwszy przykład z biblioteki SevSeg, który odlicza co jedną dziesiątą sekundy do 999 i zadziałało.

Mam jednak pytania, w czasie szukania informacji dotyczących wyświetlaczy o wspólnej anodzie, znalazłem artykuły, w których były stwierdzenia, że powinno się do nich stosować tranzystory PNP, z drugiej strony w jakimś filmiku na YouTube gość pokazuje schemat z tranzystorami NPN. Czy ktoś pokusił by się, że rozjaśnić tę kwestię bardziej.

Drugie pytanie dotyczy opcji hardwareConfig. We wgranym z biblioteki przykładzie była domyślnie ustawiona wartość COMMON_ANODE i zostawiłem ją bez zmian. Czy powinienem podobnie jak w kursie coś zmienić?

 

Link do komentarza
Share on other sites

@szeryf w takim konkretnym przypadku typ tranzystora nie robi dużej różnicy 🙂 Z tego co widzę to masz zarejestrowany zestaw do kursu elektroniki 1, więc możesz sobie w ramach eksperymentu podmienić tranzystory na PNP i zrobić taki eksperyment.

9 godzin temu, szeryf napisał:

Drugie pytanie dotyczy opcji hardwareConfig. We wgranym z biblioteki przykładzie była domyślnie ustawiona wartość COMMON_ANODE i zostawiłem ją bez zmian. Czy powinienem podobnie jak w kursie coś zmienić?

Jeśli wyświetlacz działa to dobry znak, nic raczej nie trzeba już zmieniać 🙂

Link do komentarza
Share on other sites

Podmieniłem tranzystory na PNP te do kursu (emitery podłączyłem do zasilania, bazy przez rezystor 10K do arduino, kolektory do anod). Efekt jest taki, że wczytany program działa, ale diody wyświetlacza świecą bardzo słabo (powiedziałbym 10% tego, co przy konfiguracji z tranzystorem NPN). Próbowałem zmniejszyć rezystory podłączone do diod na 330 Ω, ale poprawa była prawie niezauważalna. To był test z użyciem biblioteki SevSeg, na tym samym przykładzie co poprzednio dla tranzystorów NPN. Próbowałem jeszcze zmiany w hardwareConfig z COMMON_ANODE na P_TRANSISTORS, ale to nic nie pomogło w kwestii poprawy jasności, za to wgrany program zaczął wariować i wyświetlać cyfry bez ładu i składu w różnych miejscach.

Drugi test zrobiłem bez użycia biblioteki, podłączając do Arduino jedną anodę i diody oraz programując ręcznie piny (na wyjścia diod dałem stan niski). W artykule o tranzystorach w kursie elektroniki, w części o kluczach NPN i PNP jest napisane, że przy takiej konfiguracji tranzystora PNP jaką zastosowałem, aktywacja powinna być stanem niskim na bazie, tymczasem diody się świecą, gdy na bazę podam stan wysoki, przy niskim nic się nie dzieje. Dodatkowo, gdy włączone są wszystkie diody, to ich jasność maleje, choć nie tak bardzo jak w przypadku użycia biblioteki.

Co robię nie tak z tymi tranzystorami PNP?

Edytowano przez szeryf
Link do komentarza
Share on other sites

@szeryf  Zamieniłem tranzystor na PNP, u mnie wszystko śmiga, natomiast jak zasilanie podłaczyłem do kolektora zamiast emitera to jasność świecenia bardzo spadła, może to było problemem u Ciebie.

Co do zadania to kod poniżej:

void loop() {

  int t = 0;
  for (t = 0; t < 10; t++) {
    digitalWrite(WYS_2, HIGH);
    digitalWrite(WYS_1, LOW);
    wyswietlacz(i);
    delay(5);
    digitalWrite(WYS_2, LOW);
    digitalWrite(WYS_1, HIGH);
    wyswietlacz(j);
    delay(5);
    Serial.println(t);

  }
  i++;
  if ( i == 10){
    i =0;
    j++;
  }
  else if ( j == 10){
    i,j =0;
  }

}

 

  • Lubię! 1
Link do komentarza
Share on other sites

Dzięki za odpowiedź. U mnie niestety problemem okazał się fakt, że tranzystory NPN trafiły do woreczka, gdzie miały być PNP (czyli bałagan albo za dużo zestawów Forbota w domu 😉), dopiero jak wróciłem do złożenia podstawowego klucza PNP na zwykłej diodzie i nie zadziałał tak jak trzeba zorientowałem się, że coś nie tak z tranzystorem. Później odnalazłem zaginione tranzystory PNP i stała się jasność😃.  Później muszę potestować jeszcze z wykorzystaniem biblioteki...

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.