Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  Arduino koodi bug (jookseb kokku) märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale. Teata moderaatorile
otsing:  
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 27.10.2020 09:11:59 Arduino koodi bug (jookseb kokku) vasta tsitaadiga

Keskkütte juhtimiseks on tehtud automaatika mis lülitab 2'te pumpa vastavalt temperatuuridele.
Eile üritasin sinna MQTT funktsionaalsuse lisada, kuid asi lõppes sellega, et asi jookseb kokku, kui saata üle MQTT käsklus "ON" (Kui koodis oli ees check: if(radikaC > 39){ siis ta mingil põhjusel sinna IF sisse ka ei jõudnud MQTT callbackis. Kui see ära võtta jooksis kokku).
Samas üle ühe veebiliidese juhtimine funktsioonis int MobileSwitch(String command) töötab juba aastaid.
Ehk kellelgi hakkab silma mille vastu olen eksinud.

Kogu kood:
Spoiler Spoiler Spoiler


MQTT callback funktsioon:

float callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    Serial.println("callback...");
   
    if (!strcmp(p, "ON")){
        if(radikaC > 39){
            previousNow2 = Time.now();   
            ForceState = 1;
        }
    }       
   
           
    if (!strcmp(p, "OFF")){
        previousNow2 = Time.now();   
        ForceState = -1;
    }
    if (!strcmp(p, "AUTO")){
        ForceState = 0;
    }

}



Pumpa juhib järgmine funktsioon mis kasutab ForceState väärtust:

int tempkontroll(float radikaC, float toaC, int c, int aeg, float pliidiveeC) {   
   
    aeg =Time.hour()*60+Time.minute();

    if((toaC < 20.7 && radikaC > 39 && c == 0  && aeg < 1290 && aeg > 360 && ForceState == 0) || (ForceState == 1)) {
            c = 1;
            digitalWrite(relayRadiator, HIGH); //paneb relee "HIGH" asendisse
       
    }
   
    else if((((toaC > 21.4 || radikaC < 37) && c == 1 && radikaC < 88 && ForceState == 0) || (aeg > 1290  && radikaC < 88 && ForceState == 0)) || (ForceState == -1 && radikaC < 88) )  {
        c = 0;
        digitalWrite(relayRadiator, LOW); //paneb relee "LOW" asendisse
    }
    return c;
    }

_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
andre85
HV vaatleja

liitunud: 10.09.2006




sõnum 27.10.2020 10:36:38 vasta tsitaadiga

Sinu probleem on siin:

char p[length + 1];

See eraldab mälu magasinis ja seal ta kokku jookseb...

võiks olla midagi sellist, et eraldad mälu mujalt kui magasinist või on juba valmis eraldatud (vt Supliplexi vastust sulle teises teemas)

_________________
andres
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 27.10.2020 11:03:28 vasta tsitaadiga

See char p[length + 1]; on ka MQTT enda library näites sees, ei saa aru kuidas see võiks asja kokku jooksutada.
p ju nullitakse kogu aeg ära ka ( p[length] = NULL; ) ning mujal ta töötab.

Library näitekood:

void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;

    if (!strcmp(p, "RED"))
        RGB.color(255, 0, 0);
    else if (!strcmp(p, "GREEN"))
        RGB.color(0, 255, 0);
    else if (!strcmp(p, "BLUE"))
        RGB.color(0, 0, 255);
    else
        RGB.color(255, 255, 255);
    delay(1000);
}

_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
Supiplex
HV veteran
Supiplex

liitunud: 11.12.2002




sõnum 27.10.2020 15:45:07 vasta tsitaadiga

Kui sul on funktsiooni signatuur mis lubab tagastada floati ja sa seda funktsioonis tegelikult ei tee, siis võib juhtuda igasugu huvitavaid asju.
float callback(char* topic, byte* payload, unsigned int length)


Rohkem norimise poolest - char array sisse ei tasu nullpointerit kirjutada. Ikka null-char '\0' või - mis veel lihtsam - 0.
p[length] = NULL;

_________________
The young lady had an unusual list,
Linked in part to a structural weakness.
She set no preconditions.
Kommentaarid: 38 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum
napoleon
Unknown virus
napoleon

liitunud: 08.12.2008



Autoriseeritud ID-kaardiga

sõnum 27.10.2020 16:52:07 vasta tsitaadiga

Supiplex kirjutas:

Rohkem norimise poolest - char array sisse ei tasu nullpointerit kirjutada. Ikka null-char '\0' või - mis veel lihtsam - 0.
p[length] = NULL;


Pole see miskit norimine.
if (!strcmp(p, "ON")){
peale juhtub ka igasuguseid huvitavaid asju kui konkreetses vahendis NULL != 0.
Kommentaarid: 76 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 59
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 27.10.2020 18:55:52 vasta tsitaadiga

Kodeerimises olen ma võhik ning ei ole esimene kord kui ma millegist vaalesti aru olen saanud aga kirjutaksin lahti, kuidas mina seda lugesin:

char p[length + 1]; // char muutujale "p" määratakse tähemärkide pikkus mis saadakse funktsiooni callbacki tulevast infost. St antakse talle pikkus.
memcpy(p, payload, length); //memcpy( kuhu kohta kopeeritakse, kust kohast kopeeritakse, kui pikalt) ehk siis "p" väärtuseks kopeeritakse MQTT sissetuleva sõnumi väärtus ning selle pikkus on "length" määratud.
p[length] = NULL; // algul vaatasin, et "p" muutuja väärtus kirjtuatakse nulliks, või et ta pikkuseks kirjutatakse 0 mis oleks imo efektiivselt null väärtus. Kuid see ei saa siiski nii olla, kuna hiljem ju võrreldakse "p" "ON" jne väärtustega.

Seega kas "p" väärtuse lõppu lisatakse null? Mis see annaks?
Niipalju ma ühel hetkel päeval lugesin, et C++'s NULL != "0" 'ga jah.
Lähtunud olen ma muidugi sellest, et kui inimene on library valmis kirjutanud, siis ametlikus näites ei tohiks ta põhitõdede vastu eksida icon_smile.gif

Aga mis konkreetsed soovitused siis oleks?

p[length] = 0; // ???

_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
napoleon
Unknown virus
napoleon

liitunud: 08.12.2008



Autoriseeritud ID-kaardiga

sõnum 27.10.2020 19:29:20 vasta tsitaadiga

p[length] = 0;
oleks korrektne jah. Aga 100% kindel pole, et see probleemi lahendab.
Kommentaarid: 76 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 59
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 27.10.2020 19:34:57 vasta tsitaadiga

Katsetasin veits ning hetkel tundub, et toimib (vähemasti siiani pole pange pannud).
Mis aitas oli "delay" lisamine.


float callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = 0;
    Serial.println("callback...");
       
    if (!strcmp(p, "ON")){
        if(radikaC > 39){
            previousNow2 = Time.now();   
            ForceState = 1;
        }
    }   
    if (!strcmp(p, "OFF")){
        previousNow2 = Time.now();   
        ForceState = -1;
    }
    if (!strcmp(p, "AUTO")){
        ForceState = 0;
    }
    Alarm.delay(900);
}


Alarm.delay on ühe library funkts mida kasutan. Kas sellest võiks järeldada, et kuskil tekkis mingi lõputu "loop" mis asja kooma tõmbas?

_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
napoleon
Unknown virus
napoleon

liitunud: 08.12.2008



Autoriseeritud ID-kaardiga

sõnum 27.10.2020 19:42:12 vasta tsitaadiga

See tähendab, et midagi kuskil tehakse asünkroonselt. Aga siinkohal tõstan käed üles. C/C++ on mulle tuttav teema, aga konkreetrselt Arduino-ga pole kokku puutunud.
Kommentaarid: 76 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 59
tagasi üles
vaata kasutaja infot saada privaatsõnum
Supiplex
HV veteran
Supiplex

liitunud: 11.12.2002




sõnum 27.10.2020 19:50:48 vasta tsitaadiga

Terror kirjutas:
Seega kas "p" väärtuse lõppu lisatakse null? Mis see annaks?


C-s on kasutusel zero-terminated string. Bait väärtusega 0 tähistab stringi lõppu. Näiteks string "ON" peab koosnema kolmest baidist väärtustega 'O', 'N' ja 0.

Utiliidid nagu strcmp() otsivad seda 0-i ja kui ei leia, siis ketravad kasvõi terve mälu läbi. Noh, tavaliselt jääb mõni asjasse mittepuutuv 0 varem ette icon_smile.gif

tsitaat:
Alarm.delay on ühe library funkts mida kasutan. Kas sellest võiks järeldada, et kuskil tekkis mingi lõputu "loop" mis asja kooma tõmbas?


Veelkord. Su funktsioon "callback" peab tagastama float väärtuse, sest nii sa oled kompilaatorile lubanud. Palun tee seda - kasvõi "return 0.0;" - või korja see float sealt signatuuri algusest ära.

_________________
The young lady had an unusual list,
Linked in part to a structural weakness.
She set no preconditions.
Kommentaarid: 38 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum
NATAS999
HV Guru

liitunud: 02.04.2007




sõnum 28.10.2020 08:52:20 vasta tsitaadiga

Supiplex, kas long int peab kindlasti tagastama väärtuse kujul +0000000001?
Kommentaarid: 41 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 39
tagasi üles
vaata kasutaja infot saada privaatsõnum
mikk36
HV Guru
mikk36

liitunud: 21.02.2004




sõnum 28.10.2020 11:11:48 vasta tsitaadiga

NATAS999, võid ka 1L tagastada.
Aga antud hetkel oleks õige muuta funktsiooni signatuuris tagastatavaks tüübiks void, kuna ühtegi väärtust/pointerit ei tagastata.
Kommentaarid: 85 loe/lisa Kasutajad arvavad:  :: 0 :: 2 :: 78
tagasi üles
vaata kasutaja infot saada privaatsõnum
Supiplex
HV veteran
Supiplex

liitunud: 11.12.2002




sõnum 28.10.2020 12:22:41 vasta tsitaadiga

NATAS999 kirjutas:
Supiplex, kas long int peab kindlasti tagastama väärtuse kujul +0000000001?


Ehh? Ei. Funktsioon võib teoorias tagastada ükskõik mis tüüpi väärtuse, seni kui kompilaator on nõus selle tagastatavasse tüüpi ümber teisendama.

Lihtsalt oma koodi lugeja vaimset tervist tuleb hoida, tal seda tihtipeale niigi vähe alles icon_wink.gif Selleks on mikk36 nõu hea.

_________________
The young lady had an unusual list,
Linked in part to a structural weakness.
She set no preconditions.
Kommentaarid: 38 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum
NATAS999
HV Guru

liitunud: 02.04.2007




sõnum 28.10.2020 13:03:54 vasta tsitaadiga

mõtlesin üldisemalt seda asja. kui mul on funktsioon, mis peab mingil põhjusel vahest tagastama ujukoma väärtuse, siis mõningal juhul vastavalt sisendile võib ju tagastada ka lihtsalt 0, mitte ei pea tingimata 0.0 olema?

puht sportlikust huvist viskan sõna sekka. omale vahest kirjutan c++'ga tööriistu ja return väärtustega pole probleeme olnud. pigem aritmeetika, grammatika ja loogika vead.
Kommentaarid: 41 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 39
tagasi üles
vaata kasutaja infot saada privaatsõnum
Supiplex
HV veteran
Supiplex

liitunud: 11.12.2002




sõnum 28.10.2020 15:57:41 vasta tsitaadiga

NATAS999 kirjutas:
mõtlesin üldisemalt seda asja. kui mul on funktsioon, mis peab mingil põhjusel vahest tagastama ujukoma väärtuse, siis mõningal juhul vastavalt sisendile võib ju tagastada ka lihtsalt 0, mitte ei pea tingimata 0.0 olema?


Jah, C ning C++ keeled lubavad seda ja käänavad tüübi õigeks. https://www.oreilly.com/library/view/c-in-a/0596006977/ch04.html#cinanut-CHP-4-SECT-1.4

_________________
The young lady had an unusual list,
Linked in part to a structural weakness.
She set no preconditions.
Kommentaarid: 38 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum
napoleon
Unknown virus
napoleon

liitunud: 08.12.2008



Autoriseeritud ID-kaardiga

sõnum 28.10.2020 16:02:10 vasta tsitaadiga

Enamik keeli suudab tüübi õigeks keerata kui tüübid on teisaldatavad, hetkel ei meenugi ühtegi keelt mis selle osas väga pirtsakas oleks.
C/C++ puhul peab ainult sellega ettevaatlik olema, et see lubab ka endale jalga tulistada ning paremal juhul annab kompilaator hoiatuse, aga alati mitte ka seda.
Kommentaarid: 76 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 59
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 29.10.2020 00:27:42 vasta tsitaadiga

Lihtsalt infoks, et Arduino puhul reaalselt NULL teisendub ikkagi 0'ks, kuigi kompilaator annab hoiatuse:
warning: converting to non-pointer type 'char' from NULL

Aga mulle tundub, et Supiplex'i välja pointitud probleem, et "float" funktsoonil ei ole return'i, võib vabalt antud kokkujooksmise põhjus olla.
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
mikk36
HV Guru
mikk36

liitunud: 21.02.2004




sõnum 29.10.2020 08:20:51 vasta tsitaadiga

Lihtsaim oleks lihtsalt float -> void teha, kuna pole ju kavas tagastada midagi.
Kommentaarid: 85 loe/lisa Kasutajad arvavad:  :: 0 :: 2 :: 78
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 29.10.2020 09:42:03 vasta tsitaadiga

Voidiga ma ei saanud seal callbacki sees globaalset muutujat kasutada.
_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 29.10.2020 10:02:03 vasta tsitaadiga

Terror kirjutas:
Voidiga ma ei saanud seal callbacki sees globaalset muutujat kasutada.

See tundub väga ebaloogiline.

Kas saaksid näidata, milline "mqtt.h" välja näeb?
Siis näeb, et millist callbacki "MQTT client(server, 1883, callback);" täpselt ootab.
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 29.10.2020 10:42:40 vasta tsitaadiga

Originaal library on see: https://github.com/hirotakaster/MQTT
_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
NATAS999
HV Guru

liitunud: 02.04.2007




sõnum 29.10.2020 11:20:09 vasta tsitaadiga

konsoolis ei kannata sellist asja jooksutada ja anduritest saadavad väärtused käsitsi hoopis ette sööta, kas siis hard coded või konsooli sisestades ja siis kuskile koodi kirjutada mingid punktid cout ja mõne muutuja väärtus, mida kahtlustad, et võib pange panna. mul muidugi jooksis esimeses postis spoileris oleva kogu koodi peale kuulid kokku, aga ega ei süvenend ka enam peale esimest 20 rida icon_lol.gif
Kommentaarid: 41 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 39
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 29.10.2020 13:22:11 vasta tsitaadiga

Terror kirjutas:
Originaal library on see: https://github.com/hirotakaster/MQTT


Callback peaks ikkagi "void" olema, kuna library ootab void'i.


Mulle tundub praegu ohtlik see "byte" siin

byte server[] = { 192,168,1,223 };
MQTT client(server, 1883, callback);


MQTT libraries on kaks definitsiooni:
MQTT(char* domain, uint16_t port, void (*callback)(char*,uint8_t*,unsigned int));
ja
MQTT(uint8_t *ip, uint16_t port, void (*callback)(char*,uint8_t*,unsigned int));

Kuna "byte" on mingi Arduino platformi jaoks defineeritud tüüp, siis nüüd ei teagi, kummaks ta lahendub, kas "char* domain" või "uint8_t *ip", kuna char ja uint8_t on Arduinol põhimõtteliselt samad.
Esimene eeldab null terminated stringi ja teine nelja kohalist array'd

Äkki oleks kindlam, kui teeksid
uint8_t server[] = { 192,168,1,223 };
MQTT client(server, 1883, callback);

või võid proovda ka
char * server = "192.168.1.223";
MQTT client(server, 1883, callback);


Ja callback loomulikult
void callback(char* topic, byte* payload, unsigned int length);
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 29.10.2020 13:47:08 vasta tsitaadiga

Library oma muutmata kujul ei toiminud (void Callback..)

I trying to declare callbackstring as global, use it in the callback function and then display it in loop() but that didn't work. Displaying the value of callbackString inside the callback worked.
https://forum.arduino.cc/index.php?topic=400044.0

Sealt maalt lugema hakata. Ma sain vähemalt aru, et ei saa sealt callbacki seest infot kätte teise funktsiooni, kui üritasin seda library't muutmata kujul kasutada.

_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 29.10.2020 20:07:26 vasta tsitaadiga

Terror kirjutas:

I trying to declare callbackstring as global, use it in the callback function and then display it in loop() but that didn't work. Displaying the value of callbackString inside the callback worked.
https://forum.arduino.cc/index.php?topic=400044.0

Sealt maalt lugema hakata. Ma sain vähemalt aru, et ei saa sealt callbacki seest infot kätte teise funktsiooni, kui üritasin seda library't muutmata kujul kasutada.


Sellisel kujul nagu ta üritab teha seal foorumi postitusel ei saagi töötada.

"char callbackString;" on lihtsalt ühe baidine globaalne muutuja.

Ja nüüd callbacki sees ta skoobi mõttes varjutab selle lihtsalt ära tehes uue funktsooni sisese koahliku muutuja:
char *callbackString = (char *) payload; // see loob uue muutuja "*callbackString", mis ei ole kuidagi seotud globaalse muutujaga "callbackString"
callbackString[length] = '\0'; // siin väärtustab kohalikku muutjat "*callbackString"

Ehk siis tegelikult ta isegi ei anna midagi callbackist välja.



EDIT:
Kontrollisin. byte läheb ikkagi uint8_t'ks. Ehk siis selles osas probleemi ei ole

See kood väljastas teksti "uint8_t":
byte bytes [] = {1, 2, 3, 4};

void aa(char * a) {
  Serial.println("char");
}

void aa(uint8_t * a) {
  Serial.println("uint8_t");
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  aa(bytes);
}

void loop() {
  // put your main code here, to run repeatedly:
}
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  Arduino koodi bug (jookseb kokku)
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.