Skocz do zawartości

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


Pomocna odpowiedź

Tak, ja użyłem przewodów z zestawu. Nie będzie to czytelnie i ładnie wyglądać, ale da się i będzie działać.

Jednak jak dopisałem po edycji postu- możesz uciąć końcówki nóżek rezystorów, które posiadasz i zrobić jak w kursie.

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

Tak szukam i szukam...

Jest jakaś funkcja, która by odczytywała konkretną liczby z ciągu zmiennej typu INT? Mam np. liczbę 56, chcę odczytać osobno 5 i 6, a potem zapisać ją do INT.

Link do komentarza
Share on other sites

(edytowany)
12 minut temu, Beskid napisał:

Tak szukam i szukam...

Jest jakaś funkcja, która by odczytywała konkretną liczby z ciągu zmiennej typu INT? Mam np. liczbę 56, chcę odczytać osobno 5 i 6, a potem zapisać ją do INT.

Hm, jeśli a=56 to:

while (a>0)
{
   int x=a%10;
   a=(a-x)/10;
}

oczywiście zmienna x przechowuje wtedy kolejne cyfry liczby a „od końca”. Zmienną x w każdym przebiegu pętli możesz sobie wczytać np. do tablicy. Nie wiem dokładnie, czy o to Ci chodziło...

Edytowano przez ceiem
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

(edytowany)

To może konwersja na stringa i potem substr? Tylko wtedy dostaniesz zmienną char i znowu potrzeba zrobić konwersję... ale tu byłoby prościej (jednoelementowy podciąg stringa)+’/0’ i masz int. Ale to takie kombinowanie... Jednakże można by pokombinować i osiągnąć rezultat jakiego potrzebujesz.

Mądrzejsi niech się wypowiedzą 🙂 

Edytowano przez ceiem
Link do komentarza
Share on other sites

@ceiem No to jest potem kombinowanie. Pytam czy się tak w ogóle da. W tej lekcji z 7 segmentowym wyświetlaczem, chciałem wyświetlać liczbę ze zwykłego int'a. Nie potrafiłem znaleźć na necie więc zapytałem.

Chciałem czytać to jak z tablicy, tylko mając jeden ciąg znaków.

Link do komentarza
Share on other sites

(edytowany)

Jeśli nie chcesz robić potem obliczeń na pojedynczej cyfrze to konwersja do stringa i użycie funkcji substr całkowicie rozwiązuje Twój problem i jest to bardzo proste rozwiązanie. Tylko nie wiem jakie funkcje są dostępne dla Arduino, bo w czystym c++ to jedna linijka kodu z biblioteką sstream. 

Zerknij tutaj może coś z tego zadziała w Arduino 🙂 Ja swoją droga też przećwiczę, bo warto wiedzieć. 

Edytowano przez ceiem
Link do komentarza
Share on other sites

Witam użytkowników Forbota 🙂

Podczas próby dodania znaku ERROR na wypadek wybrania nieodpowiedniego klawisza natknąłem się na pewien problem. Jest to mianowicie fakt, że ERROR pokazuje się za każdym razem, niezależnie od podanej liczby.

Aby sprawdzić co się dzieje, wykorzystałem wiadomość ze zmienną wysyłaną do komputera przez UART. Ku mojemu zaskoczeniu, zmienna na początku przyjmuje odpowiednią wartość (1, 2, itd.), po czym niezależnie od tego, jaka była liczba, zmienia wartość na -38. Po dodaniu krótkiego delayu na końcu programu zauważyłem również, że program najpierw działa prawidłowo i pokazuje odpowiednią cyfrę, jednak po czasie ustalonym w delayu zmienna przyjmuje wartość -38 i wyskakuje ERROR.

Próbowałem dwóch sposobów (zarówno instrukcja warunkowa if, jak i funkcja default w switch-case, jednak w każdej z nich rezultat jest identyczny.

Dzieje się tak również przy wciśnięciu samego przycisku Enter bez podania żadnego znaku. Przez chwilę zastanawiałem się, czy jest to właśnie interpretacja przycisku Enter jako ten nieprawidłowy, jednak zastosowanie dodatkowych, krótkich opóźnień w celu wykluczenia mojego ciężkiego palca z grona podejrzanych raczej wskazuje inaczej.

Co robić? (PS. Połączenie wyświetlacza jest identyczne jak w kursie, pomimo zastosowania innych nazw w funkcji define)

Kod z instrukcją if
 

#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 givenNumber = 0;

void setup() {
  Serial.begin(9600);
  pinMode(Up, OUTPUT); // Initializes the display
  pinMode(leftUp, OUTPUT);
  pinMode(rightUp, OUTPUT);
  pinMode(Middle, OUTPUT);
  pinMode(Down, OUTPUT);
  pinMode(leftDown, OUTPUT);
  pinMode(rightDown, OUTPUT);

  digitalWrite(Up, HIGH); // Checks if every diode works correctly
  delay(300);
  digitalWrite(leftUp, HIGH);
  delay(300);
  digitalWrite(rightUp, HIGH);
  delay(300);
  digitalWrite(Middle, HIGH);
  delay(300);
  digitalWrite(Down, HIGH);
  delay(300);
  digitalWrite(leftDown, HIGH);
  delay(300);
  digitalWrite(rightDown, HIGH);

  delay(200);

  clearAll();
  delay(200);
  Serial.println("Please, give any number from 0 to 9 and I'll show it on the display.");
}

void loop() {
  if (Serial.available() > 0) { // If data has been received
    givenNumber = (Serial.read()- '0'); // Received number is in ASCII code, so in order to make it into the right one, we can subtract 0 (0 = 48 in ASCII)
    Serial.println(givenNumber);
    showNumber(givenNumber);
    /*
    if ((-1 < givenNumber) and (givenNumber < 10)) {
      showNumber(givenNumber);
    } else {
      digitalWrite(Up, HIGH);
      digitalWrite(leftUp, LOW);
      digitalWrite(rightUp, LOW);
      digitalWrite(Middle, HIGH);
      digitalWrite(Down, HIGH);
      digitalWrite(leftDown, LOW);
      digitalWrite(rightDown, LOW);
    }
    */
  }
}

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;
  }
}

Kod z instrukcją default w switch-case

#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 givenNumber = 0;

void setup() {
  Serial.begin(9600);
  pinMode(Up, OUTPUT); // Initializes the display
  pinMode(leftUp, OUTPUT);
  pinMode(rightUp, OUTPUT);
  pinMode(Middle, OUTPUT);
  pinMode(Down, OUTPUT);
  pinMode(leftDown, OUTPUT);
  pinMode(rightDown, OUTPUT);

  digitalWrite(Up, HIGH); // Checks if every diode works correctly
  delay(300);
  digitalWrite(leftUp, HIGH);
  delay(300);
  digitalWrite(rightUp, HIGH);
  delay(300);
  digitalWrite(Middle, HIGH);
  delay(300);
  digitalWrite(Down, HIGH);
  delay(300);
  digitalWrite(leftDown, HIGH);
  delay(300);
  digitalWrite(rightDown, HIGH);

  delay(200);

  clearAll();
  delay(200);
  Serial.println("Please, give any number from 0 to 9 and I'll show it on the display.");
}

void loop() {
  if (Serial.available() > 0) { // If data has been received
    givenNumber = (Serial.read()- '0'); // Received number is in ASCII code, so in order to make it into the right one, we can subtract 0 (0 = 48 in ASCII)
    Serial.println(givenNumber);
    showNumber(givenNumber);
  }
}

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;
  }
}

Dodam jeszcze, że po wywaleniu zarówno instrukcji warunkowej, jak i opcji default program pokazuje cyfry jak należy (pomimo tego, że w wiadomości nadal pojawia się nieszczęsne -38). Widać to na dołączonym zdjęciu.

Blad.png

Edytowano przez bujo2001
Dodatkowa zawartość - screenshot terminalu UART
Link do komentarza
Share on other sites

@Gieneq Najwidoczniej tak, według prośby ograniczyłem program do prostego odczytania:

int sign = 0; // Typ integer ze wzgledu na kod ASCII

void setup() {
  Serial.begin(9600);
}

void loop() {
  if(Serial.available() > 0) {
    sign = Serial.read();
    Serial.println("Pierwsza opcja");
    Serial.println(sign);
    sign = (sign - '0');
    Serial.println("Druga opcja");
    Serial.println(sign);
  }
}

Efekt pozostaje ten sam, Najpierw wyświetlane są prawidłowo odczytane wiadomości, a później program wykonuje tą samą operację dla pewnego innego klawisza (patrz Blad_v2.png).

Sprawdziłem w wikipedii i znak 10 w kodzie ASCII należy do Line Feed (koniec linii). Z początku myślałem, że może pomóc wywalenie końcówki -ln, jednak nadal ten sam problem.

int sign = 0; // Typ integer ze wzgledu na kod ASCII

void setup() {
  Serial.begin(9600);
}

void loop() {
  if(Serial.available() > 0) {
    sign = Serial.read();
    Serial.print(sign);
  }
}

Efekt w Blad_v3.png

Wygląda to tak, jakby po odebraniu danych i wykonaniu poprawnych operacji na odpowiednim klawiszu Arduino otrzymywało kolejny znak (którym jest przejście do nowej linii), który interpretuje jako odebrane dane (Serial.available() > 0), co wywołuje wykonanie operacji na właśnie tym znaku. Jest to jednak moja nieekspercka diagnoza i zarówno nie wiem, czy ma ona sens, jak i nie mam pomysłu na to, jak ją rozwiązać.

Niby mógłbym zrobić licznik, który przepuszczałby co drugą wartość (przykładowo dla liczby nieparzystej, która odpowiadałaby odpowiedniemu znakowi, kod zostałby wykonany, a dla parzystej, która odpowiadałaby nowej linii, program pomijałby operację), jednak mija to się z celem, jeżeli istnieje lepsze rozwiązanie.

Z góry dzięki za pomoc.

Blad_v2.png

Blad_v3.png

Link do komentarza
Share on other sites

Powiem tak: temat był wałkowany na forum mnóstwo razy, aż się nie chce wierzyć że nie można znaleźć prawidłowej odpowiedzi...

Co powiesz na:

if (Serial.available()) {
  sign=Serial.read();
  if (sign != 10) {
    Serial.println(sign); // albo co...
  }
}

A najprościej byłoby wyłączyć przekazywanie znaku nowej linii w monitorze serial...

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

@ethanak Tak, na ten pomysł już wpadłem, tak jak wspomniałem w drugim poście, jednak myślałem, że może jest tutaj jakiś problem w samym Arduino i da się to wyeliminować bez zastosowania takiego warunku.

14 minut temu, ethanak napisał:

Powiem tak: temat był wałkowany na forum mnóstwo razy, aż się nie chce wierzyć że nie można znaleźć prawidłowej odpowiedzi...

Co powiesz na:


if (Serial.available()) {
  sign=Serial.read();
  if (sign != 10) {
    Serial.println(sign); // albo co...
  }
}

A najprościej byłoby wyłączyć przekazywanie znaku nowej linii w monitorze serial...

A jak wyłączyć przekazywanie tego znaku? Raczej nie widziałem nigdzie podobnego wpisu, może zbyt słabo szukałem. Poszukam jeszcze, jednak wolałem spytać, bo widać, że znasz się na rzeczy i może szybciej się dowiem pytając.

Link do komentarza
Share on other sites

23 minuty temu, bujo2001 napisał:

A jak wyłączyć przekazywanie tego znaku?

Na dole w monitorze serial masz takie cóś na czym pisze "Newline". Kliknij w to to zobaczysz inne możliwości.

Tyle że sposób z pomijaniem znaku nowej linii jest całkiem prawidłowy i bardziej uniwersalny. Ja np. dość często stosuję coś w stylu:

if (!isspace(znaczek)) cośtam();

aby pominąć wszystkie niewidoczne znaczki (spacje, tabulacje i inne takie co się mogą wkraść niepostrzeżenie w pole w które coś trzeba wpisać).

  • Pomogłeś! 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.