RPi, Arduino ja Gambas

[size=150]Alkusanat[/size]

TÀssÀ artikkelissa opetetaan kuinka tehdÀÀn Raspberryyn graafinen ohjelma, jolla luetaan ja lÀhetetÀÀn tietoa Arduinolle. Grafiikkapuolta hoitaa Gambas3 joka muistuttaa hyvin pitkÀlti Visual Basic 6:sta. Gambasia ei ole saatavilla Windowsille, joten ne joilla ei ole omalla koneella Linuxia, joutuvat ohjelmoimaan suoraan RaspberryssÀ. Artikkelissa rikotaan vain jÀÀvuoren huippua, mutta toivottavasti tÀstÀ on jollekkin hyötyÀ. Arduino sekÀ Gambas3 ohjelmat kirjoitan PC:llÀ sekÀ ohjelmoin Arduinon. NÀmÀ toki voi suorittaa RPI:llÀkin mutta tÀssÀ artikkelissa ei kÀsitellÀ Arduino Iden asentamista RPI:lle.

Artikkelilin ymmÀrtÀmiseksi on hyvÀ ettÀ osaat vÀhÀn ohjelmoinnin perusteita. Osaat ajaa ohjelman Arduinolle, sekÀ osaat kÀynnistÀÀ Raspberryn. Toki kaiken voi suorittaa ilman RPI:tÀ, mikÀli tietokoneellasi on Linuxin kÀyttöjÀrjestelmÀ.

TÀssÀ liitetiedosto, josta löytyy kyseiset sorsat:tiedostot.zip (11.7 KB)
[size=150]Laitteisto[/size]

-Raspberry Pi (minun tapauksessa 256Mb)
-jokin nÀyttö
-Arduino Uno ja USB kaapeli
-2x Potikka 10K
-Vastus ja ledi
-Hyppyjohtoja
-USB nÀppis ja hiiri

[size=150]Aloitus[/size]

Gambas3 löytyy Debianin paketeista RPI:stÀ suoraan, mutta mitÀ olen intternettiÀ lukenut, niin siinÀ on jotain ongelmia kansioiden sijoittelussa tai jotain. No ei siitÀ sen enempÀÀ. NetistÀ löytyy suoraan kÀÀnnetty versio jossa on Gambas3 valmiiksi asennettuna, joten kÀytÀmme sitÀ.

http://dl.dropbox.com/u/97096067/2012-07-15-wheezy-gambas3.zip

Asennamme imagen muistikortille ohjeet löytyy RuuvipenkistÀ http://www.ruuvipenkki.fi/foorumi/viewtopic.php?f=15&t=682
Nyt meillÀ pitÀisi olla toimiva versio jossa on Gambas3 valmiiksi asennettuna. EnsimmÀisellÀ kÀynnistyskerralla kirjaudutaan sisÀÀn (pi, raspberry) ja kÀynnistetÀÀn x

startx

[size=150]Arduino[/size]

Teemme Arduinoon yksinkertaisen kytkennÀn, johon lisÀÀmme kaksi potentiometriÀ, sekÀ yhden ledin. NÀin ollen pystymme fyysisesti toteamaan ohjelman toiminnallisuuden.

[code]void setup()
{

Serial.begin(9600); // serialin asetukset
pinMode(2, OUTPUT); // Ledin pinni outputiks
digitalWrite(2, LOW); // Ledi alas

}

void loop()
{
int data; // data muuttuja serialille

if (Serial.available()) { // jos seriali on saatavilla
data=Serial.read(); // data muuttujaan serialilta tieto

if (data==49){ // jos saapuva data on 1 keyascii 49
digitalWrite(2, HIGH); // Ledi pÀÀlle
}
if (data==48){ // jos saapuva data on 0 keyascii 48
digitalWrite(2, LOW); // Ledi pois pÀÀltÀ
}

data=0; // kun seriali on lukenut data=0

}

Serial.print(“POT1A”); // lĂ€hetetÀÀn serialiin “POT1A”
Serial.print(analogRead(0)); // lÀhetetÀÀn serialiin A0:n arvo
Serial.print(“F”); // lĂ€hetetÀÀn serialiin lopetus “F”
Serial.print(“POT2A”); // lĂ€hetetÀÀn serialiin “POT2A”
Serial.print(analogRead(1)); // lÀhetetÀÀn serialiin A1:n arvo
Serial.print(“F”); // lĂ€hetetÀÀn serialiin lopetus “F”

delay(100); // viive jotta seriali pysyy perÀssÀ

}[/code]

Tutkitaan hieman koodia:
if (data==49){
MistÀ tÀmÀ 49 oikeen muodostuu? Se on KeyAsciita. Eli Gambas lÀhettÀÀ numeron 1 joka muutetaan KeyAscii muotoon ja siitÀ tulee 49. Kaikki merkit löytyvÀt osoitteesta: asciitable.com/
Serial.print(“POT1A”);
Miksi lopussa iso “A”? No tĂ€mĂ€ voisi olla vai “x” tai mikĂ€ tahansa merkki. TĂ€mĂ€ kuitenkin siksi ettĂ€ se helpottaa Gambas koodia. Seriaalista tuleva tieto on kirjoitettu yhteen pötköön, niin Gambas tietÀÀ ettĂ€ kun tulee iso “A” niin seuraavaksi tulee anturin arvo.
Serialissa liikkuu tĂ€mĂ€nnĂ€köistĂ€ tietoa: POT1A453FPOT2A678FPOT1A443FPOT2A578F

Serial.print(“F”);
“F” lĂ€hetetÀÀn Serialiin niin Gambas tietÀÀ milloin anturin arvo on luettu loppuun asti.

kÀÀnnetÀÀn ohjelma ja ajetaan se Arduinoon PC:n avulla.

[size=150]Gambas[/size]

KĂ€ynnistĂ€mme Gambasin, jonka jĂ€lkeen vasemmalta “New project
” avautuu seuraavanlainen nĂ€kymĂ€


Valitaan “Qt graphical application” ja painetaan “Next”, valitaan kansio johon ohjelma luodaan ja painetaan “Next”, lopuksi annetaan ohjelmalle nimi ja vielĂ€ “Ok”

TÀssÀ on kuvattu tÀrkeimpiÀ kohteita ohjelmasta. TÀssÀ artikkelissa ei opeteta Gambas ohjelmointia muutakuin vaadittavan verran, jotta esimerkin pystyy toteuttamaan.
[b]

  1. Seriali kirjaston lisÀÀminen[/b]

EnsimmĂ€iseksi tarvitsemme kirjaston jolla kĂ€sitellÀÀn Serialia. TĂ€ssĂ€ kirjastossa on muutakin, mutta tarvitsemme vain sarjaporttia. TĂ€mĂ€ löytyy ylĂ€palkista “Project -> Properties
”


Selataan listaa ja laitetaan ruksi kohtaan “gb.net”. Nyt meillĂ€ on kirjasto kĂ€ytössĂ€.

2. Graafinen kÀyttöliittymÀ

Formia voi venytellĂ€ haluamansa kokoiseksi, samoin yleensĂ€ kaikkia komponenttejĂ€. LisĂ€tÀÀn Formille kolme Buttonia eli nappia sekĂ€ kaksi LCDNumberia. Komponenttien lisÀÀminen tapahtuu ihan hiirellĂ€ vetĂ€mĂ€llĂ€ ja pudottamalla Formille. Clikataan EnsimmĂ€istĂ€ LCDNumberia ja muutetaan sen arvoa “Digits” ja annetaan arvoksi 4, koska Arduinolta saatava potentiometrin tilatieto on maksimissaan neljĂ€ numeroa eli 1023. TehdÀÀn sama toiselle LCDNumberille. Buttoneiden tekstejĂ€ voi muuttaa klickaamalla haluttua nappia ja muuttamalla arvoa “Text”.


Lopuksi lisÀÀmme Formille “SerialPort1”:n.

Nyt kÀyttöliittymÀ on valmis.
3. Ohjelmakoodi

Ohjelmakoodi on alla. Sen voi kirjoittaa Gambasiin kun tuplaclikkaa jotain komponenttia formilla, tai painaa formin ylĂ€puolella olevaa valkoista nappia, jossa lukee “Code” kun hiiren cursorin vie sen pÀÀlle. Pyyhi valmiiksi tullut koodi ja kopio koodi alapuolelta. En rupea Iden kĂ€yttöÀ kĂ€ymÀÀn tĂ€ssĂ€ lĂ€pi tarkemmin. En tiedĂ€ onko Gambasista kirjoitettu mitÀÀn suomenkielistĂ€ opasta, mutta Visual Basic 6 löytyy ainakin ja niillĂ€ pÀÀsee aika pitkĂ€lti alkuun. Muutamia eroavaisuuksia toki on mutta niistĂ€ lukee ohjelman kotisivuilla.

[code]’ Gambas class file

Public Luettu As String 'Muuttuja

Public Sub SerialPort1_Read() 'Kun Serialportti lukee se suorittaa kyseisen function

Dim Kirjain As String 'Luettu kirjain Serialista
Dim Katkottu As New String[] 'Taulu johon kirjaimet luetaan, tauluja on niin monta kuin Arduino lÀhettÀÀ

Read #SerialPort1, Kirjain, 1 'Luetaan kunnes ei ole mitÀÀn luettavaa
If Kirjain <> “F” Then 'niin kauan kunnes tulee F joka tarkoitti ettĂ€ tulee seuraavan anturin tieto
Luettu &= Kirjain 'lisÀtÀÀn Luettu muuttujaan Kirjain muuttujan arvo
Else
Katkottu = Split(Luettu, “A”) 'katkotaan Luettu A:n kohdalta

If Katkottu[0] = "POT1" Then ' jos kyseessÀ on POT1
  
  LCDNumber1.Value = Val(Katkottu[1]) 'Asetetaan LCDNumber1 valueksi arvo joka saatiin arduinolta
  
Endif

 If Katkottu[0] = "POT2" Then
  
  LCDNumber2.Value = Val(Katkottu[1])
  
Endif

Luettu = "" 'TyhjennetÀÀn Luettu

Endif

End

Public Sub Yhdista()
'tÀmÀ functio hoitaa Arduinon yhdistÀmisen
’
If SerialPort1.Status = Net.Active Then 'MikÀli yhteys on jo muodostettu
Close SerialPort1 'suljetaan yhteys
Else 'muuten hoidetaan yhteys kuntoon
SerialPort1.portname = “/dev/ttyACM0” ’ osoite jossa Arduino sijaitsee
SerialPort1.Speed = 9600
SerialPort1.parity = SerialPort.none
SerialPort1.databits = SerialPort.Bits8
SerialPort1.StopBits = SerialPort.Bits1
SerialPort1.FlowControl = SerialPort.none
Try SerialPort1.Open() 'yritetÀÀn avata yhteys
If Error Then Message.Error(“Ongelmia yhdistĂ€essĂ€ laitteistoon”) 'jos ei onnistu annetaan virhe
Endif

End

Public Sub Arduino(viesti As String)
'TÀllÀ functiolla lÀhetetÀÀn tietoa Arduinolle
Try Print #SerialPort1, viesti 'lÀhetetÀÀn tietoa serialille
If Error Then 'jos virhe
Message.Error(“Viestin lĂ€hettĂ€minen ei onnistunut”) 'tulostetaan virhe
Endif

End

Public Sub Button1_Click()
'kun Button1 clicataan, niin tÀmÀ koodi suoritetaan
Arduino(“1”) 'kutsutaan functiota Arduino ja lĂ€hetetÀÀn viesti 1
'joka Arduinonkoodissa tarkoittaa ettÀ sytytetÀÀn led

End

Public Sub Button2_Click()
'kun Button2 clicataan, niin tÀmÀ koodi suoritetaan
Arduino(“0”) 'kutsutaan functiota Arduino ja lĂ€hetetÀÀn viesti 0
'joka Arduinonkoodissa tarkoittaa ettÀ sammutetaan led

End

Public Sub Button3_Click()
Yhdista 'suljetaan yhteys
Quit 'suljetaan ohjelma
End

Public Sub Form_Open()
'tÀmÀ koodi suoritetaan kun formi kÀynnistyy
Sleep 1 'odotetaan sekuntti
Yhdista 'yhdistetÀÀn seriali

End

Public Sub Form_Close()
'tÀmÀ koodi suoritetaan kun ohjelma suljetaan ruksista
Yhdista 'suljetaan jos yhteys on pÀÀllÀ

End[/code]
Olen kommentoinut ohjelmakoodia parhaani mukaan.

4. Ohjelman kÀÀntÀminen

Ohjelmaa voi ajaa ylÀpalkissa olevalla vihreÀllÀ nuolella. Seuraavaksi kÀÀnnÀmme ohjelman yhdeksi ajettavaksi tiedostoksi. TÀmÀn jÀlkeen ohjelman voi kÀynnistÀÀ suoraan pÀÀttestÀ.
YlĂ€valikosta “Project -> Make -> Executable
” Nimi ja ok. Nyt meillĂ€ on tiedosto jota voi ajaa ettei Gambasia tarvitse kĂ€ynnistÀÀ.

5. Kopio

Kopioidaan kansio, jonka alussa loimme uuden Gambas projektin luomisen yhteydessÀ ja liitÀmme kansion Raspberrylle. TÀmÀn voi suorittaa USB muistitikulla tai vaihtoehtoisesti siirtÀmÀllÀ kansio suoraan muistikortille, omaan kotikansioon. KytketÀÀn Arduino USB-kaapelilla Raspberryyn. Ohjelman ajaminen tapahtuu kohdekansiossa pÀÀtteellÀ ./Ohjelmannimi.gambas tai tiedostojenhallinnassa tuplaclikkaamalla Ohjelmannimi.gambas tiedostoa.
kuva6.png
[size=150]Loppusanat[/size]

MitÀ tÀllÀ voi tehdÀ? Mahdollisuudet ovat tietysti rajattomat. Gambas tuntuu olevan vielÀ aika vieras monelle, joten halusin luoda arttikkelin jossa hiukan raapaistaan pintaa ja saisi harrastelijat huomaamaan ettÀ graafisen kÀyttöliittymÀn tekeminen ei vaadi ihmeitÀ ja kymmenien rivien kirjoittamista, ettÀ saa muutaman napin nÀytölle. Joten raja on nyt laskettu niin alas kuin mahdollista -> nyt koodaamaan!

HyvÀ artikkeli. Laitan raspberryn pian tilaukseen, pitÀÀ tÀtÀkin kokeilla.

Tarkoittaako tÀmÀ sitÀ, ettÀ jos asennan kortille tuon zipin, saan rpi:hin sekÀ sen perus kÀyttiksen ja Gambas3sen? Eli siis rasberryn kÀyttöön riittÀÀ, kun asennan tuon paketillisen muistikortille?

KyllĂ€ tarkoittaa. Paketissa on Raspbian “wheezy” sekĂ€ valmiiksi asennettu Gambas3. :sunglasses:

Miten voisin kÀyttÀÀ gambasin sijasta suoraan python.koodia? Tarkoitus olisi ohjata webiopi ohjelmalla arduinoa.

jotenkin nÀin:

import serial ser=serial.Serial('/dev/ttyACM0',9600 teksti=1 #tai 0 ser.write(teksti)

No mahtavaa, kiitos hyvÀstÀ ohjeesta !

Sujui helposti yksi ongelmanratkaisu, kun RasPi ja Arduino Uno oli jo omaan projektiini varattu. VielĂ€ pitĂ€isi saada sÀÀnnöllisesti siirrettyĂ€ vĂ€hĂ€n tietoa Arduinolta RPin kautta nettiin

Ai niin sattuiko seuraava artikkelisi olemaan
 :mrgreen:

Ftp, PHP $_POST, Database vai miten halusit?

TÀssÀ tiedon janoaville pythonia. Eli ohjelma lukee Arduinolta 2 analogiatietoa, tekee niistÀ tiedoston ja lÀhettÀÀ sen ftp:llÀ palvelimelle. Ohjelma on allekkirjoittaneen kÀsialaa, enkÀ ole laittanut siihen minkÀÀnlaista virheenkÀsittelyÀ. Luo samaan kansioon missÀ ohjelmaa ajat tiedot.txt

[code]import serial
import time
import datetime
from ftplib import FTP
#muuta seuraavan muuttujan arvoa sen mukaan montako anturia luetaan
antureita=2

alku = time.time() #muuttuja tietokoneen aika
anturiarvot=[]
aika = datetime.datetime.now()#kello ja pÀivÀmÀÀrÀ joka tulostetaan tiedostoon
aika=aika.strftime("%d.%m.%Y %H:%M:%S") #muutetaan luettavampaan muotoon

#FTP(“palvelin” , “kĂ€yttĂ€jĂ€tunnus”, “salasana”)
ftp = FTP(“192.168.0.1”, “kayttaja”, “salasana”)

#lisÀtÀÀn antureita listaan
for i in range(antureita):
anturiarvot.append(“0”)

odotus_aika = int(raw_input(“Anna viive sekunneissa:”))
odotus_aika2=odotus_aika+alku
lopeta=""
#tÀtÀ joudut muuttamaan serialportin mukaan!!!
ser=serial.Serial("/dev/ttyACM0",115200)
if (ser):
print(“Yhteys Arduinoon muodostettu.”)

#ohjelma pyörii luupissa, kunnes kÀyttÀjÀ kirjoittaa x ja painaa enter
while lopeta<>“x”:
#luetaan serialia size= montako bittiÀ luetaan. yksi kirjain tai numero 1 bitti
ser_tiedot=ser.read(size=antureita7)
lopeta = raw_input(“Lopeta ohjelma kirjoittamalla x ja painamalla Enter”)
#etsitÀÀn oikea aloituskohta eli “A0”, koska ohjelma alkaa sattumanvaraiselta paikalta
#lukemaan serialia
for i in range(len(ser_tiedot)):
loppu = i + len(“A0”)
if ser_tiedot[i:loppu] == “A0”:
#asetetaan serialin tulos oikeaan muotoon (leikkaa liitÀ)
#
uusi=ser_tiedot[i:antureita*7] + ser_tiedot[0:i]
for u in range(antureita):
#pilkotaan vain anturien arvot pötköstÀ
anturiarvot[u]=uusi[2+(7
u):6+(7*u)]
#mikÀli aika on suurempi, mitÀ odotusaikamme
if odotus_aika2<time.time():
#muutetaan seuraava odotusaika
odotus_aika2=odotus_aika2+odotus_aika
#avataan tiedosto lisÀys muodossa
tiedot = open(“tiedot.txt”, “a”)
#kirjoitetaan tiedostoon
tiedot.write(aika + " Anturi0:"+anturiarvot[0]+" Anturi1:"+anturiarvot[1]+"\n")
#suljetaan tiedoston kahva
tiedot.close()
#lÀhetetÀÀn tiedosto ftp:lle
ftp.storbinary(‘STOR tiedot.txt’, open(‘tiedot.txt’, ‘rb’))
#suljetaan ohjelman lopussa ftp
ftp.close()
[/code]

Arduinoon seuraavanlainen koodi:

[code]void setup() {

Serial.begin(115200);
}

void loop() {

Serial.print(“A0”);
Serial.print(analogRead(A0)+1000);
Serial.print(“X”);

Serial.print(“A1”);
Serial.print(analogRead(A1)+1000);
Serial.print(“X”);

delay(10);
}[/code]

EipÀ tuo mennytkÀÀn ihan heittÀmÀllÀ:
Latasin koko paketin + ohjelmakoodin RasPille, ajoin Gambasilla ja tulee herja:
“gb.qt4: warning: unable to load Qt translation: en_GB.UTF-8”

Ja hetken pÀÀstÀ aukeaa ikkuna jossa otsikkona ohjelman nimi,
ikkunassa tikkarin kuva ja “ongelmia yhdistettĂ€essĂ€ laitteistoon” sekĂ€ ok-painike
(Arduinossakaan ei kyllÀ ole kytkentöjÀ, mutta ainakin PC:llÀ kokeillessa tuli konsoliin tekstiÀ ok)

MitÀ itse sain kaiveltua niin:
Eka kohta liittynee kÀytössÀ olevaan kieleen, ei kai pitÀisi haitata (?)
Eli pitÀisi ehkÀ kieleksi valita englanti, vain nÀppis suomeksi ?

Toinen kohta liitty kai usbiportin nimeen, RasPin lsdev ei sisĂ€llĂ€ tuollaista “/dev/ttyACM0” laitetta. LĂ€himmĂ€s osuu “/dev/ttyAMA0” mutta ei toimi sillĂ€. MillĂ€ tuohon oikean nimen löytĂ€isi ?

EDIT: Kelpuuttaakohan Google sites FTP siirtoa ? (tullut joskus tuonne domaini parkkeerattua)

tuo herja on joku automaattisen kÀÀnnöksen herja tai jotain vastaavaa. siitĂ€ ei tarvi vĂ€littÀÀ. simun kohdalla ongelma on ainoastaan tuon oikean seriaalin löytĂ€minen
 eli usb arduinosta irti ja rasbilla terminaaliin ja kirjota
$ cd /dev
$ ls tty*
saat listan
 pluggaa usb arduinoon paikalleen ja
$ls tty*
se mikÀ sinne tulee lisÀÀ niin se on se oikea :sunglasses:

No niin, kuso kulkee :smiley: Piti vaan buutata RasPi vĂ€lillĂ€ ettĂ€ sai “ttyUSB0”:n erottumaan joukosta. Kiitos vinkistĂ€ !

Hienoa homma!

onnistuko tuon imagen asennus ihan ongelmitta?

ItellÀ toimii uusin versio raspbianista mutta tuota en saa toimimaan?
myöskÀÀn asennus ei onnistu
 kolmella eri tavalla oon kokeillu ja ensimmĂ€isellĂ€ ei lisĂ€osat onnistunu lisĂ€tĂ€, tuli vaan liuta erroreita


sen jĂ€lkeen kaks eri asennuskertaa muuten onnistu ihan hyvin mutta kun yrittÀÀ kĂ€ynnistÀÀ ohjelman nin suoritinkĂ€yttö hyppÀÀ 100% eikĂ€ ohjelma vaan kĂ€ynnisty ikinÀ 

sama ongelma ollu monella muullakin ja kĂ€sittÀÀkseni just tuo image jossa gamabas asennettuna on juurikin sitĂ€ varten tehty jos ei se asennus onnistu


sitten yritin tietysti tuota imagee ajaa kortille mutta ei etes yritĂ€ lĂ€htee kĂ€ynnistymÀÀÀn
 (merkkivaloista palaa ainoastaan punanen)
 ajoin tietysti sen uusimman uudelleen ja testasin niin se toimii taas ihan hyvin
 pari kertaa kokeilin jopa eri korteilla mutta en sitĂ€ saanu kĂ€ynnistymÀÀn?? teinkö jotain vÀÀrin?

ohjeita? vinkkejÀ?
linux ei ole ennestÀÀn kovin tuttu niin ei ole noista arkkitehtuureista tms paketeista kokemusta ettĂ€ mitĂ€ pitÀÀ olla asennettuna