Magneto-Car
Ce projet a été réalisé au cours de la deuxième session de l’inter-semestre 2015, par : Likuang Yang, Reda affane et Hatim Tbez.
L’objectif de ce projet est de pouvoir télécommander un robot (une voiture) par de simples gestes de la main. La conception et la réalisation de ce projet a porté sur deux grandes parties :
La voiture : Un robot de type Arduino, muni d’une interface Bluetooth lui permettant de recevoir les directives de la part du système de commande, conçu sous forme d’un gant.
Le système de commande : Muni de capteurs de flexions, ce système permet de capter 4 mouvements différents de la main, et de les envoyer à travers l’interface Bluetooth vers la voiture. Chacun des 4 mouvements de la main ordonne à la voiture soit d’avancer, de freiner, de tourner à droite ou de tourner à gauche.
Voici un schéma récapitulant le fonctionnement de notre prototype:
Matériel utilisé:
- 2 cartes Arduino Uno
- 2 bornes Bluetooth BlueSMiRF
- Support de voiture ( 2 moteurs, 4 roues, châssis…)
- 2 BreadBoard
- 2 batteries
- Fils de connexions
Montage du système de commande:
Code:
Le code du système de commande est le suivant:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
int r=0;
int v=A1;
int w=A2;
int capa=0;
int capb=0;
const int shreshhold=630;
const int s1=690;
const int s2=810;
const int numReadings = 10;
int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
mySerial.begin(9600);
pinMode(v, INPUT);
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;
}
void loop() // run over and over
{ total= total – readings[index];
// read from the sensor:
readings[index] = analogRead(w);
// add the reading to the total:
total= total + readings[index];
// advance to the next position in the array:
index = index + 1;
// if we’re at the end of the array…
if (index >= numReadings)
// …wrap around to the beginning:
index = 0;
// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
capb=average;
capa=analogRead(v);
Serial.println(capb);
if (capa<shreshhold){
if (capb<s1){
mySerial.println(52);
Serial.println(« droit »);
}else if(capb>s2){
mySerial.println(53);
Serial.println(« gauche »);}
else {
mySerial.println(49);
Serial.println(« avance »);
}
}
else{
mySerial.println(51);Serial.println(« arete »);
}
delay(100);
}
Timetable Corner
Timetable Corner
Ce projet a été réalisé pendant la deuxième semaine d’intersemestre 2015 au Téléfab par Mina HE, Axel BAUDOT, Huu Trung THIEU et Tianshu YANG.
Constat
Pour les élèves de Télécom Bretagne, consulter leurs emplois du temps est fastidieux : le retrouver sur internet implique de s’authentifier, et de suivre de nombreux liens avant de trouver l’information qu’ils cherchent.
Cela est d’autant plus génant lorsque l’on souhaite savoir à la dernière minute (voire complètement en retard) dans quelle salle on doit se rendre.
Concept
Nous avons souhaité réaliser une borne qui, au passage du badge d’un élève, afficherait l’horaire et la salle de son prochain cours, et ce en accord avec les dernières informations disponible sur le site de l’école. C’est le Timetable Corner
Réalisation
Le lecteur de badge réalisé à partir d’une carte Arduino Uno utilise la technologie RFID/NFC pour identifier le badge.
L’école met à disposition des élèves un lien pour télécharger un emploi du temps au format iCalendar (.ics), à condition de posséder une clé pour identifier l’élève et accéder à son propre emploi du temps, sans besoin d’authentification. Un site web nous permet de stocker les profils des élèves, avec leurs identifiants de badges et de logiciel d’emploi du temps. Une fois que l’élève s’y est enregistré, le site sera capable de récupérer son prochain cours directement sur le site de l’école. Pour connaître son identifiant RFID, un élève peut passer son badge à la borne.
Au passage d’un badge, le circuit Arduino, muni d’une connection internet, envoie l’identifiant RFID du badge vers notre serveur, qui récupèrera sur les informations sur le site de l’école avant de les renvoyer vers le boîtier.
Le prochain cours est ensuite affiché sur un petit écran LCD.
La réalisation de ce projet a nécessité le recours au matériel suivant :
- Une carte Arduino
- Arduino ethernet board
- MicroRWD MF LP module
- Une 1uH antenne
- Un écran LCD
- RTC module
- Des LED
- Un buzzer
- Une résistance de 100 Ω
- Des fils
- Une breadboard
- Deux résistances de 1kΩ
La partie NFC lecteur :
Pour lire les tags RFID, nous utilisons un module Micro RWD, dont la datasheet est disponible ici → http://www.ibtechnology.co.uk/pdf/MFprot_LP.PDF.
Nous avons réalisé le montage ci-dessous et l’avons relié à notre Arduino Uno qui pouvait ensuite récupérer les identifiants RFID des tags passés devant l’antenne.
Nous ne disposions pas d’une antenne de 1μF, mais avons pu en imprimer une dans le département micro-ondes de Télécom Bretagne. La partie suivante détail le procédé.
Fabrication de l’antenne :
Nous avons bénéficiés de techniques quasi-industrielles pour réaliser notre antenne. Une méthode plus accessible est expliquée ici → http://www.instructables.com/id/RFID-Reader-Detector-and-Tilt-Sensitive-RFID-Tag/step2/Building-the-RFID-Antenna/
Pour imprimer notre antenne, nous avons commencé par en déterminer les dimensions et la forme grâce au logiciel antenna, qui calcule immédiatement l’inductance de l’antenne possédant les propriétés géométriques données.
Une exemple de géométrie permettant d’obtenir 1μF est représenté sur la figure : une bande de 1mm de diamètre enroulé en deux spires rectangulaires de 67mm sur 40mm. 1mm d’espace entre les deux spires.
On commence par découper un masque opaque représentant notre antenne. On en couvre une plaque comportant une couche de cuivre couverte de résine.
En passant le tout sous des UVs, la résine qui n’est pas couverte par le masque va être dégradée tandis que le reste reste intacte.
Un bain permet de retirer la résine dégradée. Reste une couche de cuivre, de la résine couvrant uniquement la forme de notre antenne.
En pulvérisant un produit sur la plaque, on peut retirer le cuivre ainsi dévoilé. Un dernier bain permet de retirer la résine restante et d’obtenir le motif de cuivre désiré.
Code arduino pour lire l’identifiant du badge :
#include<SoftwareSerial.h> int rx=10; int tx=11; SoftwareSerial S4(rx,tx); int CTS=8; int pin2=12; char msg; byte message; byte message2; int s4read; int s4available; int controle=0; int id[5]; int z=0; void Lire(){ s4read=S4.read(); s4available=S4.available(); Serial.print("S4.available()"); Serial.println(s4available); Serial.print("S4.read()"); Serial.println(s4read); } void Wait() { while (digitalRead(CTS)!=0) { } } void setup() { pinMode(CTS,INPUT); pinMode(pin2,INPUT); Serial.begin(9600); S4.begin(9600); delay(200); message=B01010101; message2=B01010011; Serial.println(digitalRead(CTS)); Lire(); Wait(); S4.write(message); Lire(); Wait(); S4.write(message2); Lire(); } void loop() { //if (Serial.available()>0) if (digitalRead(pin2)==0) { msg='U'; // msg=Serial.read(); //Serial.print("msg=:"); //Serial.println(msg); Wait(); S4.write(msg); } while (S4.available()>0) { s4read=S4.read(); delay(10); s4available=S4.available(); if (controle<5) { id[controle]=s4read;} controle++; if (controle==5){ Serial.println("id:"); for (z=1;z<5;z++) { Serial.print(id[z],HEX); } Serial.println(); } } controle=0; id[0]=0;id[1]=0;id[2]=0;id[3]=0;id[4]=0; }
Code arduino de l’affichage :
/* created 28 Jan 2015 by THT */ //-------------include h file----------- #include <SPI.h> #include <Ethernet.h> #include <LiquidCrystal.h> #include <Wire.h> #include <Time.h> #include <DS1307RTC.h> //-------------------------------------- //------------global variables----------- //------------variables for web //Mac address byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x1C, 0xEA }; // IP address of the server IPAddress server(10,29,224,28); // Set the static IP address to use if the DHCP fails to assign IPAddress ip(192,168,0,177); // Initialize the Ethernet client library with the IP address and port of the server that you want to connect to (port 80 is default for HTTP): EthernetClient client; // Data receive String data; //--------------------variables for showing /* initialize the library with the numbers of the interface pins of LCD The circuit: * LCD RS pin to digital pin 3 * LCD Enable pin to digital pin 2 * LCD D4 pin to digital pin 6 * LCD D5 pin to digital pin 7 * LCD D6 pin to digital pin 8 * LCD D7 pin to digital pin 9 * LCD R/W pin to ground */ LiquidCrystal lcd(3, 2, 6, 7, 8, 9); String errorl1 = "Inscrivez-vous en ligne votre identifiant: "; //String errorl2 = " sur notre site nextclass.resel.fr"; String errorl2 = "nextclass.resel.fr"; // ID of the student, from rfid int ID_student; // information String date_classe; String hour_classe; String Lname = "THIEU"; String room = "B03-042"; String classes = "Projet fil rouge"; //data receive from rfid String data_rfid = ""; //-------------------------------------- //---------------functions-------------- //clear one row on LCD void clear_row(LiquidCrystal lcd, int row){ lcd.setCursor(0,row); lcd.print(" "); } //show class's infomation on LCD void show_data(){ lcd.clear(); lcd.setCursor(0,0); lcd.print("Votre prochain "); lcd.setCursor(0,1); lcd.print("cours: "); delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print(date_classe); lcd.setCursor(0,1); lcd.print(hour_classe); delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Nom: "); lcd.print(Lname); lcd.setCursor(0,1); lcd.print("Salle: "); lcd.print(room); delay(2000); clear_row(lcd,1); lcd.setCursor(0,1); lcd.print("Cours: "); lcd.print(classes); delay(2000); for(int i = 6; i>=0 ;i--){ clear_row(lcd,1); lcd.setCursor(i,1); lcd.print(classes); delay(500); } for(int i = 1; i <= classes.length(); i++){ clear_row(lcd,1); delay(50); lcd.setCursor(0,1); lcd.print(classes.substring(i)); delay(500); } date_classe = ""; hour_classe = ""; Lname = ""; room = ""; classes = ""; } //show day on LCD void show_time_day(int day, int month, int year){ clear_row(lcd,1); lcd.setCursor(0,1); if (day < 10){ lcd.print("0"); lcd.print(day); } else lcd.print(day); String month_char; switch(month){ case 1: month_char = "Janvier"; break; case 2: month_char = "Fevrier"; break; case 3: month_char = "Mars"; break; case 4: month_char = "Avril"; break; case 5: month_char = "Mai"; break; case 6: month_char = "Juin"; break; case 7: month_char = "Juiller"; break; case 8: month_char = "Aout"; break; case 9: month_char = "Septembre"; break; case 10: month_char = "Octobre"; break; case 11: month_char = "Novembre"; break; case 12: month_char = "Decembre"; break; } lcd.print("-"); lcd.print(month_char); lcd.print("-"); //lcd.print("20"); lcd.print(year); } //show time on LCD void show_time_hour(int minute, int hour, int sec){ clear_row(lcd,0); lcd.setCursor(0,0); if (hour < 10){ lcd.print("0"); lcd.print(hour); } else lcd.print(hour); lcd.print(":"); if (minute < 10){ lcd.print("0"); lcd.print(minute); } else lcd.print(minute); lcd.print(":"); if (sec < 10){ lcd.print("0"); lcd.print(sec); } else lcd.print(sec); } //get time and print time void get_print_time(){ tmElements_t tm; //get time if (RTC.read(tm)) { show_time_hour(tm.Minute,tm.Hour,tm.Second); show_time_day(tm.Day,tm.Month,tmYearToCalendar(tm.Year)); } else { if (RTC.chipPresent()) { Serial.println("The DS1307 is stopped. Please run the SetTime"); Serial.println("example to initialize the time and begin running."); Serial.println(); } else { Serial.println("DS1307 read error! Please check the circuitry."); Serial.println(); }}} //setIP void setIP(){ Serial.println("Setting IP"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Setting IP ..."); if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // no point in carrying on, so do nothing forevermore: // try to congifure using IP address instead of DHCP: Ethernet.begin(mac, ip); } // give the Ethernet shield a second to initialize: delay(1000); Serial.println("Setting IP finished"); lcd.setCursor(0,0); lcd.print("Setting IP finished"); delay(1000); } //get data from server boolean get_data(String rfid){ lcd.clear(); delay(100); lcd.setCursor(0,0); lcd.print("Connecting..."); char c,c_old; String data=""; int count=1; boolean flag = false; //connect to server Serial.println("connecting..."); if (client.connect(server, 80)) { Serial.println("connected"); // Make a HTTP request: //client.println("GET /?id=badge&pass=badgeedt&url=http://www.google.fr/search?q=arduino"); client.print("GET /?id=badge&pass=badgeedt&url=http://nextclass.resel.fr/next_course.php?rfid="); client.println(rfid); client.println("Host: 10.29.224.28"); client.println("Connection: close"); client.println(); } else { // kf you didn't get a connection to the server: Serial.println("connection failed"); } //connect successfully while (count <6){ if (client.available()) { c = client.read(); if (c == '#'){ if (c_old == '#'){ lcd.clear(); /* for(int i=15; i>=0; i--){ lcd.setCursor(i,0); lcd.print(errorl1); delay(500); } */ for(int i=0; i<= errorl1.length()-16; i++){ clear_row(lcd,1); delay(50); lcd.setCursor(0,0); lcd.print(errorl1.substring(i,i+16)); delay(500); } lcd.setCursor(0,1); lcd.print(rfid); delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print("sur le site"); lcd.setCursor(0,1); lcd.print(errorl2); delay(1500); lcd.setCursor(0,1); lcd.print("extclass.resel.fr"); delay(1500); lcd.setCursor(0,1); lcd.print("xtclass.resel.fr"); delay(1500); client.stop(); return false; /* Serial.print(errorl1); Serial.print(rfid); Serial.println(errorl2); client.stop(); return false; */ } //delay(10); switch(count){ case 1: Serial.println(data); date_classe = data; //Serial.print("date_classe "); //Serial.println(date_classe); delay(10); break; case 2: Serial.println(data); hour_classe = data; //Serial.print("hour_classe "); //Serial.println(hour_classe); delay(10); break; case 3: Serial.println(data); room = data; //Serial.print("room "); //Serial.println(room); delay(10); break; case 4: Serial.println(data); Lname = data; //Serial.print("Lname "); //Serial.println(Lname); delay(10); break; case 5: Serial.println(data); classes = data; //Serial.print("classes "); //Serial.println(classes); delay(10); break; } count++; data=""; c_old=c; } else{ data +=c; c_old=c; } } // if the server's disconnected, stop the client: if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); //client.stop(); break; } } client.stop(); return true; } //-------------------------------------- void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } // set up the LCD's number of columns and rows: lcd.begin(16, 2); // start the Ethernet connection: setIP(); Serial.println("Welcome to our application"); Serial.println("Visite us at nextclass.resel.fr"); } void loop() { //Serial.println("a"); char data_temp; int count = 0; if((Serial.available() >0) && (count == 0)){ data_temp = Serial.read(); lcd.clear(); delay(100); data_rfid += data_temp; count++; lcd.setCursor(0,0); lcd.print("Votre ID: "); lcd.setCursor(0,1); lcd.print(data_rfid); //Serial.print("data_temp "); //Serial.println(data_temp); /* if (data_temp < 58) data_temp = data_temp - 48; else data_temp = data_temp - 55; */ //Serial.println(data_rfid); while (count < 8){ if(Serial.available() >0){ data_temp = Serial.read(); //Serial.print("data_temp "); //Serial.println(data_temp); /* if (data_temp < 58) data_temp = data_temp - 48; else data_temp = data_temp - 55; */ //data_rfid = (data_rfid <<4) + data_temp; data_rfid +=data_temp; count++; //Serial.println(data_rfid); lcd.setCursor(0,1); lcd.print(data_rfid); } } lcd.setCursor(0,1); lcd.print(data_rfid); delay(2000); if(get_data(data_rfid)){ Serial.print("Jour: "); Serial.println(date_classe); Serial.print("Temps: "); Serial.println(hour_classe); Serial.print("Nom: "); Serial.println(Lname); Serial.print("Salle: "); Serial.println(room); Serial.print("Coures: "); Serial.println(classes); show_data(); } count =0; data_rfid=""; } else{ get_print_time(); /* lcd.clear(); delay(100); lcd.setCursor(0,0); lcd.print("Welcome to TB"); lcd.setCursor(0,1); lcd.print("nextclass.resel.fr"); delay(1000); lcd.setCursor(0,1); lcd.print("extclass.resel.fr"); delay(1000); lcd.setCursor(0,1); lcd.print("xtclass.resel.fr"); delay(1000); */ } } <pre>
Le site web: http://nextclass.resel.fr/
Voici la clé ADE qu’on demande pour s’inscrire.
Il est demandé à l’élève de s’inscrire sur un site web, afin que nous puissions connaître l’identifiant RFID de son badge, et la clé nous servant à accéder à son emploi du temps.
Lorsqu’un élève passe son badge, une requête est envoyé vers notre site, comportant le RFID du badge passé. Une base de donnée associant RFID et clé élève nous permet de récupérer l’emploi du temps de l’étudiant au format iCalendar (.ics).
Le site traite ce fichier, en extrait le prochain cours, et renvoie une réponse vers le boîtier sous le format : date#heure de début-heure de fin#nom de l’élève#intitulé du cours
Un projet de parseur iCalendar en PHP est disponible ici : https://code.google.com/p/ics-parser/
Conclusion et perspectives
Le Timetable corner permet de consulter son prochain cours d’un seul geste.
Reste à rendre l’enregistrement du badge un peu moins fastidieux, peut-être via une application Android et la fonction de lecteur NFC de nos smartphones ?
HEARTWATCH
Abstract—L’article suivant fournit un aperçu de la construction d’un prototype conçu pour représenter le rythme cardiaque sur une diode électroluminescente (LED). L‘objet a été conçu dans les locaux de Télécom Bretagne, en collaboration avec les étudiants de L’ESAB. L’objectif est de déterminer les événements cardiaques via un récepteur de pulsations, et le signal recueilli doit être analysé et traité par un microcontrôleur Arduino MINI. Dans les lignes suivantes, nous détaillerons les mesures prises pour atteindre l’objectif du projet. En commençant par une introduction dans laquelle les bases sont discutées pour analyser les battements, suivis par la mise en œuvre technique ainsi que les matériaux utilisés pour fabriquer le dispositif. Enfin, la conclusion des travaux ainsi que des recommandations pour de futures améliorations apportées au prototype inclus sont abordées
I. INTRODUCTION
Le signal d’impulsion cardiaque qui sort d’un est une fluctuation de la tension analogique, et il a une forme d’onde prévisible . La représentation de l’onde de pouls est appelé photopléthysmogramme ou PPG. Le Capteur de Pouls Amped, amplifie le signal cardiaque brut, et normalise l’onde de pouls autour de V / 2 (point médian de la tension). . Le Capteur de Pouls Amped répond aux changements relatifs à l’intensité lumineuse. Si la quantité de lumière incidente sur le capteur reste constante, la valeur du signal restera à (ou à proximité) 512 (milieu de gamme ADC). Plus de lumière, plus le signal monte. Moins de lumière, le contraire. La lumière de la LED verte qui represente les changements de capteurs pendant chaque impulsion.
L’objectif est de trouver des moments successifs et instantanés du rythme cardiaque et mesurer le temps entre eux. En suivant la forme prévisible et modèle de la vague PPG, il est possible de faire exactement cela.
Lorsque le cœur pompe le sang dans le corps, à chaque battement il y a une vague d’impulsion (un peu comme une onde de choc) qui se déplace le long de toutes les artères jusqu’aux extrémités de tissu capillaire où le capteur d’impulsion est fixé. Le sang circule réellement dans le corps beaucoup plus lent que l’onde de pouls se déplace. Une augmentation rapide à la hausse de la valeur du signal se produit que l’onde de pouls passe sous le capteur, le signal retombe vers le point normal. Parfois, l’encoche dichroïque (pic vers le bas) est plus prononcé que d’autres, mais en général, le signal s’installe au bruit de fond avant la prochaine vague d’impulsion lave travers. Depuis la vague se répète et prévisible, nous pourrions choisir ne importe quel élément reconnaissable comme un point de référence, dire le pic, et de mesurer la fréquence cardiaque par faire des mathématiques sur le temps entre chaque pic. Voir l’image ci-dessous
II. IMPLENTATION TECHNIQUE
Pour faire le pouls cardiaque détecteur prototype, ont été utilisés les composants suivants :
-
Une LED verte (Sortie 13).
-
Une LED blanche (Sortie 5).
-
Un circuit intégré Arduino MINI.
-
2 Piles de 3Volts connectées en série pour l’alimentation du circuit.
-
Un capteur de pouls Amped(TTL-232r-5V)
Le capteur de pulses est connecté au microcontrôleur Arduino, qui a été programmé avec le code comme indiqué ci-dessous :
Tout d’abord, il est important d’avoir un taux d’échantillon disponible avec résolution suffisamment élevée pour obtenir une mesure fiable de la synchronisation entre chaque battement. Pour ce faire, nous avons mis en place Timer2, une minuterie de 8 bits, de sorte qu’il effectue une interruption toutes les deux millisecondes. Ce qui nous donne un taux de 500 Hz de l’échantillon, et beat-pour-beat résolution temporelle de 2 ms.
void interruptSetup(){ TCCR2A = 0x02; TCCR2B = 0x06; OCR2A = 0x7C; TIMSK2 = 0x02; sei(); }
Les paramètres de registre ci-dessus indiquent Timer2 pour passer en mode CTC, et comptent jusqu’à 124 (0x7C) encore et encore et encore. Un diviseur de 256 est utilisé pour obtenir le bon moment pour qu’il prenne deux millisecondes à compter jusqu’à 124. Un indicateur d’interruption est réglé chaque fois Timer2 atteint 124, et une fonction spéciale appelée un programme d’interruption (ISR) que nous avons écrit est exécuté au moment suivant possible, peu importe ce que le reste du programme est en train de faire. sei () assure que les interruptions mondiaux sont activés.
Ainsi, lorsque l’Arduino est sous tension et en cours d’exécution avec capteur tactile Amped branché sur la broche analogique 0, il lit la valeur de capteur toutes les 2 ms et cherche l’instant du battement de cœur. Voici comment ça fonctionne:
ISR(TIMER2_COMPA_vect){
Signal = analogRead(pulsePin);
sampleCounter += 2;
int N = sampleCounter – lastBeatTime;
Cette fonction est appelée toutes les 2 millisecondes. La première chose à faire est de prendre une lecture analogique du capteur d’impulsions. Ensuite, on incrémente la variable sampleCounter. La variable sampleCounter est ce que nous utilisons pour garder une trace du temps. La variable N permettra d’éviter le bruit après.
Ensuite, nous suivons les valeurs les plus élevées et exclusive de la vague PPG, pour obtenir une mesure précise de l’amplitude.
if(Signal < thresh && N > (IBI/5)*3){
if (Signal < T){
T = Signal;
}
}
if(Signal > thresh && Signal > P){
P = Signal;
}
Les variables P et T designent les valeurs maximales et minimales, respectivement. La variable thresh est initialisée à 512 (milieu de gamme analogique) et des changements lors de l’exécution de suivre un point à 50% d’amplitude comme nous le verrons plus tard. Il ya une période de temps de 3/5 IBI qui doit se écouler avant T est mis à jour comme un moyen d’éviter le bruit et les fausses lectures de l’encoche dichroïque.
Maintenant, permet de vérifier et voir si nous avons une impulsion.
if (N > 250){ if ( (Signal > thresh) && (Pulse == false) && (N > ((IBI/5)*3) ){ Pulse = true; digitalWrite(pulsePin,HIGH); IBI = sampleCounter - lastBeatTime; lastBeatTime = sampleCounter;
Avant nous considérons même à la recherche d’un battement de cœur, un certain minimum de temps doit passer. Cela permet d’éviter le bruit haute fréquence. 250 millisecondes minimum N impose une limite supérieure de 240 BPM. Lorsque la forme d’onde depasse la valeur de battement, et 3/5 de la dernière IBI a passé, nous avons une impulsion! C’est alors le moment pour définir le drapeau d’impulsion et allumer le voyant pulsePin. Ensuite, nous calculons le temps écoulé depuis le dernier temps pour obtenir IBI, et d’actualiser les lastBeatTime.
Le bit suivant est utilisé pour se assurer que nous commençons avec une valeur de BPM réaliste au démarrage.
if(secondBeat){
secondBeat = false;
for(int i=0; i<=9; i++){
rate[i] = IBI;
}
}
if(firstBeat){
firstBeat = false;
secondBeat = true;
sei():
return;
}
Le booléen Firstbeat est initialisée comme vrai et secondBeat est initialisée comme faux au démarrage, donc la première fois que nous trouvons un battement et obtenons aussi loin dans l’ISR au conditionnel Firstbeat. Cela va finir par ne pas prendre en compte la première lecture IBI. La seconde fois, nous pouvons faire confiance (plus ou moins) l’IBI, et l’utiliser pour ensemencer le rate[] tableau afin de commencer avec un BPM plus précis. Le BPM est dérivée d’une moyenne des 10 dernières valeurs d’IBI, la nécessité de graines.
word runningTotal = 0;
for(int i=0; i<=8; i++){
rate[i] = rate[i+1];
runningTotal += rate[i];
}
rate[9] = IBI;
runningTotal += rate[9];
runningTotal /= 10;
BPM = 60000/runningTotal;
QS = true;
}
}
Tout d’abord, on récupère une grande variable runningTotal, pour recueillir les IBIs, alors le contenu de rate[] sont décalés plus et ajoutés à runningTotal. La plus ancienne IBI (il ya 11 battements) tombe sur la position 0, et l’IBI frais se met en position 9. Ensuite, c’est un processus simple pour la moyenne de la gamme et de calculer le BPM. La dernière chose à faire est de mettre le drapeau de QS (abréviation de Quantified Self). De sorte que le reste du programme sait que nous avons trouvé le rythme. C’est tout pour la chose à faire lorsque nous trouvons le rythme.
Il y a une couple d’autres bouts qui doivent attacher avant que nous aurons terminé, comme trouver le pas-beat.
if (Signal < thresh && Pulse == true){
digitalWrite(13,LOW);
Pulse = false;
amp = P – T;
thresh = amp/2 + T;
P = thresh;
T = thresh;
}
Pulse a été déclaré vrai lors de la montée vers le haut dans le signal de capteur d’impulsion quand nous avons trouvé le rythme, ci-dessus, de sorte que lorsque le signal passe thresh descendant, nous pouvons comprendre que l’impulsion est terminée. Un peu de ménage dans l’élimination pulsePin et le booléen d’impulsion. Puis l’amplitude de l’onde qui vient de passer est mesurée, et foule est mis à jour avec la nouvelle marque de 50%. P et T sont remis à la nouvelle thresh. L’algorithme est maintenant amorcée et prêt à trouver le temps suivant.
if (N > 2500){
thresh = 512;
P = 512;
T = 512;
firstBeat = true;
secondBeat = false;
lastBeatTime = sampleCounter;
}
S’il n’y a aucun événement de battement pour 2,5 secondes, variables utilisées pour trouver le rythme cardiaque sont réinitialisés aux valeurs de démarrage. Une sorte de soft-reset doux. C’est la fin de l’ISR.
En utilisant Timer2 interrompre, nos algorithme de recherche fonctionnent « en arrière-plan » et met à jour automatiquement les valeurs des variables.
Une fois le programme compilé, nous telechargeons l’executable sur l’arduino. Pour ce faire, nous devons passer par un convertisseur entre le cable lié au port serie du PC d’une part et l’arduino d’autre part. Le montage à effectuer coorespond au schema ci-dessous:
Figure2: Montage du circuit pour le telechargement de l’executable
Quand l’executable est mis sur l’arduino, nous pouvons enfin tester notre disposible en mesurant notre rythme cardiaque avant et apres avoir couru. Le resulat est coherent avec la prevision:
Figure3: Montage du dispositif avec une alimentation sur 2 piles montées en serie
Figure4: Test de simulation en mettant le capteur au doigt
III. MONTAGE ESTHETIQUE
Le tout doit loger dans un bracelet de poignet de telle sorte que les leds soient visibles et le capteur en contact avec la peau. Un schema a été defini d’abord à la main avant d’etre schematiqué avec un editeur d’image:
Figure5: Schema prevu pour le bracelet
Figure6: Schéma conceptuel du bracelet et liaison des fils
IV. CONCLUSION
Bildung
Ce projet a été réalisé pendant la première semaine d’intersemestre 2015 au Téléfab par Louis Frehring, Fady George Remila, Alizée Gerard, Anas Ihrboula, Julie Kelberine et Jean-Baptiste Rebuffi.
Résumé
Bildung est un système permettant de produire de la musique à l’aide de la détection du mouvement et de la position des mains.
Matériel utilisé
- un capteur à ultrasons (http://www.seeedstudio.com/wiki/Ultra_Sonic_range_measurement_module#Resources)
- un breadboard
- une carte Arduino
- des fils
- le Leap Motion (https://www.leapmotion.com/)
- une boîte en bois pour contenir le tout
Le système est relié à un Mac sur lequel fonctionne le logiciel Max.
Le lien suivant renvoie vers les sept fichiers de son de base et vers les deux fichiers Max, correspondant à deux versions différentes de Bildung: la première étant orientée vers la modulation du son et la deuxième étant plus musicale (https://github.com/BildungBox/Fichiers-Max).
Carte Arduino et capteur à ultrasons
Bildung replié
Bildung déployé
Test de Bildung
Fonctionnement
L’utilisateur utilise ses mains pour produire de la musique. Une première main permet de déclencher la musique ou de l’arrêter selon qu’elle se trouve ou non devant le capteur d’ultrasons. La deuxième main permet de moduler cette musique. Ainsi, en décalant cette main vers la gauche, on produit un son plus aigu tandis qu’il sera plus grave si on déplace sa main vers la droite. On peut de même contrôler le volume en levant sa main ou en la descendant. La pureté fréquentielle du son est gérée en avançant plus ou moins sa main (modification du facteur de qualité).
Capture d’écran du logiciel Max
Interface de réglage des paramètres de Bildung
Interface destinée à l’utilisateur
Code Arduino du capteur ultrason
#include "Arduino.h" class Ultrasonic { public: Ultrasonic(int pin); void DistanceMeasure(void); long microsecondsToCentimeters(void); long microsecondsToInches(void); private: int _pin;//pin number of Arduino that is connected with SIG pin of Ultrasonic Ranger. long duration;// the Pulse time received; }; Ultrasonic::Ultrasonic(int pin) { _pin = pin; } /*Begin the detection and get the pulse back signal*/ void Ultrasonic:istanceMeasure(void) { pinMode(_pin, OUTPUT); digitalWrite(_pin, LOW); delayMicroseconds(2); digitalWrite(_pin, HIGH); delayMicroseconds(5); digitalWrite(_pin,LOW); pinMode(_pin,INPUT); duration = pulseIn(_pin,HIGH); } /*The measured distance from the range 0 to 400 Centimeters*/ long Ultrasonic::microsecondsToCentimeters(void) { return duration/29/2; } /*The measured distance from the range 0 to 157 Inches*/ long Ultrasonic::microsecondsToInches(void) { return duration/74/2; } Ultrasonic ultrasonic(7); void setup() { Serial.begin(9600); } void loop() { long RangeInInches; long RangeInCentimeters; ultrasonic.DistanceMeasure();// get the current signal time; RangeInInches = ultrasonic.microsecondsToInches();//convert the time to inches; RangeInCentimeters = ultrasonic.microsecondsToCentimeters();//convert the time to centimeters // Serial.println("The distance to obstacles in front is: "); // Serial.print(RangeInInches);//0~157 inches // Serial.println(" inch"); // Serial.print(RangeInCentimeters);//0~400cm // Serial.println(" cm"); if(RangeInCentimeters <= 15 && RangeInCentimeters>=0 ){ Serial.println(1); Serial.println("\r") ; } else { Serial.println(0); Serial.println("\r") ; } delay(100); }
Améliorations possibles
Les valeurs des positions des doigts ou de la paume de la main renvoyées par Max ne sont pas très fiables, elles varient tout le temps, ce qui est assez restreignant lorsque l’on essaie d’assigner par exemple à un intervalle une fréquence donnée.
On pourrait rajouter des paramètres pour prendre en considération la capacité du Leap Motion à détecter le mouvement des doigts. Hélas, on se heurte là aussi à des problèmes de précision et de sensibilité.
Outre les défauts de conception et les imprécisions musicales, nous pouvons tenter d’améliorer notre maîtrise de cet instrument de musique assez particulier. Il est par exemple assez difficile de gérer à la fois l’activation et la désactivation de la musique grâce à une main et la modulation du son par l’autre main.
Music Air Play
Air Play Music
Auteurs :
– YANG Likuang
– El harem Hicham
– Idlimam Marwan
– KANTE Souleymane Cheick
I- Idée :
Vous vous êtes déjà demandés s’il serait intéressant de jouer de la musique juste avec le mouvement de la main ? Le projet Air Play Music vous apporte la réponse. Avec une grande simplicité, notre solution vous donne la possibilité de faire de musique un peu comme avec piano mais cette fois-ci selon le mouvement de votre main (dans l’air) dans un certain nombre d’endroits de l’espace entourant le dispositif.
II- Principe de fonctionnement :
Le principe de l’appareil repose sur la détection de la main de l’utilisateur et la détermination de la distance à laquelle elle se trouve, après quoi l’appareil joue une note correspondante à cette configuration.
III-Matériel utilisé :
– Des capteurs de proximité (Voir https://www.sparkfun.com/products/8959 ) : Pour pouvoir détecter un présence de même que la distance à la quelle elle se trouve avec un assez bonne précision. Les valeurs récoltées de ce capteur serviront à la prise de décision plus tard ;
– Un Controller Arduino (Voir http://arduino.cc/en/ ) : Pour pouvoir décider du type d’interaction pour tout le système afin de le rendre interactif. Là résidera l’action à proposer en fonction de chaque cas d’utilisation (en fonction des données du capteur) ;
- Un MP3 Shield relié à un haut parleur : Avec une carte mémoire sur la quelle chaque son dont nous auront besoin pour mener à bien le projet sera stocké sous forme de fichier mp3 d’un débit de 32 kbps. Ensuite il servira de support (de bonne qualité) pour émettre un son en particulier.La programmation de cette carte exige l’import de la bibliothèque Sparkfun MP3 Player Shield Arduino Library .
– D’autres matériaux secondaires : tels que des fils de connexion, des BreadBords, une planche pour supporter et stabiliser le dispositif et des leds pour montrer l’activation de l’un des capteurs.
III- Description détaillée du fonctionnement :
Comme expliqué précédemment le produit fonctionnera en trois étapes : récolte d’informations de proximité (par l’un des capteurs), détermination du cas d’utilisation et par conséquent de la note (Au niveau du Controller Arduino) et émission d’une note audible à la demande du Controller par le lecteur MP3.
Le produit développé est composé de 4 détecteurs ayant chacun deux zones de détection : 250 à 300 pour la zone lointaine et au-delà de 300 pour la zone proche.
A l’aide du Controller qui répète une serie d’actions à chaque 100 ms, on déterminera la position du capteur le plus proche de la main de l’utilisateur pour ensuite l’activer au besoin.
IV- Améliorations Possibles :
– Maîtrise du niveau sonore : possibilité d’ajuster le niveau du son (dans le programme Arduino puisque la fonctionnalité existe déjà dans les librairies qui permettent de manipuler le la carte MP3 Shield);
– Proposer plusieurs types d’instrument : proposer d’autres instruments de musique à l’instar du piano ;
– Ajouter une interface : des images qui changent en fonction de l’interaction et donnent un peu plus d’animation ;
LUMIDUINO
Constat et concept
Aujourd’hui, il existe de multiples effets de sons et lumières, pour agrémenter toutes les soirées. Le système réalisé porte le nom de lumiduino, c’est un système très visuel. Il permet d’afficher une luminosité, définie selon l’utilisateur, lors de la présence de sonorités aux alentours du capteur.
Il est composé d’un capteur et d’un néon. Le tout fonctionne par l’utilisation d’un Arduino et d’un code.
Technique
Pour réaliser ce système, j’ai utilisé une carte Aduino, un capteur et enfin un « ring neo-pixel ». J’ai élaboré le code pour me changement de luminosité selon la sonorité.
Perspectives d’améliorations
La synchronisation du changement de couleur peut être améliorée par l’amélioration du code existant. Enfin la création d’un boitier pour contenir le système sera intéressant pour pourvoir transporter le système.
Le code
#include <Adafruit_NeoPixel.h>
#define SOUND_SENSOR A0
#define PIN 6
#define NUMPIXELS 16
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin(); // This initializes the NeoPixel library.
Serial.begin(9600);
}
void loop()
{int sensorValue = analogRead(SOUND_SENSOR);//use A0 to read the electrical signal
Serial.print(« sensorValue « );
Serial.println(sensorValue);
If (250 >sensorValue )
{
for(int i=0;i<NUMPIXELS;i++){ // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(0,150,150)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(50); // Delay for a period of time (in milliseconds).
}
}
else if ( sensorValue > 250 && sensorValue < 500)
{
for(int i=0;i<NUMPIXELS;i++){ // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(250,100,0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(1); // Delay for a period of time (in milliseconds).
}
}
else if ( sensorValue > 500 && sensorValue < 700)
{
for(int i=0;i<NUMPIXELS;i++){ // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(0,200,0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay (5); // Delay for a period of time (in milliseconds).
}
}
else
{
for(int i=0;i<NUMPIXELS;i++) { // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(250,250,250)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(1); // Delay for a period of time (in milliseconds).
}
}
delay (100);
}
Synesthésia
Dans le cadre d’un intersemestre ayant pour thème la « musique ». Nous avons décidé de travailler sur la production de son à partir de la couleur de notre environnement. Bref de réaliser une impression de synesthésie.
Le groupe est composé de membre venant de l’EESAB et de TELECOM Bretagne ( Mathieu BARON , Mélinda BOUKHANA , Sisi CHEN , Xing LI , François NÉRON , Chloé TROUSSIER , Gabriel VAUDOUR ).
Nous avons créé à l’aide de MAX/MSP un programme permettant de déterminer la couleur d’une image et de jouer des notes en fonction de celle-ci. Nous avons aussi créer un tableau présentant une grande palette de couleur. Ainsi chacun pourra se placer devant la caméra et modifier les sons produit en obstruant certaines couleurs et en ajoutant les siennes.
Pour rendre l’ensemble plus visuel, on ajoute des lumières montrants les couleurs majoritaires dans les images qui sont jouées. A la fois sur l’écran de l’ordinateur et sur un ruban de LEDs
Partie Technique
I- Matériel
– logiciel Max/MSP
-une caméra (ici webcam intégrée à un ordinateur portable)
-un arduino
-un ruban à LED
-un câble USB (arduino)
-une capacité 220 μF
-une alimentation extérieur par câble
-fer à souder
-fils
II- Code
Nous nous sommes organisés en plusieurs modules :
-Détermination des couleurs présentes
-Traduction des données couleur en son
-Contrôle des LEDs
a. Détermination des couleurs présentes
Nous avons décidé de découper l’image filmée par la caméra en plusieurs bloc (ici 8) et de faire une moyenne sur ces blocs des coefficient de la coloration RVB (Rouge Vert Bleu). Afin de simplifier et de rendre plus rapide le traitement du flux continu d’image ainsi que d’éviter de nombreux sons trop proche entre eux.
Ensuite nous lisons les blocs de l’image dans un sens prédéterminé et produisons le son associé à chaque coefficient selon un traitement défini ci-dessus.
b. Traduction couleur son
Le mode de traitement des données est tout-à-fait subjectif et arbitraire. On a choisit d’associer chaque couleurs à un instrument puis chaque instrument à une note. Les instruments sont changés de façon aléatoire afin de nous préserver de la monotonie.
c. Contrôle des LEDs
On contrôle le ruban de LEDs avec Arduino
#include <Adafruit_NeoPixel.h>
#define PIN 6
char incomingByte[10];// for incoming serial data
int i = 0;
int red;
int green;
int blue;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(50, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show();
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte[i] = Serial.read();
i ++;
if (i==9){
for (int j = 0; j <9; j++){
Serial.println(incomingByte[j]);
if (j==8){
i=0;
}
}
red = (incomingByte[0]-48)*100+(incomingByte[1]-48)*10+(incomingByte[2]-48);
green = (incomingByte[3]-48)*100+(incomingByte[4]-48)*10+(incomingByte[5]-48);
blue = (incomingByte[6]-48)*100+(incomingByte[7]-48)*10+(incomingByte[8]-48);
Serial.println(« rouge »);
Serial.println(red);
Serial.println(« bleu »);
Serial.println(blue);
Serial.println(« vert »);
Serial.println(green);
colorWipe(strip.Color(red,green, blue), 20);
}
}
}
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
on utilise en parallèle l’écran de l’ordinateur qui affiche la couleur dominante sur chaque blocs.
III- Fabrication
a.Schéma de montage
On soude ensemble les fils le condensateur et l’alimentation du ruban de LEDs.
Les informations transmises par le logiciel MAX sont celles des 3 coefficients de couleur.
b. Décoration
Pour créer le tableau que nous utiliserons comme support de son, nous avons décider de créer un tableau qui présentera des zones de couleurs différentes. Nous nous sommes inspirés du haut parleur : de sa forme et de sa texture.
La sculpture est composée de carton et d’un grand papier. Elle a été peinte à la bombe. Les photos présentent plusieurs « tapes de sa construction.
Arduino sur FutureMag
Vous voulez découvrir arduino : son origine en Italie, son utilisation en collège ou au sein des fablabs, n’hésitez pas à regarder le reportage proposé par Arte.
Vous y verrez en particulier les activités des petits hackers proposées par la Maison du Libre au sein des Fabriques du Ponant.
Étoiles de Noël
C’est bientôt Noël ! Le moment parfait pour réaliser soi-même une guirlande électrique à mettre dans le sapin. Pour changer un peu des guirlandes électriques que l’on trouve dans le commerce, j’ai décidé de faire un guirlande de grands étoiles translucides, contenant chacune une LED multicolore par branche. Voici un aperçu du résultat en vidéo (en vertical désolé, mais sinon on n’aurait pas vu tout le sapin) :
Dans la vidéo, il n’y a qu’onze étoiles dans le sapin. L’objectif final est une guirlande de vingt étoiles mais le rendu est déjà sympa. Différents modes sont proposés : fixe blanc, changement de couleurs, clignotant blanc, fixe multicolore, scintillement blanc, rotation colorée des branches des étoiles, et flammes rouges et jaunes. Ce ne sont que des exemples, je n’ai pas encore eu beaucoup de temps pour programmer les effets.
Voici quelques photos détaillant la guirlande :
Si vous voulez construire une guirlande du même genre pour Noël, ce n’est pas très compliqué. Il suffit d’un peu de matériel, d’une imprimante 3D et de patience. Je détaille dans la suite comment j’ai fait ma guirlande, et ce que je compte améliorer.
Le matériel
Voici le matériel que j’ai utilisé pour construire cette guirlande :
- du plastique ABS transparent 1,5 mm (environ 500g) ;
- un ruban à LEDs Neopixel d’Adafruit de 2m avec 120 LEDs RGB (multicolores) contrôlables individuellement, PCB blanc ;
- 5m de câble 3G0,75mm noir pour la base de la guirlande ;
- 20m de câble RJ11 noir pour les branches vers les étoiles ;
- un Arduino Nano pour contrôler les LEDs ;
- une alimentation 5V 4A pour alimenter l’Arduino et les LEDs ;
- un gros condensateur pour protéger le ruban et l’Arduino.
Au niveau des outils, il faut une imprimante 3D et un poste de soudure.
L’étoile en plastique
L’étoile est entièrement réalisée à l’imprimante 3D. Le modèle a été dessiné sous OpenSCAD. Il est disponible sur Github, avec les fichiers STL exportés pour l’impression. Le fichier est paramétrable. Il est possible de modifier le nombre de branches ou la taille de l’étoile par exemple.
La pièce à imprimer se décompose en 3 parties, dont 2 identiques. Voici à quoi ça ressemble une fois imprimé :
L’étoile est faite de deux moitiés, qui s’emboitent sur un anneau central. Ceci permet de fermer simplement l’étoile en force. Je n’ai pas mis de colle, même s’il pourrait être utile d’en ajouter pour solidifier le tout. Il y a une encoche en bas de chaque demi-étoile pour laisser passer le fil électrique. Il y a aussi un petit trou en haut de chaque demi-étoile pour accrocher du fil de pêche qui servira à accrocher l’étoile au sapin. La partie circulaire au centre de l’étoile servira de support au ruban à LEDs.
J’ai imprimé toutes les pièces avec un remplissage de 100%. Le rendu visuel est différent avec un remplissage de 0%, plus transparent. Vous pouvez faire des tests.
Pour faire une guirlande complète, il faut imprimer 40 demi-étoiles et 20 anneaux, ce qui peut prendre du temps selon la rapidité de votre imprimante 3D…
Les LEDs et le câblage
La partie électronique dans chaque étoile est extrêmement simple et se compose uniquement d’un bout de ruban à LEDs contenant 5 LEDs. Les dimensions de l’étoile sont faites pour que les LEDs s’alignent toutes seules face à chaque branche de l’étoile. Voici à quoi ressemble l’intérieur d’une étoile : La seule chose à faire pour construire l’étoile est de souder sur le ruban le fil qui servira à faire une branche de la guirlande. Ce fil est du fil RJ11. J’ai découpé des morceaux de 70cm pour chaque étoile. L’intérêt du câble RJ11 est qu’il a 4 conducteurs : le noir est la masse, le rouge me sert de 5V, le vert me sert de « data in » et le jaune de « data out ». Le fil de données fait ainsi un aller retour : il arrive par le vert, traverse le ruban, et repart par le jaune. C’est ce qui permettra de contrôler indépendamment toutes les LEDs. Voici le circuit global de la guirlande :
La câble horizontal en bas est le câble 3G0,75mm et les câbles verticaux sont les câbles RJ11. Avec 20 étoiles, il y a 3 mètres de guirlande, avec une branche de 70cm qui part tous les 15 cm. Il est aussi possible d’ajouter 1 mètre de câble en début de guirlande pour éloigner le contrôleur et faciliter la mise en place dans le sapin.
La longueur et la section du câble sont importantes. Plus le câble est long, plus il doit avoir une large section (une faible résistivité) pour que la tension dans l’étoile la plus éloignée reste suffisante. De même, plus il y a d’étoiles, plus l’intensité qui traverse le fil est importante. C’est pourquoi j’utilise des fils très fins pour les branches et un gros câble pour le « tronc » de la guirlande. J’utilise cet outil en ligne pour estimer les sections à utiliser.
Pour souder le câble RJ11 au câble 3G0,75mm tous les 15cm, il suffit de dénuder un petit tronçon (2cm) du cable 3G0,75mm au cutter, puis de dénuder à des endroits différents le fil 5V et le fil de masse. On soude ensuite directement sur les parties dénudées. Il faut ensuite couper le troisième fil (données) et souder le fil vert du câble RJ11 du côté du contrôleur et le fil jaune de l’autre côté. Pour éviter des court-circuits, j’ai mis de la gaine thermo-rétractable sur les fils de données. J’ai ensuite enrobé le tout dans du scotch d’électricien noir pour isoler et cacher les fils.
Une précaution importante à prendre lors de la construction de la guirlande est que l’étoile la plus proche du contrôleur doit être faite d’un bout de ruban pris à un début de ruban. Tous les 50cm sur le ruban, il y a une soudure et une première LED avec une résistance de protection devant le « data in ». C’est une de ces LEDs qui doit être la première connectée au contrôleur.
Le contrôleur
Le contrôleur est simplement un Arduino Nano qui se situe en bout de guirlande (côté « data in »). Il envoie les commandes par le fil bleu vers les LEDs et peut contrôler chaque LED indépendemment.
Le circuit électronique est composé de l’Arduino Nano, d’un condensateur (2 en parallèle en fait) pour protéger l’alimentation, et d’une résistance d’1 MΩ servant de « pull-up » pour un bouton qui fonctionne au toucher. Le bouton sert à changer de mode d’affichage. J’ai soudé les composants sous forme d’un « shield » pour l’Arduino Nano, ce qui m’évite de le souder. Je n’ai pas encore fait de boitier pour le circuit, ni décidé comment je vais faire le bouton, ce qui explique les fils dans le vide :
Le programme est fait sous la forme d’une librairie pour contrôler les étoiles (Stars.h et Stars.cpp) et d’un sketch avec plusieurs modes d’affichage. Il est disponible sur Github et utilise la librairie NeoPixel d’Adafruit (à installer sur votre ordinateur). Les modes actuels sont assez basiques. Je compte les améliorer.
Améliorations
Plusieurs améliorations sont possibles à partir de ce premier jet :
- Faire un joli boitier pour le contrôleur.
- Coller les étoiles pour qu’elles tiennent mieux, ou concevoir un meilleur système de fixation.
- Améliorer les animations de la guirlande. L’Arduino Nano peut être utilisé pour faire des millions d’effets différents. je n’ai pas encore passé assez de temps là-dessus.
- Ajouter des capteurs pour faire réagir la guirlande à son environnement : le bruit, la lumière, la date ou l’heure pourraient faire changer les animations. Tout est possible !
- Ajouter une LED au centre de l’étoile. Je ne suis pas sûr de vouloir faire ça, mais certaines personnes me l’ont suggéré.
À vous !
Cette guirlande n’est pas très compliquée à construire. Il faut juste un peu de patience. Si vous en manquez, vous pouvez aussi construire une seule étoile, qui illuminera votre sapin. Même sans la partie électronique, l’étoile seule peut faire joli dans le sapin, et vous pouvez mettre n’importe quelle sorte de choses dedans.
Si vous faites évoluer l’idée, tenez-moi au courant !
Inauguration des Fabriques du Ponant
Le 20 septembre, dès 14h, les Fabriques du Ponant ouvrent leurs portes.
C’est l’occasion de venir faire la fête du numérique : des ateliers de découverte, de co-construction d’objets connectés, d’aménagements du lieu vous seront proposés.
Les activités pour les 9-17 « Les Petits Hackers » de la Maison du Libre seront aussi présentées à cette occasion.
N’hésitez pas à venir.