|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
malci Član
Pridružen-a: Sob 15 Sep 2007 21:05 Prispevkov: 792 Aktiv.: 3.92 Kraj: Polhov Gradec
|
Objavljeno: Sre Nov 28, 2018 10:24 pm Naslov sporočila: Optimiziranje arduino code |
|
|
Pozdravljeni!
Do sedaj sem za branje vrednosti iz serijske komunikacije ( za nastavitve..) uporabljal način, kot je v spodnji kodi. A pri zadnjem programu se je pa teh else if stavkov nabralo že več kot 20, pa še nekaj jih moram dodati. Kako bi se dalo ta void optimizirati, oz, kako narediti vsaj bolj preglednega?
lp
Uroš
Koda: |
if (Serial.available()>0) {
delay(50);
uart1();
}
void uart1() {
String sprejem=Serial.readString();
Serial.print("Sprejel sem: ");
Serial.println(sprejem);
if (sprejem.indexOf("imax")>-1){ // če vsebuje niz imax
sprejem=sprejem.substring(sprejem.indexOf("imax")+4,sprejem.indexOf("imax")+7); // izloči imax
Imax=sprejem.toInt(); //preostanek spremeni v int
Serial.println (" Imax: " + String(Imax)); // izpiši novo vrednost
}else if (sprejem.indexOf("umax")>-1){ // če vsebuje niz Umax
sprejem=sprejem.substring(sprejem.indexOf("umax")+4,sprejem.indexOf("umax")+8);
Umax=sprejem.toInt();
Serial.println (" Umax: " + String(Umax));
}else if (sprejem.indexOf("utot")>-1){ // če vsebuje niz Utot
sprejem=sprejem.substring(sprejem.indexOf("utot")+4,sprejem.indexOf("utot")+8);
Utot=sprejem.toInt();
Serial.println (" Utot: " + String(Utot));
}else if (sprejem.indexOf("ufull")>-1){ // če vsebuje niz Ufull
sprejem=sprejem.substring(sprejem.indexOf("ufull")+5,sprejem.indexOf("ufull")+9);
Ufull=sprejem.toInt();
Serial.println (" Ufull: " + String(Ufull));
}else if (sprejem.indexOf("itot1")>-1){ // če vsebuje niz Itot1
sprejem=sprejem.substring(sprejem.indexOf("itot1")+5,sprejem.indexOf("itot1")+8);
Itot1=sprejem.toInt();
Serial.println (" Itot1: " + String(Itot1));
}else if (sprejem.indexOf("itot2")>-1){ // če vsebuje niz Itot2
sprejem=sprejem.substring(sprejem.indexOf("itot2")+5,sprejem.indexOf("itot2")+8);
Itot2=sprejem.toInt();
Serial.println (" Itot2: " + String(Itot2));
}else if (sprejem.indexOf("itot0")>-1){ // če vsebuje niz Itot0
sprejem=sprejem.substring(sprejem.indexOf("itot")+4,sprejem.indexOf("itot")+8);
Itot=sprejem.toInt();
Serial.println (" Itot: " + String(Itot));
}else if (sprejem.indexOf("izpis1")>-1){ // če vsebuje niz izpis1
izpis1=!izpis1; // izpis1 je lahko true/false
Serial.println (" izpis1=" + String(mer));
}else if (sprejem.indexOf("izpis2")>-1){ // če vsebuje niz izpis2
izpis2=!izpis2;
Serial.println (" izpis2=" + String(mer));
}else if (sprejem.indexOf("mer")>-1){ // če vsebuje niz mer
mer=!mer;
Serial.println (" meritve=" + String(mer));
}else if (sprejem.indexOf("act")>-1){ // če vsebuje niz act
active=!active;
Serial.println (" active: " + String(active));
}else if (sprejem.indexOf("x")>-1){ // če vsebuje niz x (x13250 > nastavi napetost na DAC1 ..)
sprejem=sprejem.substring(sprejem.indexOf("x")+1,sprejem.indexOf("x")+6);
Vout1=sprejem.toInt();
Serial.print (" Vout1: " + String(Vout1));
}else if (sprejem.indexOf("y")>-1){ // če vsebuje niz y (y13250 > nastavi napetost na DAC2 ..)
sprejem=sprejem.substring(sprejem.indexOf("y")+1,sprejem.indexOf("y")+6);
Vout2=sprejem.toInt();
Serial.print (" Vout2: " + String(Vout2));
}else if (sprejem.indexOf("cal")>-1){ // če vsebuje niz cal (kalibracija)
Itotref=adc1; Itot1ref=adc2; Itot2ref=adc3;
Serial.println("kalibracija.......");
}else if (sprejem.indexOf("izp")>-1){ // če vsebuje niz izp
izp1();
}else if (sprejem.indexOf("t1")>-1){ // če vsebuje niz t1
sprejem=sprejem.substring(sprejem.indexOf("t1")+2,sprejem.indexOf("t1")+5);
T1=sprejem.toInt();
Serial.println (" T1: " + String(T1));
}else if (sprejem.indexOf("t2")>-1){ // če vsebuje niz t2
sprejem=sprejem.substring(sprejem.indexOf("t2")+2,sprejem.indexOf("t2")+5);
T2=sprejem.toInt();
Serial.println (" T2: " + String(T2));
}else if (sprejem.indexOf("captrim")>-1){ // če vsebuje niz captrim
sprejem=sprejem.substring(sprejem.indexOf("captrim")+7,sprejem.indexOf("captrim")+10);
CapTrim=sprejem.toInt();
Serial.println (" CapTrim: " + String(CapTrim));
}else if (sprejem.indexOf("cap")>-1){ // če vsebuje niz cap
sprejem=sprejem.substring(sprejem.indexOf("cap")+3,sprejem.indexOf("cap")+7);
Capacity=sprejem.toInt();
Serial.println (" Capacity: " + String(Capacity));
}else if (sprejem.indexOf("eeprom")>-1){ // če vsebuje niz eeprom
eeprom();
}
} |
_________________ Elektronika za hobi |
|
Nazaj na vrh |
|
|
Jaka57 Moderator
Pridružen-a: Ned 12 Dec 2004 21:47 Prispevkov: 5773 Aktiv.: 25.91 Kraj: Grosuplje
|
Objavljeno: Sre Nov 28, 2018 11:43 pm Naslov sporočila: |
|
|
Če bi bili tvoji stringi enake dolžine, bi lahko uporabil switch...case:
Koda: |
switch sprejem.substring(1, n) {
case string1:
//kar nekaj
break;
case string2:
//kar nekaj
break;
.
.
.
default:
//kar nekaj
break;
} |
Za meritev pošiljaš "mer" (trije karakterji) toda za izpis pošiljaš komplet vse karakterje. Lahko bi prav tako pošiljal samo tri, recimo "iz1" oz "iz2".....
V končni fazi, bi lahko pošiljal samo dva, na začetku programa pa imaš definirane stringe, kaj je kaj, npr. captrim="ct", izpis1="i1" itd.
Seveda pa to ne gre če pošiljaš kombinacije stringov.
_________________ Lp, Jaka |
|
Nazaj na vrh |
|
|
igo Član
Pridružen-a: Sre 11 Okt 2006 19:11 Prispevkov: 3638 Aktiv.: 17.05
|
Objavljeno: Čet Nov 29, 2018 12:35 am Naslov sporočila: |
|
|
Jaka57 je napisal/a: |
Če bi bili tvoji stringi enake dolžine, bi lahko uporabil switch...case: |
V bistvu sploh ni potreben string, ampak zadostuje navaden char (8 bitov = 1 byte). Paket je potem sestavljen v obliki [Velicina][...Vrednost...], kjer je Velicina vedno 8-bitni char, Vrednost pa ima lahko povsem različne oblike zapisa.
Sprejemna in oddajna enota morata poznati pomen Velicine in obliko Vrednosti (itak to ti določiš), ostalo je trivialno. Ni nujno, da so vse case številke zasedene, ampak jih lepo pregledno izbereš po lastnostih.
Koda: |
switch sprejem.substring(1, n) {
case 11: // 1 byte
//kar nekaj
break;
case 12:
//kar nekaj
break;
.
.
.
case 21: // 2 byta unsigned int
...
case 22:
...
case 31: // 2 byta signed int
...
case 32:
...
case 41: // 4 byti unsigned long
...
case 42:
...
case 81: // 4 byti signed long
...
case 91: // float
...
case 101: // ukaz1, naj nekaj naredi
...
case 111: // ukaz, naj pošlje nazaj obdelano Veličino 11
...
default:
//kar nekaj
break;
} |
_________________ Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor |
|
Nazaj na vrh |
|
|
đzuro Član
Pridružen-a: Čet 22 Maj 2014 17:09 Prispevkov: 47 Aktiv.: 0.39 Kraj: Ljubljana
|
Objavljeno: Ned Dec 02, 2018 3:48 pm Naslov sporočila: |
|
|
Vrednost spremenljivke naj bo istega tipa in pa enake dolzine
|
|
Nazaj na vrh |
|
|
Jaka57 Moderator
Pridružen-a: Ned 12 Dec 2004 21:47 Prispevkov: 5773 Aktiv.: 25.91 Kraj: Grosuplje
|
Objavljeno: Ned Dec 02, 2018 6:15 pm Naslov sporočila: |
|
|
đzuro je napisal/a: |
Vrednost spremenljivke naj bo istega tipa in pa enake dolzine |
Naprimer?
_________________ Lp, Jaka |
|
Nazaj na vrh |
|
|
igo Član
Pridružen-a: Sre 11 Okt 2006 19:11 Prispevkov: 3638 Aktiv.: 17.05
|
Objavljeno: Ned Dec 02, 2018 11:42 pm Naslov sporočila: |
|
|
To sploh ni nujno. Prvi byte (Velicina) je vse, kar je za switch pomembno, znotraj posameznega case primera pa se lahko potem prebere podatek dolg med 0 in n byti. 0 zato, ker je lahko Velicina že veljaven ukaz sprejemni enoti, ostalo pa po potrebi glede na število bytov, ki jih zasede spremenljivka, ki jo posamezen case napolni.
Je pa dobro, da se pred izhodom iz switch vedno izprazne sprejemni buffer, da ne bi po nesreči kaj notri ostalo, kar bi se ob naslednjem vstopu v switch obnašalo kot Velicina ali podatek, skupaj s še kakšnimi medtem prejetimi byti.
_________________ Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor |
|
Nazaj na vrh |
|
|
malci Član
Pridružen-a: Sob 15 Sep 2007 21:05 Prispevkov: 792 Aktiv.: 3.92 Kraj: Polhov Gradec
|
Objavljeno: Pon Dec 03, 2018 11:13 am Naslov sporočila: |
|
|
Pozdravljeni!
Sem včeraj malo nadaljeval...
V Switch-case je lahko Int ali Char. To je dejansko 255 možnosti z 1 Bytom - to je vredu.
Samo z logičnostjo je pa nekoliko težje (oz ne znam smiselno uporabiti #define).
Če sedaj pošljem "Imax200" s tem mislim da je dovoljen maximalni tok 200A.
Če pa pošljem npr. "A200" je pa isto, samo da moram imeti dodatno tabelo na papirju, kjer imam legendo ( da A pomeni Imax)
Bom tako naredil, da privarčujem nekaj spomina in pridobim na preglednosti.
Zaenkrat hvala vsem.
lp
Uroš
Koda: |
void uart1() {
String sprejem=Serial.readString();
char spr=sprejem.charAt(0);
}
switch (spr) {
case 98: //"a"
Serial.println("A B C test");
break;
case 97: //"b"
Serial.println("TEST XYZ");
break;
default:
//kar nekaj
break;
}
if (sprejem.indexOf("imax")>-1){ // če vsebuje niz imax
sprejem=sprejem.substring(sprejem.indexOf("imax")+4,sprejem.indexOf("imax")+7);
Imax=sprejem.toInt(); |
_________________ Elektronika za hobi |
|
Nazaj na vrh |
|
|
Jaka57 Moderator
Pridružen-a: Ned 12 Dec 2004 21:47 Prispevkov: 5773 Aktiv.: 25.91 Kraj: Grosuplje
|
Objavljeno: Tor Dec 04, 2018 10:15 pm Naslov sporočila: |
|
|
malci, saj ne rabiš uporabljat #define.
Ko sem napisal, da definiraš na začetku spremenljivke, sem mislil, da prirediš imenom veličin vrednost, npr:
char Imax='A';
char Izpis1="B";
in na oddajni strani enako, potem lahko še vedno vse delaš z Imax, Izpis1,itd. in ne rabiš vsakič gledat na papir.
in tako naprej in preko serijskega porta potem letijo 'A'<vrednost>, 'B'<vrednost>, itd.
in switch...case lahko potem izgleda takole:
Koda: |
switch sprejem.substring(1, n) {
case Imax:
//kar nekaj
break;
case Izpis1:
//kar nekaj
break;
.
.
.
case Umax:
//kar nekaj
break;
...
default:
//kar nekaj
break;
}
|
Toda, če ta ista imena veličin uporabljaš naprej v programu, boš moral definirati druga imena veličin, npr :
char Maximalni_tok='A';
char Prvi_izpis='B';
char Drugi_izpis='H';
itd.
in to samo zato, da je del programa switch...case preglednejši, vse ostalo, kar si sedaj napisal v programu pa lahko ostane enako,
saj bi pri uporabi 'A', 'B',....., dejansko moral gledati na papir.
S tem, da gre char spremenljivka od -128 do 127 (signed), byte pa od 0 do 255 (unsigned).
_________________ Lp, Jaka |
|
Nazaj na vrh |
|
|
malci Član
Pridružen-a: Sob 15 Sep 2007 21:05 Prispevkov: 792 Aktiv.: 3.92 Kraj: Polhov Gradec
|
Objavljeno: Sob Dec 08, 2018 10:18 pm Naslov sporočila: |
|
|
Citiram: |
Če pa pošljem npr. "A200" je pa isto, samo da moram imeti dodatno tabelo na papirju, kjer imam legendo ( da A pomeni Imax) |
To sem mislil v času testiranja, ko običajno delam še s terminalom.
Sem sedaj preuredil kodo na način kot je videti spodaj, in sem zadovoljen. Privarčeval 11% prostora ( iz 64 na 53%) pa tudi bolj pregledno je.
Hvala za za pomoč
lp
Koda: |
do{
int len=sprejem.length(); if (len<3) break;
byte ind=sprejem.indexOf(';',0);
String str1= sprejem.substring(0, ind);
sprejem=sprejem.substring(ind+1,len); // sprejem se zmanjša za niz do prvega podpičja
spr=str1.charAt(0); // iz str1 pridobi prvi znak
str1=str1.substring(1,str1.length()); // str1 je preostanek ( običajno vrednost)
switch (spr) {
case 97: //a
Imax=str1.toInt(); Serial.println (" Imax: " + String(Imax));
break;
case 98: //b
Umax=str1.toInt(); Serial.println (" Umax: " + String(Umax));
break;
case 99: //c
Utot=str1.toInt(); Serial.println (" Utot: " + String(Utot));
break;
case 100: //d
Ufull=str1.toInt(); Serial.println (" Ufull: " + String(Ufull));
break;
case 101: //e
Itot1=str1.toInt(); Serial.println (" Itot1: " + String(Itot1));
break;
case 102: //f
Itot2=str1.toInt(); Serial.println (" Itot2: " + String(Itot2));
break;
case 103: //g
Itot=str1.toInt(); Serial.println (" Itot: " + String(Itot));
break;
case 104: //h //izpis 1
izp1();
break;
case 105: //i //izpis 2
izp2();
break;
case 106: //j
mer=!mer; Serial.println("Meritve" + String(mer));
break;
case 107: //k
....
....
....
|
_________________ Elektronika za hobi |
|
Nazaj na vrh |
|
|
igo Član
Pridružen-a: Sre 11 Okt 2006 19:11 Prispevkov: 3638 Aktiv.: 17.05
|
Objavljeno: Ned Dec 09, 2018 1:11 am Naslov sporočila: |
|
|
Ali imaš znotraj loop(){...} zanke samo do{....} zanko ali do{....}while(...) zanko?
Če de najprej do{... , se bo tisto znotraj {...} najprej izvršilo, nato pa preverilo, ali se sme ponoviti.
Dostikrat je varneje najprej preveriti, ali se sme nekaj izvršiti:
setup()
{
...
nacin=1;
}
loop()
{
Zanka:
while(nacin==1){....}
while(nacin==2){....}
...
goto Zanka; // najhitrejši in najučinkovitejši način za kroženje zanke
}
Če pa je znotraj loop() samo do{...} zanka, jo vrzi ven, saj je loop() že sama po sebi zanka. S tistim goto Zanka pravtako prihraniš nekaj malega virov in časa.
_________________ Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor |
|
Nazaj na vrh |
|
|
malci Član
Pridružen-a: Sob 15 Sep 2007 21:05 Prispevkov: 792 Aktiv.: 3.92 Kraj: Polhov Gradec
|
Objavljeno: Ned Dec 09, 2018 10:33 am Naslov sporočila: |
|
|
ne, imam tudi while.
Se da še kak byte privarčevati. Sicer nisem v krizi s prostorom, a vseeno,
Koda: |
void loop(){
if (Serial.available()>0) { // če je na voljo niz, potem pojdi na void uart1
delay(50);
uart1();
}
.
.
.
}
void uart1() {
char spr;
String sprejem=Serial.readString(); // sprejem ima poljubno dolžino oblike a250;b6900,c145.....
Serial.print("Sprejel sem: ");
Serial.println(sprejem);
///// parsing /////
int ii=0; // to bi se verjetno dalo tudi izpustiti???
do{
int len=sprejem.length(); if (len<3) break; //Serial.println("dolzina=" + String(len));
byte ind=sprejem.indexOf(';',0);
String str1= sprejem.substring(0, ind);
sprejem=sprejem.substring(ind+1,len); // sprejem se zmanjša za niz do prvega podpičja
spr=str1.charAt(0); // iz str1 pridobi prvi znak
str1=str1.substring(1,str1.length()); // str1 je preostanek ( običajno vrednost)
switch (spr) {
case 97: //a
Imax=str1.toInt(); Serial.println (" Imax: " + String(Imax));
break;
case 98: //b
Umax=str1.toInt(); Serial.println (" Umax: " + String(Umax));
break;
case 99: //c
Utot=str1.toInt(); Serial.println (" Utot: " + String(Utot));
break;
case 100: //d
Ufull=str1.toInt(); Serial.println (" Ufull: " + String(Ufull));
break;
case 101: //e
...
...
...
case 41: //A
T2ref2=str1.toInt(); Serial.println ("T2ref2: " + String(T2ref2));
break;
default:
//kar nekaj
break;
}
} while (ii=1); // II nima nikoli vrednost 1 - vedno se zaključi v z break
}
|
_________________ Elektronika za hobi |
|
Nazaj na vrh |
|
|
vpeter Član
Pridružen-a: Pon 11 Jun 2012 16:05 Prispevkov: 337 Aktiv.: 2.34 Kraj: Maribor okolica
|
Objavljeno: Ned Dec 09, 2018 11:18 am Naslov sporočila: |
|
|
Namesto
lahko tudi napišeš
Je pa zgoraj Jaka57 napisal kako se znebiti črk, da je program preglednejši.
Posodobljeno:
Koda: |
const char Imax = 'a';
const char Izpis1 = 'b';
case Imax:
break; |
Nazadnje urejal/a vpeter Ned Dec 09, 2018 2:26 pm; skupaj popravljeno 2 krat |
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.21 Kraj: Črnomelj
|
Objavljeno: Ned Dec 09, 2018 12:47 pm Naslov sporočila: |
|
|
Super predlogi, vendar predlagam, da se prepričate kaj predlagate. Spremenljivka ne more biti del case stavka v C++, ker ni konstantna vrednost. Razen, če bo const ali constexpr.
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
Jaka57 Moderator
Pridružen-a: Ned 12 Dec 2004 21:47 Prispevkov: 5773 Aktiv.: 25.91 Kraj: Grosuplje
|
Objavljeno: Ned Dec 09, 2018 8:21 pm Naslov sporočila: |
|
|
tilz0R je napisal/a: |
Super predlogi, vendar predlagam, da se prepričate kaj predlagate. Spremenljivka ne more biti del case stavka v C++, ker ni konstantna vrednost. Razen, če bo const ali constexpr. |
Drži!
Opis: |
|
Velikost datoteke: |
74.26 KB |
Pogledana: |
11 krat |
|
_________________ Lp, Jaka |
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.21 Kraj: Črnomelj
|
Objavljeno: Ned Dec 09, 2018 8:25 pm Naslov sporočila: |
|
|
Vrži tvojo idejo v prevajalnik.
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 69 dni
Powered by phpBB © 2001, 2005 phpBB Group
|