Python /Arduino/Raspberry Pi

Her postes alt, som ikke direkte har noget med Ubuntu at gøre.
hni
Indlæg: 73
Tilmeldt: 6. nov 2008, 18:28

Python /Arduino/Raspberry Pi

Indlæg af hni »

Hej Alle!

Jeg sidder her og leger med data opsamling fra mit drivhus.

Lige nu opsamler jeg data på et SD kort (CSV fil), det virker fint.
Jeg vil dog bruge en Raspberry Pi til opsamlingen, så jeg lægge dem på en lokal hjemmeside.
Så Python (2.7) er der kommet gang i (c:
Jeg sidder med en Arduino der er forbundet med min Raspberry Pi via et USB kabel.

Den skriver lige så fint temperaturen på skærmen.
21
21
22
ovs.

Jeg er dog rent ind i et lille problem.

Python progam:

Kode: Vælg alt

#!/usr/bin/python
import serial
import csv
import sys

baudrate = 9600
indgang = '/dev/ttyACM0'
sted = '/home/pi/Drivhus/data.csv'

ser = serial.Serial(indgang,baudrate)

while 1:
    data = int(ser.readline())
    with open(sted,'a') as fp:
        a = csv.writer(fp, delimiter=',')
       
        a.writerows(str(data))
        print data
        fp.close()


Når jeg så kigger i CSV filen, så stå der:
2
1
2
1
2
2
osv.

Er der nogen der er en haj til Python der kan se hvor jeg nos... i det?????
lath
Indlæg: 5095
Tilmeldt: 27. apr 2008, 02:16
IRC nickname: lars_t_h
Geografisk sted: Fyn

Re: Python /Arduino/Raspberry Pi

Indlæg af lath »

hni skrev:Hej Alle!

Jeg sidder her og leger med data opsamling fra mit drivhus.

Lige nu opsamler jeg data på et SD kort (CSV fil), det virker fint.
Jeg vil dog bruge en Raspberry Pi til opsamlingen, så jeg lægge dem på en lokal hjemmeside.
Så Python (2.7) er der kommet gang i (c:
Jeg sidder med en Arduino der er forbundet med min Raspberry Pi via et USB kabel.

Den skriver lige så fint temperaturen på skærmen.
21
21
22
ovs.

Jeg er dog rent ind i et lille problem.

Python progam:

Kode: Vælg alt

#!/usr/bin/python
import serial
import csv
import sys

baudrate = 9600
indgang = '/dev/ttyACM0'
sted = '/home/pi/Drivhus/data.csv'

ser = serial.Serial(indgang,baudrate)

while 1:
    data = int(ser.readline())
    with open(sted,'a') as fp:
        a = csv.writer(fp, delimiter=',')
       
        a.writerows(str(data))
        print data
        fp.close()


Når jeg så kigger i CSV filen, så stå der:
2
1
2
1
2
2
osv.

Er der nogen der er en haj til Python der kan se hvor jeg nos... i det?????


Mit bud er at der opstår problemer fordi du ikke bruger den rigtige iterable.
Fra https://docs.python.org/2/library/csv.html#writer-objects har vi:
Writer objects (DictWriter instances and objects returned by the writer() function) have the following public methods. A row must be a sequence of strings or numbers for Writer objects and a dictionary mapping fieldnames to strings or numbers (by passing them through str() first) for DictWriter objects. Note that complex numbers are written out surrounded by parens. This may cause some problems for other programs which read CSV files (assuming they support complex numbers at all).


str(data) er godt nok en iterable, men ikke lige på den måde som du tror:
Din str(data), hvor data er f.eks. 21 bliver opfattet som en liste der har længden 2: ['2', '1'].
Hvis du skal have 21 til at være i sin egen liste, så skal du rigtig nok starte med at lave 21 om til en str, men den str skal også puttes ind i en liste, og det er det objekt du skal give til csv.writer.

Kode: Vælg alt

list(str(data))

...skulle være den rigtige Pytohn kode - det er lidt længe siden jeg har kodet i Python.

Derudover:
Eftersom du skriver kun et tal per linie, så kan du simplficere scriptet ved at undgå at bruge csv modulet.
Du skriver så i stedet direkte til en tekst fil (Linux er ligeglad med filendelser). Når du bruger with open, så lukkes din fil, når with går ud af scope.

Den sidste ting du skal huske når du skriver til filer er at huske at køre flush, der sikrer at de data du har skrevet bliver flushed ud af en evt disk buffer og ned i filsystemet.


Hot tip: med idle-python2.7 pakken får du en interaktiv python fortolker, hvor du nemmere kan se hvad der foregår.

/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
AJenbo
Admin
Indlæg: 20878
Tilmeldt: 15. nov 2009, 15:04
IRC nickname: AJenbo
Geografisk sted: Vanløse, København

Re: Python /Arduino/Raspberry Pi

Indlæg af AJenbo »

Du mangler også noget til at afbryde dit while loop så den ikke forsætter i en udenelig hed. Jeg er enig med Larth i at det bedste at gøre er at åbne filen, erstate linje skift med <br> og så spytte den ud på din hjemme side. Du kunne måske en dog springe python helt over ved blot at pege webserveren hen på csv filen og få den vist som teste i browseren.
lath
Indlæg: 5095
Tilmeldt: 27. apr 2008, 02:16
IRC nickname: lars_t_h
Geografisk sted: Fyn

Re: Python /Arduino/Raspberry Pi

Indlæg af lath »

AJenbo skrev:Du mangler også noget til at afbryde dit while loop så den ikke forsætter i en udenelig hed. Jeg er enig med Larth i at det bedste at gøre er at åbne filen, erstate linje skift med <br> og så spytte den ud på din hjemme side. Du kunne måske en dog springe python helt over ved blot at pege webserveren hen på csv filen og få den vist som teste i browseren.


Jeg tror ikke på at det et en fejl at der er startet en uendelig while loop.
I indlejrede systemer - efter initialisering - starter man altid med den her linie:

Kode: Vælg alt

while 1 {

... og det gør man fordi at softwaren skal køre så længe der er strøm tilsluttet.

@Ajenbo: er du sikker på at sd-kortet er tilsluttet Raspberry Pi computeren? Jeg ved godt at en RasPi har et SD kort, men Arduinoen kan også godt være udstyret med et.

Man kan godt skrive til et SD kort med FAT filsystem fra en Atmel microcontroller. Der findes FAT filsystem kode til en Atmel ATMega mikrocontroller (=Arduinoens mikrocontroller) ude på nettet.

Det er det her der får mig til at tro at Arduinoen er udstyret med et SD kort:
...
Lige nu opsamler jeg data på et SD kort (CSV fil), det virker fint.
Jeg vil dog bruge en Raspberry Pi til opsamlingen, ...


/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
AJenbo
Admin
Indlæg: 20878
Tilmeldt: 15. nov 2009, 15:04
IRC nickname: AJenbo
Geografisk sted: Vanløse, København

Re: Python /Arduino/Raspberry Pi

Indlæg af AJenbo »

Hvis det er meningen den skal vise en webside virker det ikke som det rigtige at have en while. Var det ikke også på RasberyPi koden skulle køre, for så er det jo ikke et indlejret system.

Det har ikke den store betydning hvor filen ligger hvis serveren kan tilgå den.
lath
Indlæg: 5095
Tilmeldt: 27. apr 2008, 02:16
IRC nickname: lars_t_h
Geografisk sted: Fyn

Re: Python /Arduino/Raspberry Pi

Indlæg af lath »

AJenbo skrev:Hvis det er meningen den skal vise en webside virker det ikke som det rigtige at have en while. Var det ikke også på RasberyPi koden skulle køre, for så er det jo ikke et indlejret system.

Det har ikke den store betydning hvor filen ligger hvis serveren kan tilgå den.


Programmet skulle lave dataopsamling - den slags laves nu engang i en uendelig løkke.
Webside delen er kun repræsentation, så det nytter ikke at starte programmet for at få en real-time værdi lige nu. Dataopsamlinger for en hel dag er derimod interessant, for så kan man begynde at tegne grafer.

Det skal laves er vel et cron-job som med jævnlige mellemrum producerer et javascript/en JSON fil, som bruges af det samme statiske HTML dokument.
Javascriptet/JSON filen har værdierne i et array, så man rimelig nemt kan producere en graf.

/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
AJenbo
Admin
Indlæg: 20878
Tilmeldt: 15. nov 2009, 15:04
IRC nickname: AJenbo
Geografisk sted: Vanløse, København

Re: Python /Arduino/Raspberry Pi

Indlæg af AJenbo »

ok, hade forstået det som at indsamlingen var på plads og det her handlede om at præsentere et udrag fra en csv fil på en webside.
hni
Indlæg: 73
Tilmeldt: 6. nov 2008, 18:28

Re: Python /Arduino/Raspberry Pi

Indlæg af hni »

Hej Alle!

Jeg har lige været væk et par dage :D

Lige nu står der en Arduino i viktualie rummet og gemmer data på et SD-kort (temp, hum og lys), den kan godt lave en CSV fil :)

Altså, det hele går ud på at Raspberry Pi skal opsamle data, dem skal den gemme i en CSV fil på Raspberry Pi'en
Der skal ligge en hjemmeside på den også som jeg kan kigge på, den skal gerne komme til at se ca. sådan ud.
Drivhus-html.png

Håber i kan se billedet.

Jeg har søgt og søgt på nettet, men kigger stikketer de forkete steder og jeg har stadigvæk ikke fundet en løsning.
Jeg har dog et par skud mere i bøssen :D :D

Første step er at kunne gemme filen, før jeg kan lave hjemmesiden.
P.S.
Grafen er opsamlet data fra drivhuset, tidslinen er i minutter (der er ikke realtime i min Arduino)
Vedhæftede filer
Drivhus-html.png
Drivhus-html.png (116.4 KiB) Vist 523 gange
lath
Indlæg: 5095
Tilmeldt: 27. apr 2008, 02:16
IRC nickname: lars_t_h
Geografisk sted: Fyn

Re: Python /Arduino/Raspberry Pi

Indlæg af lath »

Kunne du ikke skrive noget mere i detaljer?
Du bliver nødt til at give nogle oplysninger om dit system, ellers kan vi ikke rigtigt hjælpe dig - det bliver sådan mere gætteri agtigt uden konkrete oplysninger.

Opsummering, hvad vi ved:
  • Lige nu ved vi hvad du gerne vil: Kort fortalt: Lave en graf til en hjemmeside. Laves nok bedst som JSON data som et javascript på web siden bruger til at tegne grafen.
  • Vi har set at du bruger en seriel port til at hive tal ud fra din Arduino - men det er kun et enkelt tal - som ser ud til at være temperaturen.
  • Arduinoen:
    1. ... laver en simpel sample hvert minut (ikke så pålideligt), eller
    2. ... midler (laver et gennemsnit) over flere real-time samples indenfor et minut (meget mere pålideligt)
  • Du er interesseret i:
    1. Temperatur
    2. Luftfugtighed
    3. Lysmængde (i klx, kilo-lux gætter jeg)

Opsummering, hvad vi ikke ved:
  • Arduino programmet
  • Din *csv fils struktur: Hvor mange kolonner (vandret akse), og hvad hver kolonne er, samt delimiters (adskillelstegn) imellem både hver kolonne og imellem hver række.
  • Hvordan har du tænkt dig at overføre alle data imellem Arduino og Raspberry Pi computeren.

Har du ikke en ide om hvordan overføring af data imellem Arduinoen og Raspberry Pi computeren bedst sker, så hjælper jeg gerne, men så bliver jeg nok nødt til at se kildekoden til Arduino programmet (og det bliver uden at skulle underskrive en NDA: http://en.wikipedia.org/wiki/Non-disclosure_agreement )

Jeg har også hardwaren (et ATMega microcontroller test-board fra Atmel=ikke en Arduino), og en ekstra Raspberry Pi der kan hjælpe med i problemløsningen.

/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
AJenbo
Admin
Indlæg: 20878
Tilmeldt: 15. nov 2009, 15:04
IRC nickname: AJenbo
Geografisk sted: Vanløse, København

Re: Python /Arduino/Raspberry Pi

Indlæg af AJenbo »

Det jeg ikke forstår er hvordan det stadig er et spørgsmål hvordan data skal indsamles hvis der allerede eksisterer en csv fil med data. Så det er vel blot at plotte data på en graf?
lath
Indlæg: 5095
Tilmeldt: 27. apr 2008, 02:16
IRC nickname: lars_t_h
Geografisk sted: Fyn

Re: Python /Arduino/Raspberry Pi

Indlæg af lath »

AJenbo skrev:Det jeg ikke forstår er hvordan det stadig er et spørgsmål hvordan data skal indsamles hvis der allerede eksisterer en csv fil med data. Så det er vel blot at plotte data på en graf?

At data er indsamlet af Arduinoen er ikke nødvendigvis ensbetydende med at de også har forladt Arduinoen.

Min konklusion er:
Data er indsamlet, og ligger gemt på et SD-kort der er tilsluttet Arduinoen, og nu vil han så streame real-time data fra Arduinoen.

fordi:
Der spørges til et Python 2.7.x script der ikke virker som forventet, og så må SD-kortet jo være tilsluttet Arduinoen.
Jeg tror nu endnu mere på at Arduinoen har et SD-kort, da der kan indsamles data over et døgn. De data kan ikke være i RAM, da en Ardunio kun har 1024 bytes (1 KiB) S-RAM, og noget af den RAM ædes til stack, og data som firmwaren skal bruge.
Hvis scriptet ikke virker, så må data derfor endnu ikke være tilgængelig som en *csv fil på Raspberry Pi computerens SD-kort.

Der er så brug for en wire-protokol til overførsel af data imellem Arduinoen og Raspberry Pi computeren.
CSV encoding af data med ASCII tegn er simpelt nok som wire-protokol.

/Lars

Edit: Jeg kan se at der bruges forskellige ATMega microcontrollers til Arduino boards, og at ATMega32U4 har 2,5 KiB S-RAM, men det er stadig ikke nok : 3 samples á 1 byte/min. x 60 min./time x 24 timer i døgnet = 4320 bytes i døgnet.
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
AJenbo
Admin
Indlæg: 20878
Tilmeldt: 15. nov 2009, 15:04
IRC nickname: AJenbo
Geografisk sted: Vanløse, København

Re: Python /Arduino/Raspberry Pi

Indlæg af AJenbo »

Tror jeg har spottet problemet. Når du indlæser en linje fra serielporten konvertere du det til et tal med int():

Kode: Vælg alt

    data = int(ser.readline())

For at behandle den korrekt skal vi lidt vide hvordan den ser ud

Kode: Vælg alt

#!/usr/bin/python
import serial
import sys

baudrate = 9600
indgang = '/dev/ttyACM0'

ser = serial.Serial(indgang,baudrate)

while 1:
    print ser.readline()
    print '\n'

Og se hvad den skriver i terminalen.
hni
Indlæg: 73
Tilmeldt: 6. nov 2008, 18:28

Re: Python /Arduino/Raspberry Pi

Indlæg af hni »

Hej Alle!

Snøft, jeg har fundet fejlen, det var så simpel at jeg havde overset dette, det er til at tude over :cry:

En lille dum linie havde jeg overset:

Kode: Vælg alt

dataw = [data]


Nu virker det og jeg får en perfekt CSV fil:

Kode: Vælg alt

#!/usr/bin/python
import serial
import csv
import sys

baudrate = 9600
indgang = '/dev/ttyUSB0'
sted = '/home/hni/Drivhus/data.csv'


ser = serial.Serial(indgang,baudrate)

while 1:
    data = eval(ser.readline())
    dataw = [data]
    print data
    with open(sted,'ab') as fp:
        a = csv.writer(fp)
       
        a.writerow (dataw)
     
        del data
        del dataw
        fp.close()



Nu kan jeg arbejde videre og samle de rigtige tre data op.

For at kunne kende forskel på de data der bliver sendt fra drivhuset er de delt op i forskellige værdier, jeg kunne jo misse nogle data p.g.a. støj.
sådan er de tre informationer delt op:

Tal mellem 160 og 350 = temperatur ( sensoren kan måle mellem -40 og 150C)
Tal mellem 400 og 500 = luftfugtighed (sensoren kan måle mellem 0 to 100 relativ luftfugtighed)
Tal mellem 600 og 700 = sollys ( det er en LDR modstand jeg bruger og den har jeg sat til at give en værdi mellem 0 og 100)

Så alle tal der ligger uden for disse rammer er fejl data der bare skal ses bort fra.

Næste problem er at temperaturen en gang i mellem viser HELT forkert, den kan ligge på eks. 10C, næste temp = 113C og næste er igen 10C.

Jeg skal lige have lavet en rutine der tager tre målinger, og hvis nr. 2 aflæsning ikke ligger i mellem nr. 1 og nr. tre, så tager jeg tre nye målinger.

Jeg har masser af tid til at udføre denne test, der skal kun gemmes målinger hvert minut, senderen ude i drivhuset sender "en" data hvert sekund, så det vil tage 9 sekunder at hente alle tre oplysninger tre gange.
AJenbo
Admin
Indlæg: 20878
Tilmeldt: 15. nov 2009, 15:04
IRC nickname: AJenbo
Geografisk sted: Vanløse, København

Re: Python /Arduino/Raspberry Pi

Indlæg af AJenbo »

Kan se du nu i stedet bruger eval(). Det skal du passe meget på med, den kan betyde at hvis der sniger sig noget kode ind som input kan din maskine overtages. Du bør i stedet bruge en funktion der korrekt behandler dit input, hvis det da overhovedet er nødvendigt?

Det virker heller ikke som om du skriver mere end en kolonne i din CSV fil og så kunne du lige så godt blot skrive linjer i en tekst fil.

Når du kommer så langt så vil jeg forslå at du bruger http://www.jqplot.com/ til at tegne din graf.
lath
Indlæg: 5095
Tilmeldt: 27. apr 2008, 02:16
IRC nickname: lars_t_h
Geografisk sted: Fyn

Re: Python /Arduino/Raspberry Pi

Indlæg af lath »

Det er godt at kigge efter værdier der ligger helt ude i skoven på grund af interferens.

Du kan evt. bruge nogle små (i pico fahrad, pF) keramiske kondensatorer tæt på sensorerne, til at tage livet af et radiosignal der er blevet opfanget af en ledning. Radiosignalet er typisk fra en mobil telefon eller en basestation.

Det er bedre at bruge et unikt bogstav lige foran en måling til identificere hvad det er der læses, end at forskyde en målinger i tal-intervaller. Problemet er hvis der kommer en i-skoven-måling der efter addition kommer til at ligge i et anden målings hvad-kigger-vi-på interval.

Du kan gøre det man normalt gør og det er at midle(=lave et gennemsnit) over flere værdier indenfor et tidsinterval, evt udelade i-skoven-målinger fra midlingen.

Til slut vil jeg lige skrive at det er en god ide at bruge fejlkorrigerende koder i data der transmitteres. Det er specielt vigtigt hvis det ikke sker i et underliggende transmissionslag.
Læs lidt om emnet på f.eks. http://en.wikipedia.org/wiki/Forward_error_correction

/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags