L’objectif de cette note est de réaliser un appareil capable de mesurer les températures, de transmettre ces données sans-fil à une station et enfin de réaliser un visualiseur de données en OpenGL.
Je vous conseille de lire une note précédente au sujet du capteur DS1821:
http://hautefeuille.eu/capteur-de-temperature-dallas-1821.html
Travail préparatoire
- Configurer les modules Xbee correctement,
- Conception physique et électrique.
Composants matériels
- Module Arduino,
- Sonde de température DS1821 avec sa résistance,
- Ecran LCD avec son module série (http://www.crystalfontz.com),
- 2 modules Xbee pour émission et réception
- Un convertisseur série vers usb pour un des modules Xbee.
Composants logiciels
- Arduino IDE
- Python 2.7.x
- Kivy (kivy.org)
Protocole d’échange sur le port série
J’ai décidé de formater mes paquets de données de la manière suivante:
$val1!val2!...*
Ce choix rend plus facile les manipulations ultérieures des données.
Code source Arduino
code:
#include <SoftwareSerial.h>
#include <OneWire.h>
// DS1821 on digital pin 2 external
OneWire ds(2);
// DS1821 on digital pin 8 internal
OneWire ds1(8);
// LCD on digital pin 6 et 7
SoftwareSerial LCD(6, 7);
// LCD on digital pin 6 et 7
SoftwareSerial XBEE(3, 4);
int led = 13;
void setup(void)
{
LCD.begin(9600);
XBEE.begin(57600);
Serial.begin(9600);
//start 1821 conversion external
ds.reset();
ds.write(0xEE);
//start 1821 conversion internal
ds1.reset();
ds1.write(0xEE);
pinMode(led, OUTPUT);
digitalWrite(led,LOW);
}
void loop(void){
// external _
// internal 1
byte temp_, temp1_;
byte present, present1;
// protocol
// $val0|val1|...*
// start packet
String paquet = "$";
digitalWrite(led,LOW);
delay(1000);
// Read value external
present = ds.reset();
ds.reset();
ds.write(0xAA);
temp_ = ds.read();
// Read value internal
present1 = ds1.reset();
ds1.reset();
ds1.write(0xAA);
temp1_ = ds1.read();
//start 1821 conversion external
ds.reset();
ds.write(0xEE);
//start 1821 conversion internal
ds1.reset();
ds1.write(0xEE);
// negative temp external
if (temp_ >> 7 == 1){
paquet = paquet + "E";
paquet = paquet + "!-";
paquet = paquet + ((temp_ ^ 0xFF) + 1); // bit inversion
}
// positive temp external
else
{
paquet = paquet + "E";
paquet = paquet + "!+";
paquet = paquet + temp_;
}
// negative temp internal
if (temp1_ >> 7 == 1){
paquet = paquet + "!I";
paquet = paquet + "!-";
paquet = paquet + ((temp1_ ^ 0xFF) + 1); // bit inversion
}
// positive temp internal
else
{
paquet = paquet + "!I";
paquet = paquet + "!+";
paquet = paquet + temp1_;
}
// closing packet
paquet = paquet + "*";
Serial.print(paquet);
LCD.print("?n");
LCD.print(paquet);
XBEE.print(paquet);
digitalWrite(led,HIGH);
delay(1000); // default 500
}
Code source Python pour le visualiseur
code:
# -*- coding: utf-8 -*-
"""
@author: julien@hautefeuille.eu
#sudo apt-get install python-kivy
Usage: viewerGL.py
"""
import kivy
kivy.require('1.5.1')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
import serial
class MeteoArduino(App):
title = 'Meteo Arduino'
def build(self):
layout = BoxLayout(
orientation='vertical',
spacing=10,
padding=10)
label_temp = Label(
text='',
font_size='60sp',
size_hint=(1, 0.5))
label_temp1 = Label(
text='',
font_size='60sp',
size_hint=(1, 0.5))
layout.add_widget(label_temp)
layout.add_widget(label_temp1)
def get_packet(obj):
data = ser.read(13)
if data.startswith("$") and data.endswith("*"):
clean = data.strip('$').strip('*').strip()
split = clean.split('!')
label_temp.text = split[1]
label_temp1.text = split[3]
print split
else:
pass
Clock.schedule_interval(get_packet, 1)
return layout
if __name__ == '__main__':
connection = '/dev/ttyUSB0'
ser = serial.Serial(connection, 9600)
MeteoArduino().run()