Konstigt värde när jag skickar från uC till PC

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av johano »

Den där string_to_float(), är det en egen funktion eller något standard i Arduino?
Hur funkar din kod om du inte läser en korrekt sträng?
Ponera att du bara lyckas läsa "344" och sen inget mer...

/johan
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Al_Bundy »

Det är en funktion som har arduino-standard funktioner så som att omvandla string => array => float.

Hur min kod fungerar om jag inte läser av korrekt sträng? Jadu. Det blir fel värde då i variabeln.
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Icecap »

Al. din förklaring haltar ganska allvarligt. Som jag läser det är det när PC'n svarar tillbaka med de avlästa värden som det kommer "47".

En stor fråga är: har du/ni sniffat kommunikationen?

Själv har jag ett par DB9 hane och hona kopplat ihop och sedan ytterligare ett par DB9 kopplat till som ledar av Rx hhv TX till RX på var sin DB9 Rx. Därmed kan jag starta två terminalprogram på var sin seriella port och se vad som skickas och vad som tas emot.

På detta vis är det rimligt enkelt att avgöra var felet kommer.

Om ni kör med intern oscillator i µC'n finns det en risk att hastighetsfel finns som kan ge fel lite då och då, är t.ex. hastighetstrimningsregistret ändrat av någon anledning kan det ge en massa otrevligheter i den väg.

Det känns som att du/ni inte ha en aning om vad som händer men utgår ifrån att något borde hända men att det är helt och totalt overifierat. Och som man säger "att mäta är att veta!"

Och ja, det är helt sant att jag är extremt skeptisk till din programmering! Jag anser att du är µC-världens svar på Don Martin och att dina ambitioner är så långt ifrån din kapacitet att det är någonstans mellan skrattretande och skrämmande.

MEN - på sista tiden har du faktisk haft något så när substans i dina frågor. Du kan dock fortfarande inte ta emot och använda råd, detta antar jag är pga. din personlighet.

Du brukar svara i stil med "goddag - yxskaft" på frågor, du påstår saker som inte hänger ihop med fakta och när det blir påpekat att det finns stor chans för programmeringsfel är dit svar att ta det som personangrepp.

Väx upp! Påstår du dig vara bra i din programmering ser jag det som Dunning-Kruger effekten.

Just det: hela printout-delen avslutas med "serial.flush()" - Varför?
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Al_Bundy »

>> har du/ni sniffat kommunikationen?

Nej.

>> Om ni kör med intern oscillator i µC'n finns det en risk att hastighetsfel finns som kan ge fel lite då och då, är t.ex. hastighetstrimningsregistret ändrat av någon anledning kan det ge en massa otrevligheter i den väg.

Sådan tankar har vi också.

>> Väx upp! Påstår du dig vara bra i din programmering ser jag det som Dunning-Kruger effekten.

1. Jag har aldrig sagt att jag är bra i programmering.
2. Med din bessweisserstil så bevisar du klartecken att du är mentalt yngre än vad jag är. Vem tror du dig är egentligen? Sitt där och skriv att jag ska växa upp och sedan räcker du ut massa skit. Du beter dig precis som någon fullvuxen som inte har sett sig själv än trots hög ålder. Att se sig själv brukar komma vid 20 års åldern.

Men åter igen.
Vi vet inte vad det är för fel, varför den beter sig så. Vi har inte heller så mycket tid att åtgärda felet. Det enda vi har gjort är att vi kan manuellt bekräfta om den har gjort rätt. Om jag får ett värde som jag inte vill ha, då kör jag proceduren igen tills jag får rätt värde. Oftast behövs det bara en extra avläsning och sedan är det klart. Jag skrev bara denna tråd för att få veta om det finns något känt när detta händer. Jag skrev inte denna tråd för att jag behöver hjälp med problemet för i inlägg #1 så står det redan att det är löst. Jag är bara ute efter kunskapen av intressets skull. Du vet...intresset, det ni säger att jag inte har. Men som du skriver så har du, som jag har, teorier, funderingar, gissningar och framtida lösningar på felmeddelandet.
Användarvisningsbild
Jan Almqvist
Inlägg: 1655
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Jan Almqvist »

Man ser enkelt att inläsningen inte kan fungera.

Kod: Markera allt


if(Serial.available() > 0)
          {
            text = Serial.readString();

Att Serial.available() returnerar ett tal större än noll betyder att det finns tecken. Inte att alla tecken kommit fram.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Al_Bundy »

Arduino's Serial.available() läser exakt allt som ligger i bufferten och sedan går den vidare. Den läser inte första tecknet och sedan fortsätter den.
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Icecap »

Får definitivt hålla med Jan Almqvist här.

Själv skulle jag aldrig köra pollad utan i mycket speciella fall, jag har i 99% av projekten en interruptstyrning av mottagningen, just för att säkerställa att mottagningen fungerar bra.

Det är såklart en del mer jobb med det, man ska avsätta buffer osv men slutresultatet är att man kan fånga varje byte som överförs.

Sedan kan man argumentera att dessa serial.xxx rutiner är osäkra att använda, men jag tror att de i grunden kan fungera OK om man använder dom rätt.

Exakt vad avgör att t.ex. Serial.ReadString() är klar? Är det '\r' och/eller '\n' som terminerar? Och om dessa är störda, vad händer då?

"Arduino's Serial.available() läser exakt allt som ligger i bufferten och sedan går den vidare. Den läser inte första tecknet och sedan fortsätter den."
Hur stor är bufferten då?

"available" betyder ju bara att det finns minst ett tecken, inte att det finns ett antal tecken.
Senast redigerad av Icecap 27 november 2014, 21:07:05, redigerad totalt 1 gång.
Användarvisningsbild
Jan Almqvist
Inlägg: 1655
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Jan Almqvist »

Ingen Serial.available() kan känna till något om de tecken som ännu inte kommit fram.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Al_Bundy »

Icecap skrev:Får definitivt hålla med Jan Almqvist här.

Själv skulle jag aldrig köra pollad utan i mycket speciella fall, jag har i 99% av projekten en interruptstyrning av mottagningen, just för att säkerställa att mottagningen fungerar bra.

Det är såklart en del mer jobb med det, man ska avsätta buffer osv men slutresultatet är att man kan fånga varje byte som överförs.

Sedan kan man argumentera att dessa serial.xxx rutiner är osäkra att använda, men jag tror att de i grunden kan fungera OK om man använder dom rätt.

Exakt vad avgör att t.ex. Serial.ReadString() är klar? Är det '\r' och/eller '\n' som terminerar? Och om dessa är störda, vad händer då?

"Arduino's Serial.available() läser exakt allt som ligger i bufferten och sedan går den vidare. Den läser inte första tecknet och sedan fortsätter den."
Hur stor är bufferten då?

"available" betyder ju bara att det finns minst ett tecken, inte att det finns ett antal tecken.
Jag hade annars använt Serial.write() vilket ger ASCII-kod. Men hela vår grupp kan inte hantera just ASCII.

Serial.ReadString() terminierar vid \n.
Om dessa är störda? Hmm...jadu, bra fråga. Menar du att \n inte kommer finnas?
Om det inte finns \n så blir det fel värde i variabeln.

Enligt databladet kan bufferten ha 3 tecken, enligt vår lärare.
Användarvisningsbild
Jan Almqvist
Inlägg: 1655
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Jan Almqvist »

Jag skulle tro att Serial.ReadString() returnerar de tecken som kommit fram.

Inte att den väntar på något \n.

http://arduino.cc/en/Reference/StreamReadString
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Al_Bundy »

Men ett tecken (sträng) slutar med \n :)

Vi får inte glömma att jag konverterar från string to float. Det är en jobbig process och jag har hört från okunnigt folk att float är något man ska undvika. Jag kallar dessa okunniga. Om de har rätt eller inte, vet jag inte.
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Icecap »

Låt ponera att det har kommit 6 tecken innan det kollas om Serial.Available() är sann. Är bufferten 3 platser måste det betyda att (minst) 3 tecken har försvunnit.

Sluteffekten är att om ni inte kan garantera att Serial.Available() kollas med minst samma takt som buffern kan fyllas på kommer det att försvinna tecken! Sedan är jag tveksam till att det är 3 tecken!

Rent faktisk är det så att de flesta µC har ett register med "senast mottagna byte", det är ett steg.
Sedan kan det vara en byte på ingång, det är ytterligare ett steg.
Det finns ofta en flagga som indikerar att det finns en komplett byte att hämta och jag känner mig skapligt säker på att detta är vad Serial.Available() kollar.

Slutresultatet blir att Serial.Available() måste kollas i minst samma hastighet som byten kan tas emot, kör ni 9k6n81 blir det alltså minst 960 gg/sekund.

Men om ni istället skapar ett vettigt protokoll kan detta lösas ganska enkelt!

Säg att de olika värden överförs på samma sätt, komma mellan osv. Om ni då lägger till ett slutvärde som innehåller alla sända bytes - fram till checksumman - adderat ihop - men trunkerat till byte-storlek (alltså addera i en byte o skita i alla bits som går "över" byten) kan meddelanden verifieras vid att räkna baklänges och sedan se om man får samma resultat.

Jag gör just så, då med en 16-bit checksum och hexadecimala tecken. När checksumman är dekodad subtraherar jag alla värden steg för steg, skiter i alla overflow men när alt är klart ska Checksum vara noll. Och som det är just nu fungerar det bra.

Detta skulle betyder att nu INTE behöver skicka tillbaka värden men bara kan kolla om meddelandet "hänger ihop". Svar kan vara en ACK för "tack, det är OK" eller NACK för "Hoppla, sänd om igen". En annan byte kan vara "Sänd ny omgång värden, tack" vilket plötsligt minskar kommunikationen till Arduinon till 1-bytes kommandon som lätt ligger i buffern fram till de kollas med Serial.Available().

Så min dom kvarstår: orsaken till problemet är dåligt protokoll kombinerat med dålig programmering. Jag är starkt tveksam till att det är hårdvarafel som orsakar problemen.

Men detta tar du ju sannolikt som påhopp och skiter i råden - så jag skriver det mest för att andra kan lära sig.

EDIT: Att omvandla till/från float är mycket krävande och det är rent faktisk mycket sällan att man behöver float i µC! Vill man ha decimaler vid t.ex. temperatur (xx,x°C istället för xx°C) kan man helt enkelt räkna alla värden i heltal med bas på 0,1°C. 10,2°C blir alltså internt ett heltal på 102 och detta är enkelt och snabbt att räkna med i en µC.

Men man vill ju gärna läsa dom rätt och det är enkelt också! Under utskrivning är det bara att skriva ut värdet delad med 10, en komma och sedan resten av en division med 10 (modulo 10). I C brukar jag skriva sprintf(Buffer, "%u,%u°C", Temperatur / 10, Temperatur % 10);
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av jesse »

Al_Bundy skrev:Men ett tecken (sträng) slutar med \n :)

Vi får inte glömma att jag konverterar från string to float. Det är en jobbig process och jag har hört från okunnigt folk att float är något man ska undvika. Jag kallar dessa okunniga. Om de har rätt eller inte, vet jag inte.
Gör två program med lite beräkningar som gör samma sak - multiplikationer, divisioner mm... det ena med heltal, det andra med float. Kolla hur mycket minne programmen tar upp, hur lång tid det tar att köra programmet. Sen är det upp till dig om du vill använda float eller inte. Då har du skaffat dig kunskap om varför man ibland vill undvika float. Okunnig är man när man inte vet varför.

Jag använder mer än gärna float i en PC, men undviker det så mycket det går i en enklare microcontroller.
Float har fördelen att det sällan blir overflow - ett problem som ofta uppstår med heltalsvariabler (dvs. något man måste ta hänsyn till vid programmeringen). Heltal har å andra sidan fördelen att du alltid vet hur noggrant talet representeras. Du tappar aldrig sista siffran. Flyttal (float) kan ge varierande trunkeringsfel som förstör resultatet, och som man också måste ta hänsyn till vid programmering - detta kan dock vara lite lurigt att beräkna ibland.
hummel
Inlägg: 2544
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av hummel »

Några kommentarer:

Serial.available
Returnerar antalet bytes i buffern. Dvs den har ingen aning om hur många tecken som ska läsas in.
Så länge det finns olästa tecken så ska du hämta dessa och lägga i din egen buffert.
När rätt anta tecken lästs in så ska du hantera din sträng.
Upptäcks att strängen är korrupt så kasta bort strängen och börja om och vänta på nästa tecken.
Se till att använda en checksumma.
Mr Andersson
Inlägg: 1409
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Konstigt värde när jag skickar från uC till PC

Inlägg av Mr Andersson »

Al_Bundy skrev:Jag hade annars använt Serial.write() vilket ger ASCII-kod. Men hela vår grupp kan inte hantera just ASCII.
Strängar är ju ASCII. Menade du något annat dataformat men skrev fel?
Serial.ReadString() terminierar vid \n.
Om de inte ändrat readString sen sist jag testade (någon månad sen) så terminerar den inte alls. Den väntar tills timeout uppnåtts (default 1000ms om jag minns rätt) och slänger sen in allt dittills mottaget i en sträng. Du har ingen garanti att strängen slutar på \n, eller att du ens får hela skickade strängen, och om din kod behöver \n så kommer du att få problem förr eller senare pga tappade tecken.
readString fungerar väl i nödfall, men jag gillar inte blockerande i/o. Finns bättre sätt att lösa det på.

Jag instämmer med tidigare inlägg som föreslagit någon form av checksumma alt. felkorrigering.
Skriv svar