Sida 2 av 3
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 20:10:54
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
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 20:12:14
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 20:28:00
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?
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 20:44:40
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 20:48:21
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 21:01:55
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 21:06:13
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 21:06:32
av Jan Almqvist
Ingen Serial.available() kan känna till något om de tecken som ännu inte kommit fram.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 21:29:48
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 21:41:20
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
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 21:48:02
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 21:54:20
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);
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 23:24:22
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 27 november 2014, 23:41:32
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.
Re: Konstigt värde när jag skickar från uC till PC
Postat: 28 november 2014, 04:37:43
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.