Table des matières
Stage LPH: février 2019
Introduction
Stage LPH de février à L'UBO Open Factory
L'objectif de cet atelier est de réaliser une petite station météo et domotique à base d'arduino.
Public cible | 12 jeunes |
---|---|
Date | 18, 19 et 20 février |
Lieu | UBO Open Factory |
Modalités
Une inscription est nécessaire pour pouvoir planifier. Une adhésion (de 20 euros) et une participation financière (60 euros) pour le matériel (en fonction du projet) seront demandées.
Planning et contenu
- Communication
- Inscription et vérification de la faisabilité du projet (en compétences, en temps, en matériels si besoin et en coût matériel)
- Validation inscription et devis matériel
- Planification du projet sur la semaine de mai (en fonction du temps…)
État du stock et matériel pour le stage
Stock à vérifier en fonction des projets. Voici une première liste de matériel à apporter avec nous pour le stage:
Intitulé | Quantité dans le stock | A commander/produire |
---|---|---|
Servo moteur (1 par kit) | ||
Arduino nano (avec câble USB) | ||
Câbles élec | ||
écran pour le vidéo-projecteur | ||
vidéo-projecteur | ||
2 rallonges | ||
4 multiprise | ||
12 PCs: (j'en ai déjà 5 de prêt, il m'en reste 2/3 à préparer) | ||
alimentations PC | ||
souris PC | ||
12 cartes arduinos (avec cordons USB) | ||
12 DHT 11 | ||
12 relais | ||
12 transistors | ||
12 servo moteurs | ||
12 LDR | ||
12 ventilateurs | ||
cartes de support pour les éléments | ||
fils de connexion | ||
3/4 fers à souder | ||
4 tapis pour fer à souder | ||
4 support fer à souder | ||
étain | ||
fils | ||
en option (afficheurs LCD, module bluetooth) |
Liste de tâches
Tâche | Qui | Opération |
---|---|---|
Faire l'état du stock | Christian et Stéphane | |
Commande matériel | Christian et Stéphane | |
Communication sur les listes de diffusion | Christian et Stéphane | |
Communication “Affiche” | ||
Gestion des inscriptions | ||
Validation des inscriptions | ||
Planification des projets |
Présent pour animer
Animation de l'atelier:
- Stéphane Blanc
- Christian Jacolot
- …
Déroulé du projet
- Présentation du projet
- Validation du matériel (kit arduino) et des logiciels installés sur le PC
- Montages:
- capteur température
- capteur de lumière
- programmation arduino
- programmation visuelle et affichage des valeurs des capteurs
- Montages:
- servo moteur
- relais
- programmation arduino
- programmation visuelle et contrôle des automatismes
Contacts
Structure | Nom Prénom | Rôle sur le projet / poste |
---|---|---|
Maison du libre | Stéphane Blanc | Logistique et animation |
Maison du libre | Christian JACOLOT | Logistique et animation |
Remerciements
Nous remercions Yves et Matthieu pour accueillir le stage dans les locaux de l'UBO Open Factory.
Préparation des PC
Installation de xubuntu 18.04 sur les PC, iso sur clé USB.
Mise à jour et installation des logiciels/paquets nécessaires:
$ sudo apt update $ sudo apt upgrade $ sudo apt install git mercurial build-essential arduino-core arduino-mk gcc-avr avr-libc openjdk-8-jdk $ sudo apt install squeak-vm squeak-plugins-scratch $ sudo apt install nodejs npm $ id $ sudo usermod -a -G dialout $USER $ more /etc/group # télécharger arduino sur arduino.cc / linux 32 bits $ cd Téléchargements/ $ tar xf arduino-1.8.8-linux32.tar.xz $ cd arduino-1.8.8/ $ ./install.sh $ cd # démarrer arduino IDE # menu Outils / Gérer les bibliothèques # installer: circuit playground, unified sensor, DHT sensor library $ sudo npm install -g --unsafe-perm node-red $ node-red # navigateur web sur localhost:1880 # installer via palette: node-red-node-serialport et node-red-dashboard $ sudo apt install logisim openssh-server $ sudo apt install gcc-avr avr-libc flashplugin-installer algobox blender python3-dev python3-setuptools python3-numpy $ sudo apt install python3-opengl ffmpeg libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsmpeg-dev libsdl1.2-dev libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev libtiff5-dev libx11-6 libx11-dev fluid-soundfont-gm timgm6mb-soundfont xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic fonts-freefont-ttf libfreetype6-dev $ java -version $ javac -version $ sudo update-alternatives --config java # choisir java 8 $ java -version $ sudo add-apt-repository ppa:openscad/releases $ sudo apt update $ sudo apt install openscad $ sudo apt install fritzing fritzing-parts gimp
Présentation
Documents
Fichier de présentation mdl_stage_lph_fevrier_2019.odp
Code
Code Arduino pour piloter le relai tout en récupérant la température et l'humidité:
int relayPin = 3; // relay pin -- Digital 3 int relayState = HIGH; int incomingByte = 0; // for incoming serial data unsigned long previousMillis = 0; long checkDHT = 2000; void setup() { Serial.begin(9600); pinMode(relayPin, OUTPUT); digitalWrite(relayPin, relayState); previousMillis = millis(); } void loop() { // send data only when you receive data: if (Serial.available() > 0) { // read the incoming byte: incomingByte = Serial.read(); // Serial.print("I received: "); // Serial.println(incomingByte, DEC); if (incomingByte == 49) { // ASCII: 1 => 49 relayState = HIGH; } else { relayState = LOW; } } unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= checkDHT) { previousMillis = currentMillis; // Remember the time Serial.print("{\"hum\":"); Serial.print(random(20,80)); Serial.print(",\"temp\":"); Serial.print(random(0,50)); Serial.println("}"); } // set the relay: digitalWrite(relayPin, relayState); }
Avec servo moteur
#include <VarSpeedServo.h> #include <ArduinoJson.h> VarSpeedServo myservo; // create servo object to control a servo // twelve servo objects can be created on most boards int pos = 0; // variable to store the servo position int positionServo = 0; int speedServo = 100; // Serial reading buffer const byte numChars = 60; char receivedChars[numChars]; // an array to store the received data boolean newData = false; StaticJsonBuffer<120> jsonBuffer; void recvWithEndMarker() { static byte ndx = 0; char endMarker = '\n'; char rc; while (Serial.available() > 0 && newData == false) { rc = Serial.read(); if (rc != endMarker) { receivedChars[ndx] = rc; ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // terminate the string ndx = 0; newData = true; } } } void setup() { pinMode(9, OUTPUT); myservo.attach(9); // attaches the servo on pin 9 to the servo object Serial.begin(9600); // myservo.write(positionServo, speedServo, true); newData = false; } void loop() { recvWithEndMarker(); if (newData == true) { JsonObject& root = jsonBuffer.parseObject(receivedChars); if (!root.success()) { Serial.println("parseObject() failed"); return; } // Fetch values. // // Most of the time, you can rely on the implicit casts. // In other case, you can do root["time"].as<long>(); if(root.containsKey("servo")) { positionServo = root["servo"][0]; speedServo = root["servo"][1]; // Print values. Serial.println(positionServo); Serial.println(speedServo); // myservo.write(positionServo, speedServo); //, true); // move to 180 degrees, use a speed of 30, wait until move is complete } else { Serial.println("parseObject() servo key not found"); } newData = false; } }
Arduino: Programme complet (JSON, relai, ventilo, LDR, DHT11, servo-moteur):
#include <VarSpeedServo.h> #include <ArduinoJson.h> #include "DHT.h" #define LDRPIN 0 #define DHTPIN 2 // Digital pin connected to the DHT sensor #define VENTILOPIN 7 #define RELAIPIN 8 #define SERVOPIN 9 #define DHTTYPE DHT11 // DHT 11 DHT dht(DHTPIN, DHTTYPE); VarSpeedServo myservo; unsigned long time; unsigned long diff; int ldrValue = 0; int relayState = LOW; int ventiloState = LOW; int positionServo = 0; int speedServo = 100; long checkDHT = 2000; // Serial reading buffer const byte numChars = 60; char receivedChars[numChars]; // an array to store the received data boolean newData = false; void recvWithEndMarker() { static byte ndx = 0; char endMarker = '\n'; char rc; while (Serial.available() > 0 && newData == false) { rc = Serial.read(); if (rc != endMarker) { receivedChars[ndx] = rc; ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // terminate the string ndx = 0; newData = true; } } } void setup() { pinMode(VENTILOPIN, OUTPUT); pinMode(RELAIPIN, OUTPUT); // relai, broche en mode sortie pinMode(SERVOPIN, OUTPUT); time = millis(); dht.begin(); myservo.attach(9); // attaches the servo on pin 9 to the servo object Serial.begin(9600); newData = false; } void loop() { StaticJsonBuffer<120> jsonBuffer; recvWithEndMarker(); if (newData == true) { JsonObject& root = jsonBuffer.parseObject(receivedChars); if (!root.success()) { Serial.println("parseObject() failed"); receivedChars[0] = '\0'; return; } if(root.containsKey("servo")) { positionServo = root["servo"][0]; speedServo = root["servo"][1]; myservo.write(positionServo, speedServo, true); } if (root.containsKey("ventilo")) { int ventiloValue = root["ventilo"]; if (ventiloValue == 1) { ventiloState = HIGH; } else { ventiloState = LOW; } } if (root.containsKey("relai")) { int relaiValue = root["relai"]; if (relaiValue == 1) { relayState = HIGH; } else { relayState = LOW; } } else { Serial.println("parseObject() servo key not found"); } newData = false; } diff = millis() - time; if (diff >= checkDHT) { time = millis(); float h = dht.readHumidity(); float t = dht.readTemperature(); // read the value from the sensor: ldrValue = analogRead(LDRPIN); Serial.print("{\"hum\":"); Serial.print(h); Serial.print(",\"temp\":"); Serial.print(t); Serial.print(",\"ldr\":"); Serial.print(ldrValue); Serial.println("}"); } // set the relay: digitalWrite(RELAIPIN, relayState); // set the ventilo: digitalWrite(VENTILOPIN, ventiloState); }
Nodered flow
[{"id":"3d2aea77.badaf6","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"3f949c8b.e9662c","type":"serial in","z":"3d2aea77.badaf6","name":"Arduino liaison série","serial":"7934b4c5.a4c6ac","x":118.50001525878906,"y":105,"wires":[["58f6c8f2.f84108","ee8168db.c30cd8"]]},{"id":"58f6c8f2.f84108","type":"debug","z":"3d2aea77.badaf6","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":708.5,"y":70,"wires":[]},{"id":"ee8168db.c30cd8","type":"json","z":"3d2aea77.badaf6","name":"","property":"payload","action":"","pretty":false,"x":108.49998474121094,"y":204,"wires":[["47a6359d.a05d6c","ad8bab3b.6151e"]]},{"id":"47a6359d.a05d6c","type":"debug","z":"3d2aea77.badaf6","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":709.5,"y":162,"wires":[]},{"id":"ad8bab3b.6151e","type":"function","z":"3d2aea77.badaf6","name":"Récupérer Humidity","func":"msg.payload = msg.payload.hum;\nreturn msg;","outputs":1,"noerr":0,"x":156.50001525878906,"y":291,"wires":[["49353fa9.b11378","5aa63008.6e225"]]},{"id":"49353fa9.b11378","type":"ui_chart","z":"3d2aea77.badaf6","name":"","group":"6236518f.ee41e8","order":1,"width":0,"height":0,"label":"Humidité","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"10","removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":798.5,"y":274.9999694824219,"wires":[[],[]]},{"id":"5aa63008.6e225","type":"switch","z":"3d2aea77.badaf6","name":"Humidité >= 60","property":"payload.state","propertyType":"msg","rules":[{"t":"gte","v":"60","vt":"num"},{"t":"lt","v":"60","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":147.83338928222656,"y":384.333251953125,"wires":[["13b76f6c.0304c9"],["2c7f8898.6e7d38"]]},{"id":"3a206f96.153a9","type":"ui_button","z":"3d2aea77.badaf6","name":"","group":"6236518f.ee41e8","order":3,"width":0,"height":0,"passthru":true,"label":"Arrêter le ventilo","tooltip":"","color":"","bgcolor":"","icon":"","payload":"2","payloadType":"str","topic":"","x":512.8333740234375,"y":646.3333740234375,"wires":[[]]},{"id":"902a3c34.bdb6d","type":"serial out","z":"3d2aea77.badaf6","name":"Arduino sortie","serial":"7934b4c5.a4c6ac","x":822.833251953125,"y":400.16668701171875,"wires":[]},{"id":"e06793a6.3b1558","type":"ui_switch","z":"3d2aea77.badaf6","name":"","label":"Automatique","tooltip":"","group":"6236518f.ee41e8","order":4,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":328.8333740234375,"y":531.3333740234375,"wires":[["77a8e113.0544f"]]},{"id":"77a8e113.0544f","type":"switch","z":"3d2aea77.badaf6","name":"","property":"payload","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":551.8333740234375,"y":552.3333740234375,"wires":[[],[]]},{"id":"13b76f6c.0304c9","type":"function","z":"3d2aea77.badaf6","name":"Démarrer ventilo","func":"msg.payload = \"{\\\"ventilo\\\":1}\\n\"\nreturn msg;","outputs":1,"noerr":0,"x":371.8333740234375,"y":355.66668701171875,"wires":[["902a3c34.bdb6d"]]},{"id":"2c7f8898.6e7d38","type":"function","z":"3d2aea77.badaf6","name":"Arrêter ventilo","func":"msg.payload = \"{\\\"ventilo\\\":0}\\n\"\nreturn msg;","outputs":1,"noerr":0,"x":347.2833251953125,"y":437.73333740234375,"wires":[["902a3c34.bdb6d"]]},{"id":"7934b4c5.a4c6ac","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":true,"responsetimeout":"10000"},{"id":"6236518f.ee41e8","type":"ui_group","z":"","name":"Chambre","tab":"ad170f6e.de74f8","disp":true,"width":"6","collapse":false},{"id":"ad170f6e.de74f8","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]