Skocz do zawartości

Arduino w modelarstwie kolejowym


prezesedi

Pomocna odpowiedź

Witam wszystkich.

Swoją przygodę z Arduino zacząłem niedawno, więc proszę o wyrozumiałość gdyż nie znam wszystkich pojęć ani też nie jestem programistą.

Jako modelarz kolejowy postanowiłem trochę zautomatyzować makietę kolejową i dodać kilka ciekawych rozwiązań opartych na zastosowaniu prostych modułów z Arduino (jeśli ktoś ma jeszcze inne pomysły niż poniższe, to proszę pisać).

Na pierwszy ogień poszedł wyświetlacz dworcowy, a w napisaniu kodu do owego urządzenia bardzo duży wkład wnieśli koledzy @ethanak oraz @farmaceuta za co kolejny raz dziękuję. Wspomniany wyświetlacz oferuje wyświetlanie rozkładu jazdy pociągów na stacji. Wyświetlany jednocześnie jest rozkład dla czterech pociągów, opis przewija się, a na koniec wyświetlana jest stacja kolejowa i godzina (niestety na razie ustawiona na stałe). Mamy 9 komunikatów pod 9ma przyciskami klawiatury membranowej oraz czyszczenie wyświetlacza pod '0'. Zaznaczam, że cały rozkład został zmyślony na potrzeby owego urządzenia, więc proszę nie pisać, że pociąg "SZYCHTA" nigdy nie istniał.

Kod zamieszczam poniżej - może komuś się przydać.

#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 = -12 * 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;
   }
}

Kolejne usprawnienie makiety o którym pomyślałem, to sterowanie semaforami.

Napisałem krótki i prosty kod (bo tylko na tyle moje wiedza mi pozwala), dzięki któremu jednym przyciskiem ustawiam 10 różnych sygnałów na semaforze.

Semafor pięciokomorowy (5 świateł, od góry zielone, pomarańczowe, czerwone, pomarańczowe, białe - zgodnie z występowaniem na kolei). 10 sygnałów przełączanych jednym klawiszem typu switch w pętli. Kod poniżej:

void setup() {
  pinMode(8, OUTPUT); //Dioda zielona
  pinMode(9, OUTPUT); //Dioda pomarańczowa1
  pinMode(10, OUTPUT); //Dioda czerwona
  pinMode(11, OUTPUT); //Dioda pomarańczowa2
  pinMode(12, OUTPUT); //Dioda biała
 
  pinMode(7, INPUT_PULLUP); //Przycisk
 
  digitalWrite(8, LOW); //Wyłączenie diod
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
}
 
void loop()
{
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
  
  //S1
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH); //czerwona
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S2
  digitalWrite(8, HIGH); //zielona
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S3
  digitalWrite(8, HIGH); //zielona on
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  delay(500);
  digitalWrite(8, LOW); //zielona off
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  delay(500);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S4
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH); //pomarańczowa1 on
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  delay(500);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW); //pomarańczowa1 off
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  delay(500);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S5
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH); //pomarańczowa1
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S10
  digitalWrite(8, HIGH); //zielona
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //pomarańczowa2
  digitalWrite(12, LOW);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S11
  digitalWrite(8, HIGH); //zielona on
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //pomarańczowa2
  digitalWrite(12, LOW);
  delay(500);
  digitalWrite(8, LOW); //zielona off
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //pomarańczowa2
  digitalWrite(12, LOW);
  delay(500);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S12
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH); //pomarańczowa1 on
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //pomarańczowa2
  digitalWrite(12, LOW);
  delay(500);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW); //pomarańczowa1 off
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //pomarańczowa2
  digitalWrite(12, LOW);
  delay(500);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //S13
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH); //pomarańczowa1
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //pomarańczowa2
  digitalWrite(12, LOW);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) { //Czekaj na wciśnięcie przycisku
	
  //Sz
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH); //czerwona
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //biała on
  delay(500);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH); //czerwona
  digitalWrite(11, LOW);
  digitalWrite(12, LOW); //biała off
  delay(500);
  }


  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) {} //Czekaj na wciśnięcie przycisku
  delay(1000);
}

I teraz prośba do Was, zaawansowanych w pisaniu kodu - chciałbym zmienić przycisk na klawiaturę 4x4 i wyświetlać sygnały po wciśnięciu dwóch/trzech przycisków na klawiaturze (co łatwiejsze do wykonania - nie musi być tzw. zatwierdzenia klawiszem '#'). Dlaczego? Wciskanie przycisku i szukanie odpowiedniego sygnału jest czasochłonne i nieefektywne. Przejście z S2 na S1 to sklikanie wszystkich sygnałów po kolei.

Chciałbym, by działało to na poniższej zasadzie:

sygnał S1 po wciśnięciu A1 (lub A1#)

sygnał S2 po wciśnięciu A2 (lub A2#)

...

sygnał Sz po wciśnięciu A0 (lub A0#)

Na chwilę obecną przerobiłem przycisk SWITCH na klawisz '1' na klawiaturze, jednak dalsze kroki są dla mnie czarną magią

#include <Keypad.h>

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

        // podłączenie klawiatury do Arduino   
byte rowPins[ROWS] = {8, 7, 6, 5};  //Piny, do których podłączamy wyprowadzenia od rzędów
byte colPins[COLS] = {4, 3, 2, 1}; //Piny, do których podłączamy wyprowadzenia od kolumn

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


void setup() {
  pinMode(9, OUTPUT); //Dioda zielona
  pinMode(10, OUTPUT); //Dioda pomarańczowa1
  pinMode(11, OUTPUT); //Dioda czerwona
  pinMode(12, OUTPUT); //Dioda pomarańczowa2
  pinMode(13, OUTPUT); //Dioda biała
 
  digitalWrite(9, LOW); //Wyłączenie diod
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
}
 
void loop()
{
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
  
  //S1
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //czerwona
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S2
  digitalWrite(9, HIGH); //zielona
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S3
  digitalWrite(9, HIGH); //zielona on
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  delay(500);
  digitalWrite(9, LOW); //zielona off
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  delay(500);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S4
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH); //pomarańczowa1 on
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  delay(500);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW); //pomarańczowa1 off
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  delay(500);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S5
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH); //pomarańczowa1
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  }
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S10
  digitalWrite(9, HIGH); //zielona
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //pomarańczowa2
  digitalWrite(13, LOW);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S11
  digitalWrite(9, HIGH); //zielona on
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //pomarańczowa2
  digitalWrite(13, LOW);
  delay(500);
  digitalWrite(9, LOW); //zielona off
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //pomarańczowa2
  digitalWrite(13, LOW);
  delay(500);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S12
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH); //pomarańczowa1 on
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //pomarańczowa2
  digitalWrite(13, LOW);
  delay(500);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW); //pomarańczowa1 off
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //pomarańczowa2
  digitalWrite(13, LOW);
  delay(500);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //S13
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH); //pomarańczowa1
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //pomarańczowa2
  digitalWrite(13, LOW);
  }

  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (keypad.getKey() != '1') { //Czekaj na wciśnięcie przycisku
	
  //Sz
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //czerwona
  digitalWrite(12, LOW);
  digitalWrite(13, HIGH); //biała on
  delay(500);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH); //czerwona
  digitalWrite(12, LOW);
  digitalWrite(13, LOW); //biała off
  delay(500);
  }


  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) {} //Czekaj na wciśnięcie przycisku
  delay(1000);
}

Czy ktoś może od siebie coś zaproponować? Kombinacje B0-B9; C0-C9; D0-D9 chciałbym zostawić dla semaforów nr 2-3-4.

Tak wygląda układ na symulatorze

https://wokwi.com/projects/338066449320903252

Edytowano przez prezesedi
Link do komentarza
Share on other sites

Dobra, to tak jak już kiedyś wspominałem.

Loop powinien wyglądać tak:

void loop()
{
  int key = getSequenceKey();
  wyswietl(key);
  semafor(key);
  drugi_semafor(key);
  coś_tam_jeszcze(key);
}

Tę funkcję getSequenceKey dostaniesz w prezencie, tylko muszę klawiaturę znaleźć (leży na dnie któregoś pudełka, ale na jutro będziesz miał funkcję). Tyle że musisz pozbyć się tego ifa który siedzi w loop i przenieść go wo wyswietl().

 

Edytowano przez ethanak
Link do komentarza
Share on other sites

No niestety - klawiatura mi gdzieś przepadła, a więc kawałek programu bez sprawdzania:

#include <Keypad.h>

/*
 * tu wszystkie linie jak dla keypad
 * ważne,aby klawiszom A, B, C i D odpowiadały
 * kody 'A', 'B', 'C' i 'D', reszta jest dowolna
 * czyli coś w stylu:

char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}};

*/

static uint32_t seqKeyTimer;
static uint8_t seqKeyState;

#define SEQKEY_TIMEOUT 1500UL

uint16_t getSequenceKey(void)
{
    uint8_t = keypad.getKey();
    if (!k) {
        // zapominamy o wciśnięciu prefiksu jeśli za długo się namyślamy
        if (seqKeyState && millis() - seqKeyTimer > SEQKEY_TIMEOUT) {
            seqKeyState = 0;
        }
        return 0;
    }
    if (k >= 'A' && k <= 'D') {
        seqKeyState = k;
        seqKeyTimer = millis();
        return 0;
    }
    if (!seqKeyState) {
        // nie było prefiksu
        return 0;
    }
    uint16_t rc = (seqKeyState << 8) | k;
    seqKeyState = 0;
    return rc;
}

#define SEQ_PREFIX(a) ((char *)((a) >> 8))
#define SEQ_KEY(a) ((char *)((a) & 255))
#define SEQ_COMBINE(prefix, key) ((((prefix) << 8) & 0xff00) | ((key) & 0xff))

    

W programie robisz coś takiego:
 

void loop()
{
	uint16_t key = getSequenceKey();

	switch(key) {
		case SEQ_COMBINE('A','1'):
		// kod dla wyświetlania pierwszego komunikatu

		case SEQ_COMBINE('B','1'):
		// kod dla ustawienia semafora B na wartość 1

// i tak dalej

Najlepiej by było aby wyświetlanie, semafory i tak dalej umieścić w oddzielnych funkcjach (uwierz, funkcje nie gryzą) ale jak lubisz mieć choinkę ze switch-case w loop to na upartego możesz.

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

@prezesedi no a ten dziadowski kod co Ci wysłałem na priv ostatni raz to nie działa??..ja nigdy nie łączyłem kilku znaków w Stringa(nie potrzebowałem), więc na szybko znalazłem przykład pierwszy z brzegu i być może popełniłem jakiś nie wielki błąd...🙃 ( a Ty zamilkłeś bez odpowiedźi czy działa😉

Może kolega ethanak zauważy ewentualny błąd...(wydaje mi się że problem (jeśli jest) to może być w tym pierwszym warunku if..no klawiatura chyba nie ma odpowiednika "available" no a pasuje wiedzieć kiedy przylazł pierwszy znak)  



void loop() {

static char key[2];
static bool stan = 0;
static byte i = 0;
static String komenda = "";
  
 if (keypad.getKey() ) {
  key[i] = keypad.getKey();
  i++;
  last = millis();
  stan = 1;
  }

 if (komenda == "A0") { 
  Serial.println("OK");
  komenda = "";
  }
  
  if (millis() - last >= 1500UL && stan == 1) {
    komenda = (String)key[0] + key[1];
    i = 0;
    stan = 0; 
    }
  }
    

 

Edytowano przez farmaceuta
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, farmaceuta napisał:

klawiatura chyba nie ma odpowiednika "available"

Nie ma, zwraca 0 jeśli nie został naciśnięty klawisz i kod klawisza gdy klawisz został naciśnięty, a nie kiedy jest wciśnięty.

W związku z tym taki fragment kodu:

if (keypad.getKey() ) {
  key[i] = keypad.getKey();

wstawi do key zawsze zero.

Poza tym kolega ethanak jak widzi kod, w którym do porównania dwóch intów ze stałą używa się malloc/realloc/free i memcmp zastanawia się, czy po to są procki z zegarkiem ponad 200 MHz aby zmusić je do działania w tempie jakiegoś attiny na 8 MHz...

Edytowano przez ethanak
  • Pomogłeś! 1
Link do komentarza
Share on other sites

12 minut temu, ethanak napisał:

zwraca 0 jeśli nie został naciśnięty klawisz i numer klawisza gdy klawisz został naciśnięty, a nie kiedy jest wciśnięty.

W związku z tym taki fragment kodu:


if (keypad.getKey() ) {
  key[i] = keypad.getKey();

wstawi do key zawsze zero.

 

I tak mi coś mówiło ale lenistwo nie pozwoliło mi poszukać kabli w celu podpięcia klawiatury i sprawdzenia czy mi dobrze mówi (to coś) 😜 

14 minut temu, ethanak napisał:

Poza tym kolega ethanak jak widzi kod, w którym do porównania dwóch intów ze stałą używa się malloc/realloc/free zastanawia się, czy po to są procki z zegarkiem ponad 200 MHz aby zmusić je do działania w tempie jakiegoś attiny na 8 MHz...

Ja tak zrobiłem??😉 

...to może tak zadziała 

key = keypad.getKey();
  if (key != 0 ) {
  key[i] = keypad.getKey();
  

 

Link do komentarza
Share on other sites

13 minut temu, farmaceuta napisał:

Ja tak zrobiłem??

Tak. Poszukaj w swoim kodzie wywołań wszystkich czterech funkcji o których pisałem...

 

13 minut temu, farmaceuta napisał:

...to może tak zadziała 

Nie, z przyczyn takich samych jak poprzednio.

Jak myślisz, jeśli getKey zwrócił np. 'A' to jaki będzie rezultat wywołania getKey np. po milisekundzie?

 

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

10 minut temu, ethanak napisał:

 

Jak myślisz, jeśli getKey zwrócił np. 'A' to jaki będzie rezultat wywołania getKey np. po milisekundzie?

 

Tfu! tfu! Pisemne przejęzyczenie 😉 chodzilo mi oczywiście o..

key = keypad.getKey();
  if (key != 0 ) {
  key[i] = key;
  

 

12 minut temu, ethanak napisał:

Poszukaj w swoim kodzie wywołań wszystkich czterech funkcji o których pisałem...

Nie no to tylko taki luźny przykład podałem żeby się dowiedzieć co tam złego może być w tym kodzie, a jeśli by działać miało i ktoś by chciał to wykorzystywać to wtedy można się bawić w upiekszanie całości, czyli funkcje o ktorych wspominasz etc😉 (coś mi zaczyna świtać o tym Stringu i czemu są zle 🤔 zaraz doczytam)

Link do komentarza
Share on other sites

Koledzy jak zwykle mają ciekawe pomysły, jednak ja przed dodaniem poprawek do kodu muszę korzystać z Google by zrozumieć, co dany kawałek kodu robi i jak go wykorzystać 🙂

Link do komentarza
Share on other sites

6 minut temu, prezesedi napisał:

jednak ja przed dodaniem poprawek do kodu muszę korzystać z Google by zrozumieć, co dany kawałek kodu robi i jak go wykorzystać

A zajrzałeś do mojego kodu? Czego tam nie rozumiesz i dlaczego nie znalazłeś sposobu w jaki sposób go wykorzystać (który przecież podałem)?
BTW zamiast w google szukałbym raczej w podręczniku C/C++ 😉

7 minut temu, farmaceuta napisał:

chodzilo mi oczywiście o..

key = keypad.getKey();
if (key) {

 

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

Oczywiście, że zajrzałem i wrzuciłem go do symulacji. Zmieniłem także w LOOP dla A1, A2, A3 ... Jednak wywala mi błędy i staram się zrozumieć dlaczego

Nie rozumiem tech wpisów:

static uint32_t seqKeyTimer;
static uint8_t seqKeyState;

#define SEQKEY_TIMEOUT 1500UL

#define SEQ_PREFIX(a) ((char *)((a) >> 8))
#define SEQ_KEY(a) ((char *)((a) & 255))
#define SEQ_COMBINE(prefix, key) ((((prefix) << 8) & 0xff00) | ((key) & 0xff))

a błąd jest taki:

 

Przechwytywanie4.JPG

Link do komentarza
Share on other sites

void loop() {

static bool stan = 0;
static byte i = 0;
static char tab[5];
static bool sprawdź = 0;
  
  char key = key.getchar();
 if (key) {
  tab[i] = key;
  i++;
  last = millis();
  stan = 1;
  }

 if (strcmp(tab, "A0") == 0 && sprawdź == 1) { 
  Serial.println("OK");
  tab[] = "";
   sprawdź = 0;
  }
  
  if (millis() - last >= 1500UL && stan == 1) {
    sprawdź = 1;
    i = 0;
    stan = 0; 
    }
  }
    

No a takie coś już lepsze niż ten String?😉 (Tak na przyszłość pytam)

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

2 minuty temu, farmaceuta napisał:

No a takie coś już lepsze niż ten String?

Pewnie że lepsze. Tylko nie strcmp a memcmp (zawsze porównywane stringi mają długość 2, trzeba o to zadbać), no i oczywiście właściwe zmienne 🙂

Rozumiem ze chodzi o samą koncepcję a nie konkretny kod.

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

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.