Skocz do zawartości

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


Pomocna odpowiedź

mcklaklen, dzięki za podzielnie się Twoim rozwiązaniem 🙂 Pamiętaj proszę, aby kody programów na forum obejmować tagami . Dzięki temu będą one znacznie czytelniejsze 🙂

Link do komentarza
Share on other sites

Witam,

Jak w poście pod klawiaturą ,tym razem mam problem ze szkicem do wyświetlacza.

Pierwszy raz taki komunikat mi się pokazał i nie mam pojęcia czym to jest spowodowane.

Coś o "id" piszę lecz nie mogę znaleźć owego folderu z tym.

Z góry dziękuję 
Pozdrawiam.

image.png

Link do komentarza
Share on other sites

Obawiam się, ze nie potrafię zrozumieć części z niebezpośrednim podłączeniem katody do masy „Przy włączeniu wszystkich segmentów cały wyświetlacz może pobrać
"z katody" ponad 20 mA, więc nie powinniśmy podłączać jej bezpośrednio do Arduino!”

Czy podłączenie masy przez tranzystor do Arduino zmienia cos poza możliwością sterowania? Nie jest to dalej połączenie bezpośrednie? Dlaczego w przykładzie z jednoczesnym wyświetlaniem tych samych znaków nie potrzebowaliśmy tranzystorów?

Pozdrawiam :)

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

Dnia 8.11.2018 o 22:44, D3binski napisał:

Czy podłączenie masy przez tranzystor do Arduino zmienia cos poza możliwością sterowania?

@D3binski oczywiście, że tak. Mówiąc najprościej, sterowanie przez tranzystor sprawia, że nie obciążasz płynącym prądem wyjścia Arduino tylko właśnie ten tranzystor. Przykładowo (dane wzięte z powietrza, tylko dla przykładu) - z wyjścia Arduino pobierzesz tylko 5 mA, które "włączy tranzystor" i przez układ bezpiecznie popłynie 140 mA. Gdyby ten większy prąd przepłynął przez pin w Arduino to doszłoby do jego uszkodzenia.

Dnia 8.11.2018 o 22:44, D3binski napisał:

Dlaczego w przykładzie z jednoczesnym wyświetlaniem tych samych znaków nie potrzebowaliśmy tranzystorów?

Bo wtedy wspólne wyprowadzenia wyświetlaczy było podłączone bezpośrednio do zasilania. Sumaryczny prąd płynący przez wszystkie diody nie obciążał żadnego wyjścia Arduino. Każdy używany przez nas pin Arduino obciążony był tylko prądem jednej diody (czyli nie było to dla niego problemem). Pamiętaj, że  przez wspólne wyprowadzenie wyświetlacza płynie suma prądów płynących przez wszystkie diody, czyli np. 7*20 mA, a to już za dużo jak na jeden pin Arduino. Dlatego wspólne wyprowadzenie wyświetlacza musi być sterowane przez tranzystor, który nie zostanie uszkodzony przez taki prąd. Czy trochę się rozjaśniło? 😉

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

@rozrabiaka nie tyle zabrakło, co głównym zamysłem było tutaj pokazania jak faktycznie działają takie wyświetlacze. Najłatwiej zrozumieć ich działanie właśnie podczas bezpośredniego sterowania diodami wbudowanymi w wyświetlacze. Korzystanie z ekspanderów lub dodatkowych sterowników to kolejny krok, którym pewnie też się kiedyś zajmiemy 🙂

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

Cześć,

Póki co mogę się podzielić zadaniami domowymi 6.1 oraz 6.2. Nieśmiało poeksperymentowałem z millis().

/*
 * Kurs Arduino poziom II
 * Wyświetlacze 7-segmentowe
 * Zadania domowe 6.1 oraz 6.2
 */

#define SEG_C 2   //Definicje pinów segmentów wyświetlaczy
#define SEG_E 3
#define SEG_D 4
#define SEG_G 5
#define SEG_A 6
#define SEG_F 7
#define SEG_B 8

#define Minus 9   //Definicje pinów przycisków
#define Plus 10
#define Reset 11

#define mryganie 500    //Okres mrygania kodu błędu

int i = 0;    //Zmienna "i" służy do określenia wyświetlanej cyfry w pętli głównej
int j = 0;    //Zmienna "j" służy do resetowania czasu po upłynięciu okresu jednego mrygnięcia
unsigned long poprzedniCzas = 0;    //Zmienna "poprzedniCzas" zapisuje aktualny czas z komendy millis() przed mrygnięciem kodu błędu

void setup() {
  pinMode(SEG_A, OUTPUT);   //Deklaracja pinów wyświetlacza jako wyjścia
  pinMode(SEG_B, OUTPUT);
  pinMode(SEG_C, OUTPUT);
  pinMode(SEG_D, OUTPUT);
  pinMode(SEG_E, OUTPUT);
  pinMode(SEG_F, OUTPUT);
  pinMode(SEG_G, OUTPUT);

  pinMode(Minus, INPUT_PULLUP);   //Deklaracja pinów przycisków jako podciągnięte wejścia
  pinMode(Plus, INPUT_PULLUP);
  pinMode(Reset, INPUT_PULLUP);
}

void loop() {
  
  if(digitalRead(Plus) == LOW){   //Jeżeli przycisk "Plus" wciśnięty (zwarty z masą) to zwiększ "i" o jeden i odczekaj aby wyeliminować efekt wielokrotnego wciśnięcia przycisku
    i++;
    delay(200);
  }
  else if(digitalRead(Minus) == LOW){   //Po wciśnięciu minusa zmniejsz "i" o jeden
    i--;
    delay(200);
  }
  else if(digitalRead(Reset) == LOW){   //Przycisk "Reset" nadaje zmiennej "i" wartość 0
    i = 0;
    delay(200);
  }

  if(i > 9){    //Dwie instrukcje warunkowe ograniczające i do zakresy od -1 do 10
    i = 10;
  }
  if(i < -1){
    i = -1;
  }
  
  wyswietlacz(i);   //Wyświetlenie cyfry

}

void wyswietlacz(int cyfra){    //Funkcja zamieniająca wartość "i" na wyświetlenie konkretnych diod. Cyfra jest zmienną wewnątrz tej funkcje przyjmującą wartość "i"

  if((cyfra > 9 || cyfra < 0) && j == 0){   //Jeżeli cyfra nie mieści się w zakresie wyświetlania wyświatlacza i zmienna "j" wskazuje początek nowego/pierwszego mrygnięcia to zapisz aktualny czas do zmiennej
    poprzedniCzas = millis();
  }

  if(poprzedniCzas < millis() - mryganie){    //Jeżeli okres mrygnięcia minął to zresetuj zmienną "j" co spowoduje rozpoczęcie kolejnego mrygnięcia
    j = 0;
  }
  
  if(cyfra > 9 || cyfra < 0){   //Kolejne sprawdzenie czy zakres cyfry poza zakresem wyświetlacza i...
    if(poprzedniCzas > millis() - (mryganie/2)){    //jeżeli tak to włącz diody sygnalizujące kod błędu o ile nie mineło więcej niż pół okresu mrygnięcia, zwiększ zmienną "j" tak aby nie nadpisywał się czas w zmiennej "poprzedniCzas"
    j++;
    digitalWrite(SEG_A, HIGH);
    digitalWrite(SEG_B, LOW);
    digitalWrite(SEG_C, LOW);
    digitalWrite(SEG_D, HIGH);
    digitalWrite(SEG_E, LOW);
    digitalWrite(SEG_F, LOW);
    digitalWrite(SEG_G, HIGH);
    }
    else{   //Jeżeli natomiast minęło pół okresu mrygnięcia to wyłącz diody
    digitalWrite(SEG_A, LOW);
    digitalWrite(SEG_B, LOW);
    digitalWrite(SEG_C, LOW);
    digitalWrite(SEG_D, LOW);
    digitalWrite(SEG_E, LOW);
    digitalWrite(SEG_F, LOW);
    digitalWrite(SEG_G, LOW); 
    }
  }
  else{   //Jeżeli cyfra mieści się w zakresie wyświetlacza to przygotuj zmienną "j" na początek okresu mrygnięcia kodu błędu na wypadek gdyby cyfra przestała się mieścić w następnym obiegu
    j = 0;
  }
  
  switch(cyfra){    //Instrukcja zamiany konkretnej cyfry na włączenie konkretnych diod tak aby całość była wyświetlana jako ta cyfra
    
    case 0:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, LOW);
     break;

     case 1:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
     break;

     case 2:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, HIGH);
     break;

     case 3:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, HIGH);
     break;

     case 4:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
     break;

     case 5:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
    break; 
    
    case 6:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
    break;
   
    case 7:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
    break;
    
    case 8:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
    break;
    
    case 9:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
    break;     
  }
}

 

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

a ja trochę z innej parafii. Nie wrzucam prac domowych, bo jest ich sporo 😄 Uparłem się, że zrobię sobie wpisywanie cyfr z komputera i mam. W tym celu skorzystałem z przerwania realizowanego przez przycisk. Podczas przerwania, realizowana jest funkcja restartująca software'owo całą płytkę. Jeśli chodzi o funkcję resetującą arduino to dopiero staram się zgłębić jej działanie. Póki co wiem, że działa. Teoretycznie mógłbym korzystać z przycisku wbudowanego w płytkę ale jak rozumiem to jest pełny restart hardware'owy. Trwa on sporo dłużej no i dodatkowo chciałem sprawdzić działanie funkcji restartującej w razie jakbym kiedyś potrzebował sobie wyprowadzić taki element restartujący w momencie gdy sama płytka będzie gdzieś na przykład schowana.  Dodatkowo po wpisaniu na przykład litery zamiast cyfry wyświetlacz pokazuje komunikat o błędzie (3 poziome kreski). 

Kod: 

#define SEG_C 11
#define SEG_E 12
#define SEG_D 4 
#define SEG_B 5
#define SEG_G 6
#define SEG_A 7
#define SEG_F 8
#define WYSW_1 9
#define WYSW_2 10
#define PRZYCISK 2

int cyfra1 = 0; //zmienne dla wyświetlacza
int cyfra2 = 0; 

void setup() {
  //konfiguracja pinów jako wyjścia
  pinMode(SEG_A, OUTPUT);
  pinMode(SEG_B, OUTPUT);
  pinMode(SEG_C, OUTPUT);
  pinMode(SEG_D, OUTPUT);
  pinMode(SEG_E, OUTPUT);
  pinMode(SEG_F, OUTPUT);
  pinMode(SEG_G, OUTPUT);
  pinMode(WYSW_1, OUTPUT);
  pinMode(WYSW_2, OUTPUT);
  pinMode(PRZYCISK, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(PRZYCISK), RESET, RISING); //przerwanie

  Serial.begin(9600); //rozpoczęście komunikacji z PC

  Serial.println("Podaj pierwszą cyfrę!"); //komunikat dla użytkownika
  while (Serial.available() == 0) {
    delay(50); //zatrzymanie programu
}

if (Serial.available() >0) { //zapisanie podanej liczby do zmiennej
    cyfra1 = Serial.read();
}

Serial.println("Podaj drugą cyfrę!"); //komunikat dla użytkownika
while (Serial.available() == 0) {
    delay(50);
}

if (Serial.available() >0) { //zapisanie podnej liczny do zmiennej
    cyfra2 = Serial.read();
}
  
}

void loop() {
  
    digitalWrite(WYSW_1, HIGH); //multipleksowanie - zapalenie jednej cyfry
    digitalWrite(WYSW_2, LOW);
    wyswietlacz(cyfra1);
    delay(10);
    wyswietlacz(cyfra2);
    digitalWrite(WYSW_2, HIGH); //multipleksowanie - zapalanie drugiej cyfry
    digitalWrite(WYSW_1,LOW);
    delay(10);

}

void wyswietlacz(int cyfra) {
    //w zaleznosci od podanej cyfry
    switch (cyfra) {
        case '0':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, HIGH);
            digitalWrite(SEG_F, HIGH);
            digitalWrite(SEG_G, LOW);
        break;

        case '1':
            digitalWrite(SEG_A, LOW);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, LOW);
            digitalWrite(SEG_E, LOW);
            digitalWrite(SEG_F, LOW);
            digitalWrite(SEG_G, LOW);
        break; 

        case '2':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, LOW);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, HIGH);
            digitalWrite(SEG_F, LOW);
            digitalWrite(SEG_G, HIGH);
        break;

        case '3':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, LOW);
            digitalWrite(SEG_F, LOW);
            digitalWrite(SEG_G, HIGH);
        break;

        case '4':
            digitalWrite(SEG_A, LOW);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, LOW);
            digitalWrite(SEG_E, LOW);
            digitalWrite(SEG_F, HIGH);
            digitalWrite(SEG_G, HIGH);
        break;

        case '5':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, LOW);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, LOW);
            digitalWrite(SEG_F, HIGH);
            digitalWrite(SEG_G, HIGH);
        break;

        case '6':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, LOW);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, HIGH);
            digitalWrite(SEG_F, HIGH);
            digitalWrite(SEG_G, HIGH);
        break;

        case '7':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, LOW);
            digitalWrite(SEG_E, LOW);
            digitalWrite(SEG_F, LOW);
            digitalWrite(SEG_G, LOW);
        break;

        case '8':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, HIGH);
            digitalWrite(SEG_F, HIGH);
            digitalWrite(SEG_G, HIGH);
        break;

        case '9':
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, HIGH);
            digitalWrite(SEG_C, HIGH);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, LOW);
            digitalWrite(SEG_F, HIGH);
            digitalWrite(SEG_G, HIGH);
        break;

        default:
            digitalWrite(SEG_A, HIGH);
            digitalWrite(SEG_B, LOW);
            digitalWrite(SEG_C, LOW);
            digitalWrite(SEG_D, HIGH);
            digitalWrite(SEG_E, LOW);
            digitalWrite(SEG_F, LOW);
            digitalWrite(SEG_G, HIGH);
        break;
       
    }

}

void RESET() { //funckja odpowiadająca za restart arduino
  digitalWrite(SEG_A, LOW);
  digitalWrite(SEG_B, LOW);
  digitalWrite(SEG_C, LOW);
  digitalWrite(SEG_D, LOW);
  digitalWrite(SEG_E, LOW);
  digitalWrite(SEG_F, LOW);
  digitalWrite(SEG_G, LOW);
    asm volatile ("  jmp 0");
}

Film: 

 

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

20 godzin temu, BHBmacieg napisał:

Podczas przerwania, realizowana jest funkcja restartująca software'owo całą płytkę. Jeśli chodzi o funkcję resetującą arduino to dopiero staram się zgłębić jej działanie. Póki co wiem, że działa.

Ciekawe, fajnie że poszukałeś czegoś więcej. Choć wydaje mi się że dałoby się to zrealizować bez skoku na początek kodu (reset).

Ewentualnie może mógłbyś poszperać jak zamienić gigantyczny blok ifów na coś bardziej kompaktowego 🙂 podpowiedź to że możesz ztablicować stałe wartości 😉 

Link do komentarza
Share on other sites

@ceiem, w artykule chodziło o odcięte podczas lutowania końcówki nóżek rezystorów. Ja jak przerabiałem kursy forbota (najpierw ten, a lutowania sporo później) też ich jeszcze nie miałem przerabiając ten odcinek z wyświetlaczem 🙂 Zatem wykorzystałem zwykłe kabelki. Płytka stykowa wyglądała znacznie brzydziej niż na zdjęciach z kursu 😄 Ale działać działało.

 

Edycja: Oczywiście rezystory jakieś posiadasz, więc możesz też obcinaczkami przyciąć ich nóżki i wykonać wszystko jak w kursie.

Edytowano przez Bhoy67
  • 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.