2 Ensimmäinen projekti: Lämpömittari RS485-väylään
Ensimmäisessä projektissa liitetään lämpötila-antureita Arduino Nanoon ja Arduino Nano
lähettää RS485-väylän kautta lämpötilatietoja eteenpäin.
Tässä vaiheessa ei rakenneta vastaanotinta, mutta dataa voi vastaanottaa tietokoneella
käyttäen ensimmäisessä kirjoituksessa mainittua USB-adapteria.
Näitä DS1820-antureita voi liittää Arduinolle rinnakkain useita. Tässä esimerkissä on kolme
anturia, mutta voi käyttä pienempää tai isompaa määrää. Muuta vain Arduinon ohjelmakoodissa kohtaa:
const int anturimaara = 3;
Käytännössä virheitä RS485-väylällä tulee hyvissä olosuhteissa olemattoman vähän, jos ollenkaan.
Mutta varaudutaan siihen kuitenkin lisäämällä viestiin tarkastussumma, joka kertoo
välittyikö viesti oikein.
Koska tätä järjestelmää on tarkoitus myöhemmin pikkuhiljaa laajentaa, varaudutaan siihen
jo nyt tekemällä sanomarakenteesta seuraavanlainen:
Sanoman rakenne:
>MBK123wk<
||||| | |
||||| | Loppumerkki
||||| Tarkaste
||||Parametri
|||Sanoma
||Lähettäjä
|Vastaanottaja
Alkumerkki
Jokaisella laitteella on siis oma laitetunnuksensa, jonka se liittää sanomaan. Lisäksi lasketaan
yksinkertaiset tarkastusmerkit, joista vastaanottopuolella voidaan varmistaa että
saatu tieto on oikeaa. Tiedon mahdolliseen katoamiseen matkalla ei tässä vaiheessa varauduta millään
tavalla. Niin kuitenkin voi käydä, jos useampi laite lähettää vahingossa väylälle samaan aikaan.
Tarkastesumman laskeminen tietokoneella Pythonilla menisi näin:
#!/usr/bin/env python3
def laskeTarksum(sanoma):
sum1 = 0;
sum2 = 0;
for a in range(len(sanoma)):
arvo = ord(sanoma[a]);
sum1 = (sum1 + arvo) % 94;
sum2 = (sum1 + sum2) % 94;
return ">"+sanoma+chr(sum1 + 33) + chr(sum2 + 33)+"<"
viestiTarkasteella=laskeTarksum("MBK123")
print(viestiTarkasteella)
Lasketaan siis kaksi tarkastemerkkiä, joista kumpikin voi olla
ASCII-arvo välillä 33..126. Tämä siitä syystä, että halutaan merkkejä, joita sarjaportin kautta
on helppo lähettää ilman että täytyy varautua merkkien käsittelyssä asiaan sen enempää.
Merkkijono jolle tarkaste lasketaan, on MBK123.
Aloitusmerkin, tarkastusmerkkien ja lopetusmerkin kanssa RS485-väylään lähetettävä sanoma
kokonaisuudessaan on >MBK123wk<.
Ja sitten koodaamaan Arduinoa! Käynnistä siis Arduinon ohjelmisto. Ja liitä Arduino tietokoneeseen USB-kaapelilla.
Tässä projektissa käytetään kirjastoja OneWire ja DallasTemperature, joten
asenna ne nyt (ohje oli kirjoituksessa 1, jos jo unohdit miten se tehdään).
Arduinon koodi kaikessa yksinkertaisuudessaan (tai sekavuudessaan näkökannasta riippuen) on tällainen:
[rs485transmitter.ino]
Arduinon ohjelmistossa säädä kohdalleen Työkalut -> Kortti : Arduino Nano, Työkalut -> Prosessori : ATmega328(Old Bootloader) ja sitten vielä Työkalut -> Portti.
Nyt ohjelma voidaan Lähettää Arduinolle
valinnalla Sketsi -> Lähetä.
Jos kaikki menee oikein, Arduino alkaa nyt lähettämään lämpötiloja RS485-väylään.
Tässä vaiheessa kuitenkin testataan Arduinon Työkalut -> Sarjamonitorista, että tuleeko sieltä
dataa. Tulosteen pitäisi ollaa tämänkaltaista:
Mikäli tämäkin on ok, poista USB-kaapeli tietokoneen ja Arduinon väliltä ja syötä Arduinolle jännitettä vaikkapa kännykän laturilla. Lisää USB RS485 sovittimen ja Arduinon RS485-moduulin välille johtimet A-A ja B-B.
Nyt tietokoneella voi seurata RS485 Dataa esimerkiksi Minicom-ohjelmalla.
Tehdään nyt kuitenkin pieni Python3-ohjelma, joka varmistaa vielä sen, että vastaanotettu sanoma
on virheetön.
Asenna ensin pyserial, ellei se ole jo asennettuna:
sudo pip3 install pyserial tai sudo apt install -y python3-serial
Muuta koodissa kohta sarjaportti= viittaamaan oikeaan laitteeseen!
[vastaanota.py]
Muuta ohjelma suoritettavaksi:
chmod a+x vastaanota.py
ja sitten suorita ohjelma
./vastaanota.py
Ohjelman pitäisi tulostaa seuraavanlaisesti tekstiä:
kokonaisuudessaan on >MBK123wk<.
Ja sitten koodaamaan Arduinoa! Käynnistä siis Arduinon ohjelmisto. Ja liitä Arduino tietokoneeseen USB-kaapelilla.
Tässä projektissa käytetään kirjastoja OneWire ja DallasTemperature, joten
asenna ne nyt (ohje oli kirjoituksessa 1, jos jo unohdit miten se tehdään).
Arduinon koodi kaikessa yksinkertaisuudessaan (tai sekavuudessaan näkökannasta riippuen) on tällainen:
[rs485transmitter.ino]
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 10 //Lämpötila-anturit tässä pinnissä
unsigned int kierros = 0;
const int lahetysPin = 2; //tässä pinnissä RS485-moduulin ohjaus rx/tx
const int lahetaLampotilaKierros = 50; //Lähetä joka n kierroksella lämpötila-antureiden data
const char omaId = 'B'; //Tämän laitteen tunnus huomaa että '' eikä "" !
const char isantaId = 'M'; //Laite jolle lähetys osoitetaan
const int anturimaara = 3; //Näin monta anturia on kiinni
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(9600);
Serial.setTimeout(50);
pinMode(lahetysPin, OUTPUT);
digitalWrite(lahetysPin, LOW);
}
void loop() {
if (kierros % lahetaLampotilaKierros == 0) {
kierros=0;
sensors.requestTemperatures(); //pyydetään lämpötilat antureilta
String param = "";
for (int a = 0; a < anturimaara; a++) {
param += String(a) + "=" + sensors.getTempCByIndex(a) + ";";
}
laheta('T', param);
}
kierros++;
delay(100);
}
//======================================================================================================================================================
void laheta(char sanoma, String parametri) { //Parametreinä vain Sanoma ja Parametri.
String lahetaRivi = lisaaCRC(String(isantaId) + String(omaId) + String(sanoma) + parametri); //Lisätään itse vastaanottajaksi isäntäkone, lisätään oma tunnus
digitalWrite(lahetysPin, HIGH); // Enable RS485 Transmit
Serial.println(lahetaRivi);
Serial.flush(); //odotetaan kunnes lähetys valmis
delay(50);
digitalWrite(lahetysPin, LOW);
}
String lisaaCRC(String dataStr) {
byte sum1 = 0;
byte sum2 = 0;
for (int i = 0; i < dataStr.length(); i++) {
byte arvo = byte(dataStr[i]);
sum1 = (sum1 + arvo) % 94;
sum2 = (sum1 + sum2) % 94;
}
return String(">" + dataStr + String(char(sum1 + 33)) + String(char(sum2 + 33)) + "<");
}
Arduinon ohjelmistossa säädä kohdalleen Työkalut -> Kortti : Arduino Nano, Työkalut -> Prosessori : ATmega328(Old Bootloader) ja sitten vielä Työkalut -> Portti.
Nyt ohjelma voidaan Lähettää Arduinolle
valinnalla Sketsi -> Lähetä.
Jos kaikki menee oikein, Arduino alkaa nyt lähettämään lämpötiloja RS485-väylään.
Tässä vaiheessa kuitenkin testataan Arduinon Työkalut -> Sarjamonitorista, että tuleeko sieltä
dataa. Tulosteen pitäisi ollaa tämänkaltaista:
>MBT0=21.25;1=-127.00;2=-127.00;cU< >MBT0=21.38;1=-127.00;2=-127.00;gP< >MBT0=22.19;1=-127.00;2=-127.00;gQ<
Mikäli tämäkin on ok, poista USB-kaapeli tietokoneen ja Arduinon väliltä ja syötä Arduinolle jännitettä vaikkapa kännykän laturilla. Lisää USB RS485 sovittimen ja Arduinon RS485-moduulin välille johtimet A-A ja B-B.
Nyt tietokoneella voi seurata RS485 Dataa esimerkiksi Minicom-ohjelmalla.
Tehdään nyt kuitenkin pieni Python3-ohjelma, joka varmistaa vielä sen, että vastaanotettu sanoma
on virheetön.
Asenna ensin pyserial, ellei se ole jo asennettuna:
sudo pip3 install pyserial tai sudo apt install -y python3-serial
Muuta koodissa kohta sarjaportti= viittaamaan oikeaan laitteeseen!
[vastaanota.py]
#!/usr/bin/env python3
import serial, time
def laskeTarkiste(sanoma):
sum1 = 0;
sum2 = 0;
for a in range(len(sanoma)):
arvo = ord(sanoma[a]);
sum1 = (sum1 + arvo) % 94;
sum2 = (sum1 + sum2) % 94;
return ">"+sanoma+chr(sum1 + 33) + chr(sum2 + 33)+"<"
#------------------------------------------------------------------------------------------
sarjaportti=serial.Serial("/dev/serial/by-path/pci-0000:00:14.0-usb-0:2:1.0-port0", baudrate=9600, timeout=0.05)
while True:
try:
arvo=(sarjaportti.readline().decode('iso-8859-1', errors='replace').replace("\r\n","")) #Luetaan sarjaportista String ilman rivinvaihtomerkkeja
if(len(arvo)>0):
sisalto=arvo[1:-3] #sanomat varsinainen sisältö ilman alku, varmenne ja loppu -merkkejä
lasketullaVarmisteella=laskeTarkiste(sisalto)
if(lasketullaVarmisteella == arvo): #saatu varmennemerkki täsmää itse lasketun kanssa
pass
print("Saatiin oikein oleva sanoma: "+arvo)
else:
print("Saatiin sanoma, jossa on kuitenkin virhe tarkisteessa: "+arvo+ " LASKETTU: "+lasketullaVarmisteella)
except Exception as e:
print("***VIRHE***")
print(e)
time.sleep(0.2)
Muuta ohjelma suoritettavaksi:
chmod a+x vastaanota.py
ja sitten suorita ohjelma
./vastaanota.py
Ohjelman pitäisi tulostaa seuraavanlaisesti tekstiä:
Saatiin oikein oleva sanoma: >MBT0=20.44;1=-127.00;2=-127.00;cT< Saatiin oikein oleva sanoma: >MBT0=20.81;1=-127.00;2=-127.00;dn< Saatiin oikein oleva sanoma: >MBT0=21.75;1=-127.00;2=-127.00;hj<
Ja miksi minulla sitten vain anturi 0 näyttää järkevää lämpötilaa ja anturit 1 ja 2 -127 astetta?
No siksi, että vain anturi 0 tuli loppupeleissä tuohon koekytkentäalustalle laitettua, koska
kahteen muuhun anturiin en jaksanut juottaa johtoja jolla ne levylle kiinni saisi..


Hyvää settiä... etenkin tuo koodin upotus värityksineen on erinomainen.
VastaaPoista