Robisz sobie po prostu nowy typ zmiennej, która ma w sobie X różnych zmiennych. Taką zmienną możesz przypisać jak zmienne int a,b; i potem w programie możesz użyć a=b.
Kod:
struct pakiet{
int a=0;
float b=0;
bajt c=0;
char d=0;
} struktura;
pakiet struktura2;
void setup() {
Serial.begin(115200);
struktura.a=12;
struktura.b=13;
struktura.c=14;
struktura.d=15;
struktura2= struktura;
Serial.println(struktura2.a);
Serial.println(struktura2.b);
Serial.println(struktura2.c);
Serial.println(struktura2.d);
}
void loop() {}
Wszystkie wartości przypisane wewnątrz zmiennej "struktura" zostaną przekopiowane do zmiennej struktura2 i to zobaczysz na wydruku. Do poszczególnych zmiennych odwołujesz się używając operatora '.' i nazwy elementu.
Możesz sobie zrobić np. 1000 tak zdefiniowanych zmiennych, w kodzie programu używasz zawsze do np. wydruku Serial.println(strukturaaktualna.b);, a gdy chcesz zmienić zestaw danych na ten o numerze 678 to wystarczy strukturaaktualna=struktura678 i dopóki znowu tego nie zmienisz będzie brał wszystkie zmienne .a .b .c .d z zestawu 678.
Żeby było łatwiej to nie robisz sobie 1000 zmiennych o różnych nazwach, skoro jest to 1000 tych samych zmiennych (tego samego typu - pakiet) to robisz sobie ich tablicę. Typem zmiennej jest dalej "pakiet".
pakiet tabstr[1000];
Oczywiście 1000 takich zmiennych zjadło by kilka razy RAM w UNO, więc umieść je we flash.
Dla powiedzmy 10 jak nic ciekawego nie robisz to może być RAM, wystarczy go, i wtedy jest prosto:
Kod:
pakiet tabstr[10];
tabstr[5]=struktura;
Serial.println(tabstr[5].a);
Serial.println(tabstr[5].b);
Serial.println(tabstr[5].c);
Serial.println(tabstr[5].d);
W Arduino, czy tam C++ (to właściwie to samo) są obiekty. To rozwinięcie struktur. W obiektach mogą być również funkcje specjalnie przypisane do obsługi danych obiektu.
Choć oczywiście tu użyjesz odwrotnie,
strukturaaktualna=tabstr[5], czy tam któryś i-ty element tablicy.
Tylko wtedy definiując tablicę od razu przypisujesz wartości wszystkim 10 zestawom. Tu się zaciąłem, bo oczywiście nigdy tego nie robiłem, a choć logicznie byłoby robić tak jak z wszystkimi innymi zmiennymi to jednak z tablicami to nie działa. Można zmienne definiować już w czasie działania programu, ale przypisanie zmiennych globalnych od razu trzeba robić w definicji struktury.
A teraz patrz uważnie, bo tego w książkach nie znajdziesz:
Kod:
uint32_t czasTeraz,czasPoprzedni,tik=10; //tik musi byc mniejszy niz 1000 i dzielic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis[32];
struct pakiet { //definicja struktury RAM
int a;
int b;
int c;
int d;
} tabstr[]={ //tablica struktur w RAM z inicjalizacja, mozna dodawac i odejmowac pola (linia to zestaw danych) by sprawdzic jak to wplywa na RAM
{1,2,3,4},
{11,12,13,1},
{21,22,23,24},
{31,32,33,34},
{41,42,43,44},
{51,52,53,54}
};
const pakiet tablicaPROGMEM[] PROGMEM= // a to definicja tablicy struktur we FLASH
{
{311,312,313,31},
{321,322,323,324},
{331,332,333,334},
{341,342,343,344}, //mozna dodawac i odejmowac pola by sprawdzic jak to wplywa na RAM
{351,352,353,354},
};
pakiet struktura;
pakiet struktura2;
void setup() {
Serial.begin(115200);
struktura2={21,22,23,24};
struktura.a=12;
struktura.b=13;
struktura.c=14;
struktura.d=15;
struktura2= struktura;
Serial.println(struktura2.a);
Serial.println(struktura2.b);
Serial.println(struktura2.c);
Serial.println(struktura2.d);
tabstr[4]=struktura;
Serial.println(tabstr[4].a);
Serial.println(tabstr[4].b);
Serial.println(tabstr[4].c);
Serial.println(tabstr[4].d);
for (int i =0; i<6;i++)
{
Serial.println(tabstr[i].a);
Serial.println(tabstr[i].b);
Serial.println(tabstr[i].c);
Serial.println(tabstr[i].d);
Serial.println();
}
memcpy_P( &struktura2, &tablicaPROGMEM[3], sizeof( pakiet)); //przepisanie danych z FLASH do RAM, ze struktury we FLASH do struktury w RAM,
// i wydruk tych wartosci
Serial.println(struktura2.a);
Serial.println(struktura2.b);
Serial.println(struktura2.c);
Serial.println(struktura2.d);
}
void loop() {
czas();
static int zmienna=0;
if (fsekundy)
{
// a teraz zabawa z roznymi zestawami danych w zaleznosci od wartosci zmiennej "zmienna"
memcpy_P( &struktura2, &tablicaPROGMEM[zmienna], sizeof( pakiet));
sprintf(napis,"%02d:%02d:%02d:%02d ",struktura2.a,struktura2.b,struktura2.c,struktura2.d);
Serial.print("Wydruk wartosci aktualnych wartosci struktura2: ");
Serial.println(napis);
if(++zmienna>4) zmienna=0;
}
}
void czas()
{
czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"
{
czasPoprzedni=czasTeraz;
fnTik=1;
nTik++;
if(nTik>=(1000/tik))
{
nTik=0;
sekundy++;
fsekundy=1;
if (sekundy>=60)
{
sekundy=0;
minuty++;
fminuty=1;
if (minuty>=60)
{
minuty=0;
godziny++;
fgodziny=1;
if (godziny>=24)
{
godziny=0;
fdni=1;
dni++;
}
}
}
}
}
}
No część może tak, nie widziałem nigdzie wszystkiego razem.
Gdy pobawisz się ilością zestawów danych w tych dwóch rodzajach tablic to zauważysz, że ta w RAM zjada flash i RAM, a ta z const PROGMEM tylko flash. Znaczki '&' pobierają adres w pamięci zmiennych za nimi, dzięki niemu przepisujesz funkcją memcpy_P dane ze zmiennej we flash do zmiennej w RAM (zmiennej zawierającej całą strukturę). O robaczkach typu & * -> możesz poczytać w książkach.
Może uda Ci się ściągnąć książki o C stąd (darmowe i bez punktów): https://www.elektroda.pl/rtvforum/viewto...6#18012536.