Skocz do zawartości

Plik na karcie SD zawierający program, który wykonuje Arduino.


Szmyterling

Pomocna odpowiedź

39 minut temu, prezesedi napisał:

pomyślałem, że można "wyciszyć wyświetlacz".

Bardzo dobrze pomyślałeś.

Wyłączenie wyświetlacza:

display.ssd1306_command(SSD1306_DISPLAYOFF);

Włączenie w teorii powinno wyglądać tak:

display.ssd1306_command(SSD1306_DISPLAYON);

ale nie zawsze się to udaje. Możesz spróbować. Jeśli nie wyjdzie - wywołaj po command po prostu display.begin() z takimi samymi parametrami jak w setup.

39 minut temu, prezesedi napisał:

czy to jest to samo co zapis --1)

Nie - taki zapis nie ma sensu.

Operatory pre/postdekrementacji działaja tylko na zmiennych i oznaczają podstawienie do zmiennej nowej wartości, równej poprzedniej wartości minus jeden. A raczej do jedynki dość trudno podstawić cokolwiek.

Prawidłowy jest zapis x-- lub --x. O różnicy między nimi może innym razem 🙂

 

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

...DISPLAYON i ...DISPLAYOFF "już w kodzie".

Jeszcze nie sprawdzałem, ale zapewne różnica jest następująca: te komendy wyłączają i włączają zasilanie w ekranie co zmniejsza pobór prądu? Czy może chodzi też o zwolnienie części zasobu pamięci?

Link do komentarza
Share on other sites

1 godzinę temu, ethanak napisał:

A tak przy okazji - do czego jest zmienna "kopia", bo Twój sposób nazywania zmiennych jest... jakby tu powiedzieć... niezbyt standardowy 😉

Nazwa tej zmiennej to mój wynalazek...😜 Jakoś się przyzwyczaiłem do "kopia" "stan" i wszelkiej maści "xyz" (oczywiscie tylko wtedy kiedy jest killka zmiennych, a nie 50 czy 100) ta zmienna ma zapamiętać który guzik został wciśnięty żeby można było zapętlić maszynę stanów i wrócić do konkretnego case...

56 minut temu, prezesedi napisał:

 


 

 

 

Link do komentarza
Share on other sites

W sumie to... nie jest mój kod. To Wasze dzieło @ethanak i @farmaceuta. Nawet wątek nie jest mój i mało wspólnego z tematem.

Jak czytam mój pierwszy wpis, to jestem w szoku czego chciałem dokonać. Jak bardzo skomplikować życie sobie i innym.

@ethanak zajrzałem do pliku z czcionką jaki mi przesłałeś i wykorzystałem w kodzie polskie znaki. Efekt wygląda jak poniżej:

 

20220629_160329[1].jpg

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

38 minut temu, prezesedi napisał:

Nawet wątek nie jest mój i mało wspólnego z tematem.

W sumie może ktoś ( @Gieneq? @Treker ) zlituje się i wydzieli te posty do oddzielnego wątku? Proponuję tytuł "Wyświetlacz OLED w makiecie kolejowej" albo coś podobnego...

Tak przy okazji:

1 godzinę temu, prezesedi napisał:

te komendy wyłączają i włączają zasilanie w ekranie co zmniejsza pobór prądu?

Mniej więcej tak. Zasilanie ekranu zostaje wyłączone (m.in. przetwornica) a sam kontroler przechodzi w tryb niskiego poboru prądu. W Twoim rozwiązaniu rozwiązanie jest niespecjalnie trafione - stosuje się to w rozwiązaniach z zasilaniem bateryjnym, gdzie nie ma wyłącznika. Robiłem tak w takiej zabawce (gra na ATtiny85) zasilanej z bateryjki 2032. Przy zasilaniu sieciowym lepiej zastosować zwykłe czyszczenie ekranu tak jak proponowałeś.

Ale odrobina wiedzy nikomu nie zaszkodziła.

44 minuty temu, prezesedi napisał:

wykorzystałem w kodzie polskie znaki

I o to chodziło.

To co, kombinujemy dalej?

Link do komentarza
Share on other sites

11 minut temu, ethanak napisał:

To co, kombinujemy dalej?

Oczywiście

czytam o podpinaniu dwóch wyświetlaczy, jednak dopiero zaczynam i trochę mi zejdzie. Wiem już że trzeba nazwać obydwa inaczej i zrobić komendy dla obu. Mój pomysł - ten 128x64 na budynku dworca - wszystkie kody jak do tej pory. Mały 128x32 na peronie. Mam też rozpiskę pinów ESP32 by zdefiniować drugą linię I2C.

Czy zdefiniowanie wyświetlaczy będzie następujące?

Adafruit_SSD1306 display1(128,64,&Wire);
Adafruit_SSD1306 display2(128,32,&Wire);

 

Link do komentarza
Share on other sites

14 minut temu, prezesedi napisał:

Czy zdefiniowanie wyświetlaczy będzie następujące?

Nie - musisz użyć dwóch szyn I2C bo wyświetlacze mają ten sam adres.

Powinno być:

Adafruit_SSD1306 display1(128,64,&Wire);
Adafruit_SSD1306 display2(128,32,&Wire1);

i potem w setup inicjalizacja obu szyn:
 

Wire.begin(OLED_SDA, OLED_SCL);
Wire1.begin(OLED2_SDA, OLED2_SCL);

Wire i Wire1 są zdefiniowane przez bibliotekę. OLED2_SDA i OLED2_SCL to piny drugiej szyny.

Tylko troszkę wyhamuj rozpęd: najpierw zróbmy te nieszczęsne wyświetlanie, bo jak będziesz każdą linijkę po sto razy powielać to te nędzne 4 megabajty flasha mogą nie starczyć. Czyli najpierw zrobienie porządnych funkcji wyświetlania (można zacząć od tego co pokazałem wcześniej), a potem dopiero podłączenie drugiego wyświetlacza.

Dlaczego tak?

Bo teraz podłączenie drugiego wyświetlacza wymaga dopisania jakichś dwustu linii kodu. A ja planuję zmieścić się w kilkunastu...

Link do komentarza
Share on other sites

2 minuty temu, prezesedi napisał:

Adres obu to wg I2c Scanner

I2C device found at address 0x3C  !

Czyli tu nic się nie poradzi, musimy zastosować dwie szyny.

2 minuty temu, prezesedi napisał:

Ten skrócony kod można jeszcze bardziej skrócić?

Oczywiście że można - tyle że chcę to zrobić etapami żebyś cokolwiek z tego zrozumiał i w razie czego był w stanie coś tam zmienić/poprawić.

Link do komentarza
Share on other sites

47 minut temu, prezesedi napisał:

"AJM REDI"

OK, to jedziemy.

Jak rozumiem, zmieniłeś już sposób wyświetlania z makaronu w switch/case na wywołanie funkcji "wyświetl"? Jeśli nie, zrób to i pokaż pełny kod. Będziemy się zastanawiać, jak to można jeszcze uprościć - na razie poprzez usunięcie powtarzających się fragmentów kodu.

A,i przygotuj się na to, że pozmieniamy sobie nazwy zmiennych. O ile 'x' jeszcze jakoś ujdzie, o tyle 'y' sugeruje że mamy do czynienia z jakimś przesunięciem w pionie, a 'kopia' to już w ogóle pomyłka (bo czego to kopia i do czego ma niby służyć?). Ale to przy okazji następnej iteracji 🙂

Link do komentarza
Share on other sites

pełny kod, który pracuje na 0,94" wygląda następująco (przypominam, że miałem problem z klawiaturą - dlatego tam jest bajzel - ale wyświetla dzięki temu prawidłowo)

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Keypad.h>

      //ustawienie i2c
#define OLED_SDA 21
#define OLED_SCL 22
#define SCROLL_STEP 10UL

static uint32_t displayctl= millis();

Adafruit_SSD1306 display(128,64,&Wire);



      // ustawienie klawiatury
const byte ROWS = 4; //cztery rzędy
const byte COLS = 3; //trzy kolumny
char hexaKeys[ROWS][COLS] = {
  {'2','1','3'},
  {'5','4','6'},
  {'8','7','9'},
  {'0','*','#'}};

char message1[]="1 00:05 EC 'SOBIESKI' Wien";
char message2[]="2 01:15 EC 'POLONIA' Berlin";
char message3[]="3 02:00 EC 'CHOPIN' Graz";
char message4[]="4 03:30 EC 'SILESIA' Praha";
char message5[]="1 04:05 EIP 'GIBKI CUG' Warszawa Wsch.";
char message6[]="2 05:00 TLK 'JASNA G\013RA' Cz\005stochowa";
char message7[]="3 05:55 EIC 'KORMORAN' Olsztyn G\025.";
char message8[]="4 06:20 IC 'TATRY' Zakopane";
char message9[]="1 07:15 IC 'G\013RAL' Bielsko Bia\025a";
char message10[]="2 07:30 EIC 'LATARNIK' Ko\025obrzeg";
char message11[]="3 08:00 K\006 'SZTYGAR' Tarnowskie G\014ry";
char message12[]="4 08:05 IC 'CZANTORIA' Wis\025a G\025\005bce";
char message13[]="1 11:55 TLK 'GRANICA' Cha\025upki";
char message14[]="2 12:00 IC 'SUDETY' K\025odzko";
char message15[]="3 12:10 IC 'LAJKONIK' Krak\014w";
char message16[]="4 12:25 K\006 'BESKIDY' \016ywiec";
char message17[]="1 14:15 K\006 'G\013RNIK' Gliwice";
char message18[]="2 14:40 K\006 'FIAT' Tychy Lodowisko";
char message19[]="3 15:00 PR 'WARTA' Wielu\023 D\003browa";
char message20[]="4 15:25 TLK 'BOLEK I LOLEK' Wodzis\025aw \006l.";
char message21[]="1 17:30 IC 'ODRA' Opole";
char message22[]="2 17:40 EIP 'PRZEMY\006LANIN' Przemy\007l G\025.";
char message23[]="3 17:55 K\006 'SPODEK' Katowice";
char message24[]="4 18:15 EIC 'KARKONOSZE' Jelenia G\014ra";
char message25[]="1 19:00 EIP 'NEPTUN' Hel";
char message26[]="2 19:20 K\006 'PIRAT' Lubliniec";
char message27[]="3 19:45 PR 'SPRINTER' \016ywiec";
char message28[]="4 20:00 K\006 'GWAREK' Racib\014rz";
char message29[]="1 21:00 EIC 'BA\024TYK' Gdynia G\025.";
char message30[]="2 21:30 EIP 'PIAST' Pozna\023 G\025.";
char message31[]="3 21:45 PR 'GIBKI CUG' Tarnowskie G\014ry";
char message32[]="4 22:00 IC 'CHEMIK' P\025ock";
char message33[]="1 22:05 EIC 'WYDMY' Ustka";
char message34[]="2 22:40 TLK 'SZYCHTA' Sosnowiec P\025d.";
char message35[]="3 23:20 EIC 'WOLIN' \006winouj\007cie";
char message36[]="4 23:50 EC 'LW\013W EXPRESS' Kiev";
   int x, minX;

      // podłączenie klawiatury do Arduino   
byte rowPins[ROWS] = {18, 5, 17, 16};  //Piny, do których podłączamy wyprowadzenia od rzędów
byte colPins[COLS] = {2, 4, 15}; //Piny, do których podłączamy wyprowadzenia od kolumn

Keypad keypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );

  void setup(){

  Wire.begin(OLED_SDA, OLED_SCL);
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setTextWrap(false);
  x = display.width();
  minX = -16 * strlen(message1);
  }

  void wyswietl(const char *msg1, const char *msg2, const char *msg3, const char *msg4)
{
    display.ssd1306_command(SSD1306_DISPLAYON);
    display.clearDisplay();
    display.setTextSize(2); // wystarczy raz
    display.setCursor(x,0);
    display.print(msg1);
    display.setCursor(x,16);
    display.print(msg2);
    display.setCursor(x,32);
    display.print(msg3);
    display.setCursor(x,48);
    display.print(msg4);
    display.display();
    x -= 1;
}

  void loop(){
 static byte y = 0;
 static long last = 0;
 static byte kopia = 0;

  char key = keypad.getKey();
      Serial.println(key);
 
  if (key == '1') { 
    delay(500);       
   x= display.width();
   y = 1;
   kopia = 1;
} else if (key == '2') { 
   delay(500);       
   x= display.width();
   y = 2;
   kopia = 2;
} else if (key == '3') { 
   delay(500);
   x= display.width();
   y = 3;
   kopia = 3;
} else if (key == '4') { 
   delay(500);
   x= display.width();
   y = 4;
   kopia = 4;
} else if (key == '5') { 
   delay(500);
   x= display.width();
   y = 5;
   kopia = 5;
} else if (key == '6') { 
   delay(500);
   x= display.width();
   y = 6;
   kopia = 6;
} else if (key == '7') { 
   delay(500);
   x= display.width();
   y = 7;
   kopia = 7;
} else if (key == '8') { 
   delay(500);
   x= display.width();
   y = 8;
   kopia = 8;
} else if (key == '9') { 
   delay(500);
   x= display.width();
   y = 9;
   kopia = 9;
} else if (key == '0') { 
   delay(500);
   x= display.width();
   y = 0;
   kopia = 0;
}

if (millis() - displayctl < SCROLL_STEP) return;
displayctl = millis();

switch(y) {
        case 0:
        display.ssd1306_command(SSD1306_DISPLAYOFF);
        break;
        
        case 1:
        wyswietl(message1, message2, message3, message4);
        break;

        case 2:
        wyswietl(message5, message6, message7, message8);
        break;

        case 3:
        wyswietl(message9, message10, message11, message12);
        break;

        case 4:
        wyswietl(message13, message14, message15, message16);
        break;

        case 5:
        wyswietl(message17, message18, message19, message20);
        break;

        case 6:
        wyswietl(message21, message22, message23, message24);
        break;

        case 7:
        wyswietl(message25, message26, message27, message28);
        break;

        case 8:
        wyswietl(message29, message30, message31, message32);
        break;

        case 9:
        wyswietl(message33, message34, message35, message36);
        break;

   case 10: 
   display.clearDisplay();
   display.setCursor(18,0);
   display.setTextSize(1);
   display.print("KATOWICE BRYNOW");
   display.setTextSize(3);
   display.setCursor(20,15);
   display.print("15:20");
   display.display();
   y = 11;
   last = millis();
   break;

   case 11:
   if (millis() - last > 3000UL) { // 3000 = 3 sekundy
    y = kopia;
    x = display.width();
    }
  break;
  }
  
    
  if(x < minX) {
    x = display.width();
    y = 10;
   }
}

 

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

OK, jeśli to działa to spróbujmy teraz trochę posprzątać.

Przede wszystkim to co mówiłem o zmiennych. Po pierwsze - zdecydujmy się na język. Polski jest fajny, ale bez polskich literek czasem można się pogubić. Mieszanka językowa polsko-angielska też nie jest za ciekawa. Pozostańmy więc przy angielskim.

  • Zmienna o nazwie 'y' niknie z programu. W jej miejsce pojawia się zmienna globalna currentMsg (to co jest rzeczywiście wyświetlane)
  • Zmienna o nazwie 'kopia' niknie z programu. W jej miejsce pojawia się zmienna globalna scheduleMsg (czyli komunikat rozkładu)
  • Zmienna o nazwie 'last' niknie z programu. W jej miejsce pojawia się zmienna globalna lastLocalMsg (kiedy zaczęto wyświetlać nazwę stacji)
  • Zmienną 'x' pozostawimy na razie bez zmian...

Tak więc mamy przed setup() (tam gdzie zwykło się umieszczać deklaracje zmiennych):
 

byte currentMsg=0; // nic nie wyświetlamy
byte scheduleMsg=0; // nie wyświetlamy rozkładu
uint32_t lastLocalMsg; // to jest właściwy typ do trzymania czasu a nie żaden long.

W związku z tym początek głównej pętli będzie wyglądać tak:
 

void loop()
{
    char key = keypad.getKey();

Na razie możesz uczynić stosowne poprawki kosmetyczne (pozmieniać te nazwy zmiennych, skompilować program, sprawdzić czy działa i jeśli działa to czytać dalej)

Operujemy teraz cały czas jakimiś dziwacznymi zmiennymi typu messageCośtam. To jest dopuszczalne jak tych wiadomości jest dwie czy trzy, ale nie więcej. Zróbmy sobie z nich po prostu tablicę:

char * messages[] = {
    "1 00:05 EC 'SOBIESKI' Wien",
    "2 01:15 EC 'POLONIA' Berlin",
    "3 02:00 EC 'CHOPIN' Graz",
    "4 03:30 EC 'SILESIA' Praha",
    "1 04:05 EIP 'GIBKI CUG' Warszawa Wsch.",
    "2 05:00 TLK 'JASNA G\013RA' Cz\005stochowa",
    "3 05:55 EIC 'KORMORAN' Olsztyn G\025.",
    "4 06:20 IC 'TATRY' Zakopane",
    "1 07:15 IC 'G\013RAL' Bielsko Bia\025a",
    "2 07:30 EIC 'LATARNIK' Ko\025obrzeg",
    "3 08:00 K\006 'SZTYGAR' Tarnowskie G\014ry",
    "4 08:05 IC 'CZANTORIA' Wis\025a G\025\005bce",
    "1 11:55 TLK 'GRANICA' Cha\025upki",
    "2 12:00 IC 'SUDETY' K\025odzko",
    "3 12:10 IC 'LAJKONIK' Krak\014w",
    "4 12:25 K\006 'BESKIDY' \016ywiec",
    "1 14:15 K\006 'G\013RNIK' Gliwice",
    "2 14:40 K\006 'FIAT' Tychy Lodowisko",
    "3 15:00 PR 'WARTA' Wielu\023 D\003browa",
    "4 15:25 TLK 'BOLEK I LOLEK' Wodzis\025aw \006l.",
    "1 17:30 IC 'ODRA' Opole",
    "2 17:40 EIP 'PRZEMY\006LANIN' Przemy\007l G\025.",
    "3 17:55 K\006 'SPODEK' Katowice",
    "4 18:15 EIC 'KARKONOSZE' Jelenia G\014ra",
    "1 19:00 EIP 'NEPTUN' Hel",
    "2 19:20 K\006 'PIRAT' Lubliniec",
    "3 19:45 PR 'SPRINTER' \016ywiec",
    "4 20:00 K\006 'GWAREK' Racib\014rz",
    "1 21:00 EIC 'BA\024TYK' Gdynia G\025.",
    "2 21:30 EIP 'PIAST' Pozna\023 G\025.",
    "3 21:45 PR 'GIBKI CUG' Tarnowskie G\014ry",
    "4 22:00 IC 'CHEMIK' P\025ock",
    "1 22:05 EIC 'WYDMY' Ustka",
    "2 22:40 TLK 'SZYCHTA' Sosnowiec P\025d.",
    "3 23:20 EIC 'WOLIN' \006winouj\007cie",
    "4 23:50 EC 'LW\013W EXPRESS' Kiev"
};

Teoretycznie nic to nie dało, ponieważ do funkcji wyswietl musielibyśmy przekazywać parametry typu:

wyswietl(messages[0], messages[1], messages[2], messages[3]);

Spróbujmy więc zrobić coś, aby funkcja 'wyswietl' była jakaś bardziej sensowna:

void wyswietl(int n)
{
    display.ssd1306_command(SSD1306_DISPLAYON);
    display.clearDisplay();
    display.setTextSize(2); // wystarczy raz
    int i;
    for (i=0;i<4; i++) {
        display.setCursor(x,i*16);
        display.print(messages[(n-1) * 4] + i);
    }
    display.display();
    x -= 1;
}

Jakby ładniejsza się zrobiła... no ale co to zmienia?

A zmienia tyle, że możemy teraz zrobić prostą konstrukcję typu:

if (currentMessage >= 1 && currentMessage <= 9) {
    wyswietl(currentMessage);
    return;
}

switch(currentMessage) {
    case 10:
    // tu kod dla 10
    break;
    
    case 11:
    // tu kod dla 11
    break;

    default: //zamiast case 0
    // tu kod dla 0
    break;
}

Jak się skrócił kod? Ile linijek będziesz musiał zmienić gdy podłączysz display 128x32?

W ramach odpoczynku przy wieczornej herbatce wymyśl jakąś fajną nazwę dla funkcji 'wyswietl'

Stay tuned!

 

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.