Système Pick-to-Light WiFi Arduino MKR1000 – Projet 2
Composants et fournitures
| Arduino MKR1000 | × | 1 |
| LED (génériques) | × | 2 |
| Fils de connexion (génériques) | × | 1 |
| Bouton poussoir 12 mm SparkFun | × | 1 |
| Résistance 10 kΩ | × | 1 |
| Résistance 330 Ω | × | 4 |
| Plaque d'essai (breadboard) | × | 1 |
| Câble USB-A vers Micro-USB | × | 1 |
| Transistor NPN usage général | × | 1 |
À propos du projet
Ce second projet explore un système "pick-to-light" (prélèvement guidé par la lumière) utilisant le WiFi. Contrairement au premier projet qui était relié au PC par câble, celui-ci utilise le protocole UDP (User Datagram Protocol) pour la communication sans fil. De plus, il inclut un numéro de séquence dans la confirmation de prélèvement afin que le système sache jusqu'où l'opérateur a prélevé en cas de problème.
Étape 1 : Python 3.6+
Installer Python 3.6 ou supérieur depuis python.org.
Étape 2 : Bibliothèque socket Python
La bibliothèque socket pour UDP est déjà incluse dans Python.
Étape 3 : Arduino IDE
Télécharger l'Arduino IDE depuis arduino.cc ou utiliser l'éditeur web create.arduino.cc.
Étape 4 : Répertoire de travail Python
Lancer IDLE Python, taper import os puis os.getcwd() pour obtenir le répertoire de travail courant.
Étape 5 : Fichier de séquence CSV
Créer un fichier CSV (ex: sequence1.txt) dans le répertoire de travail avec un numéro de séquence (4 chiffres) et un numéro de bac séparés par une virgule.
Étape 6 : Communication série pour débogage
Le port série est utilisé dans le sketch Arduino pour afficher les messages sur le moniteur série.
Étape 7 : Script Python
Le script Python lit le fichier CSV ligne par ligne, envoie le numéro de séquence et le numéro de bac via UDP, puis attend l'acquittement de l'Arduino (le numéro de séquence du dernier bac prélevé). Si le numéro reçu ne correspond pas, le programme s'arrête avec un message d'erreur indiquant le numéro de séquence fautif.
Étape 8 : Sketch Arduino
Le sketch connecte le MKR1000 au WiFi, attend les données UDP du PC pour le prochain prélèvement, allume la LED correspondant au bac, surveille le bouton associé, et renvoie le numéro de séquence après confirmation.
Avec l'éditeur web Arduino, un onglet arduino_secrets.h est créé automatiquement pour y entrer le SSID et le mot de passe WiFi. Avec l'IDE de bureau, partir de l'exemple WiFiUdpSendReceiveString qui inclut déjà cet onglet.
Étape 9 : Câblage
Le câblage diffère du projet 1 car l'activation du WiFi sur le MKR1000 fait chuter la tension sur les broches 8 et 9. Un transistor NPN est utilisé pour contourner ce problème. Attention : vérifier que les résistances conviennent aux LED et au transistor, et câbler correctement pour éviter d'endommager l'Arduino.
Étape 10 : Test
Vérifier la connexion WiFi de l'Arduino, puis lancer le script Python (F5). La LED du bac 1 s'allume. Appuyer sur le bouton pour confirmer le prélèvement renvoie le numéro de séquence au programme Python qui vérifie et envoie la séquence suivante.
On peut tester l'échec de séquence en modifiant le code Arduino pour renvoyer un numéro fixe.
Conclusion
Le système fonctionne, est simple et facilement extensible. Des améliorations sont envisagées pour un futur projet 3.
Code
Sketch Arduino
#include <SPI.h>
#include <WiFi101.h>
#include <WiFiUdp.h>
const int OKbutton = 2;
const int Bin1 = 8;
const int Bin2 = 9;
String mydata = "";
String myseq = "";
int buttonPress = 0;
int status = WL_IDLE_STATUS;
#include "arduino_secrets.h"
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
int keyIndex = 0;
unsigned int localPort = 2390;
char packetBuffer[255];
char ReplyBuffer[5] = "";
String mystring;
WiFiUDP Udp;
void setup() {
Serial.begin(9600);
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
while (true);
}
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
Serial.println("Connected to wifi");
printWiFiStatus();
Serial.println("\nStarting connection to server...");
Udp.begin(localPort);
}
void loop() {
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
IPAddress remoteIp = Udp.remoteIP();
Serial.print(remoteIp);
Serial.print(", port ");
Serial.println(Udp.remotePort());
int len = Udp.read(packetBuffer, 255);
if (len > 0) packetBuffer[len] = 0;
Serial.println("Contents:");
Serial.println(packetBuffer);
String mystring(packetBuffer);
mydata = mystring.substring(4);
myseq = mystring.substring(0, 4);
Serial.println(mydata);
Serial.println(myseq);
while (mydata != "") {
if (mydata == "Bin1") {
digitalWrite(Bin1, HIGH);
digitalWrite(Bin2, LOW);
while (buttonPress != HIGH) {
buttonPress = digitalRead(OKbutton);
mydata = "";
}
digitalWrite(Bin1, LOW);
Serial.println("Picked");
buttonPress = 0;
delay(1000);
}
if (mydata == "Bin2") {
digitalWrite(Bin2, HIGH);
digitalWrite(Bin1, LOW);
while (buttonPress != HIGH) {
buttonPress = digitalRead(OKbutton);
mydata = "";
}
digitalWrite(Bin2, LOW);
Serial.println("Picked");
buttonPress = 0;
delay(1000);
}
}
myseq.toCharArray(ReplyBuffer, 5);
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
Serial.println(ReplyBuffer);
}
}
void printWiFiStatus() {
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
Script Python
import csv
import socket
import time
import sys
UDP_IP = "192.168.1.119"
UDP_PORT = 2390
print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
time.sleep(5)
with open('sequence1.txt') as csvDataFile:
csvReader = csv.reader(csvDataFile)
for row in csvReader:
myseq = row[0]
mystate = row[1]
myrow = row[0] + row[1]
print("Current sequence being picked", myseq, "from", mystate)
sock.sendto(bytes(myrow, "utf-8"), (UDP_IP, UDP_PORT))
data = ""
while data == "":
(data, addr) = sock.recvfrom(1024)
mytest = data.decode("utf-8")
print("picked =", mytest)
if mytest != myseq:
print("there is a sequence fault at sequence", mytest)
sys.exit()
Fichier de séquence
0001,Bin1
0002,Bin2
0003,Bin1
0004,Bin2
0005,Bin1
0006,Bin2
0007,Bin1
0008,Bin2
0009,Bin1
0010,Bin2
0011,Bin1
0012,Bin2
0013,Bin1
Schémas
Fichier Fritzing : picktolightudp_OCbpNt9XPK.fzz
Processus de fabrication
- Les lanternes à gaz : évolution, conception et fabrication moderne
- Pointeur laser : conception, fabrication et aperçu de la sécurité
- Lampe Torche : De l'Invention à l'Innovation Moderne
- Le kaléidoscope : de la science de Brewster au design moderne
- Lasers à semi-conducteurs : Génération de lumière de précision pour la technologie moderne
- L'art et la science des procédés photographiques : du daguerréotype au film moderne
- Feux de signalisation : ingénierie, histoire et innovations futures
- Du Feu au Filament : L'Évolution et la Production de l'Ampoule Moderne
- Médiator Motorisé et Pédale d'Effet DIY – Impression 3D et Arduino