Stwórzmy więc mini bazę danych na potrzeby naszego routera 433 do zapamiętywania kodów urządzeń (adresów):
struct stadres {
long kod;
int impuls;
};
#define ilekod 3 //rozmiar tablicy kodów
stadres tablica_adres[ilekod]; //deklaracja tablicy kodów
Rekordami bazy danych są kolejne pozycje tabicy [0], [1]..... Tu rekordem jest struktura zawierająca dwie dane (dwa pola rekordu) - kod i impuls - specyficzne dla każdego urządzenia bezprzewodowego. Na najniższym (bajtowym) poziomie rekord składa się z 6 bajtów - 4 bajtowe pole rekordu dla kodu w formacie long i 2 dla impulsu w formacie int.
W poprzednim wpisie ćwiczyłem adresowanie poszczególnych pól rekordów a więc kodu i impulsu dla danego urządzenia. Przy użyciu tabeli struktur jest to banalnie proste. Jeśli chcemy odczytać kod dla 11-stego urządzenia w tabeli piszemy po prostu
long l = tablica_adres[11].kod;
a kompilator sam wyliczy adres pierwszego bajtu zmiennej kod dla 11 rekordu tablicy i pobierze 4 kolejne bajty do zmiennej typu long. Coś pięknego. Zastanawiam się ile dłubania wymagałoby napisanie takiej procedury w asemblerze. C to potęga nawet w tak uproszczonej formie jaka jest dostępna w Arduino IDE. Zbyszek nie ma się co zastanawiać - wgrywaj program i do roboty!!!
Procedury zapisu i odczytu kodu w eepromie nieco się uprościły i fragment programu odpowiedzialny z odczyt kodu i zapisanie go do pamięci przybrał postać
struct stadres {
long kod;
int impuls;
};
#define pamkod 100 // początek tablicy kodów we flash
#define ilekod 3 //romiar tablicy kodów
stadres tablica_adres[ilekod]; //deklaracja tablicy kodów
int nrpozkod = 0; //nr pozycji do zapisu kodu pobierany z aplikacji BLYNK
int stan = 1; // nr stanu programu
int p_kod = 0; //stan przycisku aplikacji BLYNK - start programu i zapisu do pamięci
long KOD = 0; // kod urządzenia do zapisu w pamięci
int IMPULS = 0; //impuls urządzenia do zapisu w pamięci
void savetab () { //zapisz tabelę kodow do flash
int liczadres = pamkod;
EEPROM.begin(512);
EEPROM.put(liczadres, tablica_adres);
EEPROM.end(); // EEPROM.commit();
}
void readtab() { // odczyt tabeli kodów z flash
int liczadres = pamkod;
EEPROM.begin(512);
EEPROM.get(liczadres, tablica_adres);
EEPROM.end(); // EEPROM.commit();
}
BLYNK_WRITE(V110) {
nrpozkod = param.asInt(); //nr pozycji zapisu kodów - widget menu
}
BLYNK_WRITE(V111) {
p_kod = param.asInt(); //stan klawisza "start zapisu kodu" 1 = start procedury
}
void zapisz_kod() {
tablica_adres[nrpozkod].kod = KOD;
tablica_adres[nrpozkod].impuls = IMPULS;
Serial.print(" nr " + String(nrpozkod)); Serial.print(" zapisuje kod " + String(KOD)); Serial.println(" impuls " + String(IMPULS));
savetab();
} //procedura wywołania zapisu tablicy kodów do pamięci nieulotnej
void do_zapisz_kod() { // resety i zapisz kod
zapisz_kod();
Blynk.virtualWrite(V112, KOD); //wyświetlanie zapisywanego kodu
Blynk.virtualWrite(V111, 0); //przełcznik procedury wyłącz
reset_all();
}
void reset_all() { // resety po zakończeniu procedury
o_kod = 0; KOD = 0; p_kod = 0; o_impuls = 0;
}
void KOD_do_eeprom() { //graf czyli automat skończony procedury zapisu kodu 433MHz do pamięci
switch (stan) {
case 1: {
if (p_kod != 0) stan = 2; else stan = 1;
o_kod = 0; KOD = 0;
} break;
case 2: {
if (p_kod == 0) stan = 1;
if (o_kod != 0) stan = 3;
} break;
case 3: {
KOD = o_kod;
IMPULS = o_impuls;
o_kod = 0;
stan = 4;
} break;
case 4: {
if (p_kod == 0) stan = 5;
if (o_kod != 0) stan = 6;
} break;
case 5: {
do_zapisz_kod();
stan = 1;
} break;
case 6: {
if (o_kod == KOD) stan = 5; else stan = 3;
} break;
default: break;
}
}
Zapisuję i odczytuję wszystko za jednym zamachem to znaczy zapisywana jest cała tablica pomimo zmiany tylko jednego jej rekordu. Tablica to nie tylko wygodny sposób zapisu danych do pamięci nieulotnej. To przede wszystkim wygodne narzędzie do żonglowania dużą ilością różnych danych w programie. A dzięki temu że tablica tworzona jest w RAMie procesora to znakomicie przyspiesza wszelkie operacje na zmiennych. Na początku programu załaduję zmienną tablica_adres zawartością przechowywaną w eepromie i to ta zmienna będzie bazą dla wszelkich dalszych operacji na adresach. Jeśli z jakiegokolwiek powodu pola rekordu w tablicy tablica_adres w czasie działania programu ulegną zmianie niezwłocznie nastąpi kolejny zapis do pamięci aktualizujący zawartość eepromu. Taki sposób znacząco zwiększa ilość operacji na pamięci nieulotnej co w przyszłości może być pewnym problemem (maksymalna gwarantowana liczba zapisów dla pamięci flash to ok 10tys. razy). Ale tym sposobem mam pewność iż dane zostaną zapamiętane w pamięci co jest ważne np. w przypadku niespodziewanego resetu mikrokontrolera.
Dla sprawdzenia działania procedury przygotowałem mały test
void setup()
.................
tablica_adres[0] = {1000000, 100}; //wypełnienie tablicy wartością początkową adresów
tablica_adres[1] = {111111, 111};
tablica_adres[2] = {22222, 222};
Serial.print(tablica_adres[0].kod); Serial.println(" wartosc poczatkowa");
Serial.print(tablica_adres[1].kod); Serial.println(" wartosc poczatkowa");
Serial.print(tablica_adres[2].kod); Serial.println(" wartosc poczatkowa");
readtab(); // odczytuje z eepromu
Serial.print(tablica_adres[0].kod); Serial.println(" z eeprom");
Serial.print(tablica_adres[1].kod); Serial.println(" z eeprom");
Serial.print(tablica_adres[2].kod); Serial.println(" z eeprom");
}
W procedurze setup() ustawiam wstępnie pola rekordu zmiennej tablica_adres a następnie zapisuje ją danymi pobranymi z eepromu. Oba stany - przed i po odczycie pamięci wyświetlam. Skutek działania po resecie mikrokontrolera jak niżej
CBDO
Automat skończony do dekodowania kodów ᐯ
Zapisywanie kodów do EEPROMu ᐯ
typ struktura i zapis tablicy struktur do EEPROMu ᐯ
baza danych i operacje na tablicy struktur ᐯ
W tym tempie router powstanie pewnie w następnej pięciolatce - no ale dzięki temu jest szansa, że ciąg dalszy jednak kiedyś nastąpi.
Wcześniejsze odcinki serialu
http://100-x-arduino.blogspot.com/2017/11/router-433-mhz-aczymy-rozne-systemy.html
http://100-x-arduino.blogspot.com/2017/11/router-433-mhz-nauka-czytania-i-pisania.html
http://100-x-arduino.blogspot.com/2017/12/router433-jak-programowac-schematy.html
http://100-x-arduino.blogspot.com/2017/12/esp8266-zapis-do-pamieci-eeprom-kodow.html
http://100-x-arduino.blogspot.com/2017/12/zapis-tablicy-struktur-do-eeproma-nauka.html
109
Brak komentarzy:
Prześlij komentarz