avrdude -C ..\etc\avrdude.conf -p m328p -c arduino -P COM5 -b 57600 -U flash:w:"c:\temp\find_i2c.ino.hex":i
J'ai choisi un composant compatible le SODIAL NANO V3.0 à moins de 2€ avec le cable.
Même en cas de mauvaise manipulation, y'a pas de mal!
Caractéristiques:
Montage du capteur à fourche ITR9606.
Le programme suivant permet de savoir si il y a quelque chose entre les fourches.
const int encoderIn = 8; // Entrée D8 sur l'arduino const int statusLED = 13; // Sortie sur la led L de la carte int detectState=0; // Variable pour lire le statu void setup() { pinMode(encoderIn, INPUT); //Set pin 8 as input pinMode(statusLED, OUTPUT); //Set pin 13 as output Serial.begin(9600); } void loop() { detectState=digitalRead(encoderIn); if (detectState == HIGH) { //If encoder output is high digitalWrite(statusLED, HIGH); //Turn on the status LED Serial.println("Objet présent"); } else { digitalWrite(statusLED, LOW); //Turn off the status LED Serial.println("Objet Absent"); } }
Et si nous voulions l'utiliser en capteur de vitesse de rotation :
// Définition des broches utilisé et du timeout #define PULSE_PIN 2 #define PULSE_TIMEOUT 1000000 // Variable contenant la vitesse du moteur en rotations par minute unsigned long rpm; // setup() void setup () { // Initialisation du port série Serial.begin(9600); // Place la broche de la sonde en entrée pinMode(PULSE_PIN, INPUT); // Sonde à collecteur ouvert -> pull-up obligatoire digitalWrite(PULSE_PIN, HIGH); } // loop() void loop () { // Mesure de la durée du temps bas en us rpm = pulseIn(PULSE_PIN, LOW, PULSE_TIMEOUT); // Calcul de la vitesse en RPM à partir du temps bas en us rpm = 60 / (rpm / 1000000.0); // Affichage sur le port série Serial.print("N= "),Serial.print(rpm),Serial.println(" RPM"); // Délai no-flood delay(500); }
Et si nous voulions l'utiliser en capteur de position :
A faire
Câblage |
int photocellPin = 0; // the cell and 10K pulldown are connected to a0 int photocellReading; // the analog reading from the analog resistor divider void setup(void) { // We'll send debugging information via the Serial monitor Serial.begin(9600); } void loop(void) { photocellReading = analogRead(photocellPin); Serial.println("Résultat analogique = "); Serial.println(photocellReading); // the raw analog reading // We'll have a few threshholds, qualitatively determined if (photocellReading > 10) { Serial.println(" - Noir"); } else if (photocellReading > 200) { Serial.println(" - Sombre"); } else if (photocellReading > 500) { Serial.println(" - Lumiere"); } else if (photocellReading > 800) { Serial.println(" - Lumineux"); } else { Serial.println(" - Tres lumineux"); } delay(5000); /*5 secondes */ }
// [HC-SR04 Capteur de distance] int trigPin=13; // On définis chaque Pin int echoPin=12; // Arduino va communiquer via echo et trig void setup() { Serial.begin (9600); // On établis la liaison a 9600 Bauds // On définis les entrées et sorties pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { long duration, distance; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); /* On envoi une "salve" pendant une durée déterminé qui sera par la suite calculée */ distance = (duration/2) / 29.1; // On calcule if (distance > 25) { /* ici « 25 » définis le fait qu'on ne signalera pas l'objet avant qu'il soit à 15cm du capteur */ } if (distance <= 200 || distance >= 0){ /* là on dit que si la distance de l'objet dépasse 200cm on affichera "Hors de portée" sur le port série */ Serial.println("Hors de portee"); } else { Serial.print(distance); Serial.println(" cm"); } delay(100); }
//Le temps laissé au capteur pour le calibrer (10 à 60 secondes selon la fiche technique) //the time we give the sensor to calibrate (10-60 secs according to the datasheet) int calibrationTime = 30; int ledPin = 5; // choisir la broche pour la LED int inputPin = 7; // choisir la broche d'entrée ( pour le capteur PIR ) int pirState = LOW; // nous commençons , en supposant qu'aucun mouvement détecté int val = 0; // variable pour la lecture de l'état de la broche void setup() { pinMode(ledPin, OUTPUT); // déclarer comme sortie LED pinMode(inputPin, INPUT); // déclarer capteur en tant qu'entrée Serial.begin(9600); Serial.print("Etalonnage capteur PIR "); for (int i = 0; i < calibrationTime; i++) { Serial.print("."); digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); } } void loop() { val = digitalRead(inputPin); //lire la valeur d'entrée //Serial.println(val); if (val == HIGH) { // vérifier si l'entrée est HIGH digitalWrite(ledPin, HIGH); // passer LED ON delay(150); if (pirState == LOW) { // nous venons allumé // Nous voulons seulement sortir sur le changement de sortie , // pas le changement d'état pirState = HIGH; Serial.println("Un mouvement detecte!"); } } else { digitalWrite(ledPin, LOW); // turn LED OFF delay(300); if (pirState == HIGH) { // We only want to print on the output change, not state pirState = LOW; // we have just turned off Serial.println("Pas ou plus de mouvement!"); } } }
Capteur effet Hall 4. 5-24V, Détecteur magnétique |
/* Capteur effet Hall Y3144 (C) Sammy76 - V1.0 Présence d'un champ magnétique */ int hallPin = 2; int ledPin = 3; int hallState; void setup(){ Serial.begin(9600); pinMode(hallPin, INPUT); pinMode(ledPin, OUTPUT); } void loop(){ hallState = digitalRead(hallPin); if (hallState == HIGH){ Serial.print("Pas de signal, Etat: "); digitalWrite(ledPin, LOW); } if (hallState == LOW){ Serial.print("Source magnetique proche, Etat: "); digitalWrite(ledPin, HIGH); } Serial.println(hallState); delay(100); }
Réalisation d'un tachymètre :
J'en profite pour vous mettre la distance parcouru si vous avez un rayon de rotation
Le principe est de mesurer le nombre d'impulsions pendant une durée.
Dans le programme ci-dessous, la durée étant de 3s, le si j'ai une impulsion durant ces 3s cela fait :
$N=\dfrac{1 \times 60}{3}=20~RPM$, c'est donc la précision minimum.
/* Capteur effet Hall Y3144 * Tachymetre avec gestion des interruptions (C) Sammy76 - V1.0 */ //Rayon en mm pour la vitesse de translation #define RAYON 300 long duree_test = 3000; // test sur 3 secondes const float Pi = 3.1415927; // Variable contenant la vitesse du moteur en rotations par minute unsigned long rpm=0; float ms; long chrono = 0; // valeur courante du chrono long chrono_depart = 0; // valeur de départ du chrono volatile long nb_chgt = 0; // nb de changement etat Pin // Gestion de l'interruption 0 void gere_int0() { nb_chgt = nb_chgt + 1 ; } void setup () { // Initialisation du port série Serial.begin(9600); chrono_depart = millis(); // l'interruption zero correspond à la pin 2 // on enregistre tous lorsque la broche passe de //l'état HAUT vers l'état BAS (front descendant) attachInterrupt(0,gere_int0,FALLING); } void loop() { chrono = millis(); //durée de test terminée? if (chrono - chrono_depart > duree_test) { // Mesure sur 3 secondes : // il faut multiplier le nb de chgt par 20 // pour avoir le nb de changement par minute rpm=nb_chgt*(60000/duree_test); //Nombre de changement ms=Pi*rpm*RAYON/30000; //v=omegaxR=(pi.N/30)x(R/1000) // Affichage sur le port série Serial.print("N="),Serial.print(rpm),Serial.print(" RPM, "); Serial.print("V="),Serial.print(ms),Serial.println(" m/s"); chrono_depart = millis(); nb_chgt=0; } }
Autre technique de mesure, je mesure le temps entre deux impulsions.
Cette technique est plus précise.
/* Capteur effet Hall Y3144 * Tachymetre avec gestion des interruptions * principe de mesure de temps entre deux impulsions (C) Sammy76 - V1.0 */ //Rayon en mm pour la vitesse de translation #define RAYON 300 boolean front; const float Pi = 3.1415927; // Variable contenant la vitesse du moteur en rotations par minute unsigned long rpm=0; float ms; long chrono_depart = 0; // valeur de départ du chrono // Gestion de l'interruption 0 void gere_int0() { front=true; } void setup () { // Initialisation du port série Serial.begin(9600); chrono_depart = millis(); // l'interruption zero correspond à la pin 2 // on enregistre tous lorsque la broche passe de //l'état HAUT vers l'état BAS (front descendant) attachInterrupt(0,gere_int0,FALLING); } void loop() { //changement de front if (front){ rpm=millis() - chrono_depart; front=false; //(rpm/1000) durée entre deux impulsions en seconde rpm = 60000 / rpm ; ms=Pi*rpm*RAYON/30000; //v=omegaxR=(pi.N/30)x(R/1000) // Affichage sur le port série Serial.print("N="),Serial.print(rpm),Serial.print(" RPM, "); Serial.print("V="),Serial.print(ms),Serial.println(" m/s"); chrono_depart=millis(); } }
I²C : Inter-Integrated Circuit chez certain constructeur ce bus s'appelle TWI (Two Wire Interface)
source Wikipedia, très bien faite!
Le programme suivant permet de connaitre les périphériques i²C connectés :
/* -------------------------------------- i2c_scanner * Pin Connections: * SCL = A5 * SDA = A4 * VCC = 5V * GND = GND -------------------------------------- */ #include "Wire.h" //Pour les périphériques I2C void setup() { Wire.begin(); Serial.begin(9600); while (!Serial); // Attent le moniteur série Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for (address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("Périphérique I²C touvé à l'addresse 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Erreur inconnu à l'addresse 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("Pas de périphérique I2C trouvé\n"); else Serial.println("fin\n"); delay(5000); // wait 5 seconds for next scan }
/*LCD1602 sur I2C * Pin Connections: * SCL = A5 * SDA = A4 * VCC = 5V * GND = GND */ #include "Wire.h" // Comes with Arduino IDE /* Inclut la librairie pour le lcd */ #include "LiquidCrystal_I2C.h" LiquidCrystal_I2C lcd(0x3f, 16, 2); //Adresse LCD1602 0x3F /* Caractères personnalisés */ byte r0[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B00000, B00000 }; // 0 / 5 byte r1[8] = { B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 }; // 1 / 5 byte r2[8] = { B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 }; // 2 / 5 byte r3[8] = { B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 }; // 3 / 5 byte r4[8] = { B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 }; // 4 / 5 byte r5[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 }; // 5 / 5 // Fonction dessinant le bargraph void draw_bargraph(byte percent) { byte i, cp, cl; // Affiche la nouvelle valeur lcd.setCursor(0, 0); lcd.print(percent); lcd.print(" % "); // Ligne suivante lcd.setCursor(0, 1); /* Map percent de (0 ~ 100) vers (0 ~ 80) ( 1 char = 5 colonnes, 16 * 5 = 80) */ percent = map(percent, 0, 100, 0, 80); /* Calcul le nombre de cases pleines et le nombre de colonnes dans la dernière case */ cp = percent / 5; //diviser par 5 cl = percent % 5; //Reste de la division /* Dessine les cases pleines */ for (i = 0; i < cp; ++i) lcd.write(5); /* Dessine la dernière case */ lcd.write(cl); /* Dessine les cases vides restantes */ for (i = 0; i < 16 - (cp + (cl ? 1 : 0)); ++i) lcd.write((uint8_t)0); } /* setup() */ void setup() { lcd.begin(); /* Enregistre les caractères personnalisés dans le lcd */ lcd.createChar(0, r0); lcd.createChar(1, r1); lcd.createChar(2, r2); lcd.createChar(3, r3); lcd.createChar(4, r4); lcd.createChar(5, r5); /* Initialise le lcd */ lcd.clear(); /* Départ à 0% */ draw_bargraph(0); } /* loop() */ void loop() { /* Valeur en % du bargraph */ static byte percent = 0; /* Indique si la valeur a été modifiée */ /* Lit les boutons et agis en conséquence */ /* Dessine le nouveau bargraph*/ for (percent = 0; percent <= 100; percent = percent + 1) { draw_bargraph(percent); } /* Refresh 2Hz */ delay(1000); }
/******************************************************** MAX6675 avec thermocouple type K GND --> Gnd Vcc --> Vcc 5V SO Data Output --> D4 CS Chip Select --> D5 CLK clock --> D6 LCD1602 sur i2C 1 VCC alimentation du module --> Vcc 3.3v à 5V 2 GND masse--> Gnd 3 SCL Serial Clock --> A5 4 SDA Serial Data --> A4 5 DRDY --> n/a, Data ReaDY non utilisé. */ #include "max6675.h" //La librairie du MAX6675 #include "Wire.h" //Librairie Wire pour la communication I2C #include "LiquidCrystal_I2C.h" LiquidCrystal_I2C lcd(0x3f, 16, 2); //Adresse LCD1602 0x3F #define consigne 240 //240°C byte copyright[8] = { B01110, B10101, B11011, B11001, B11001, B11011, B10101, B01110 }; uint8_t deg[8] = { B00110, B01001, B01001, B00110, B00000, B00000, B00000, B00000 }; uint8_t e_acc[8] = { B00010, B00100, B01110, B10001, B11111, B10000, B01110, B00000 }; byte up[8] = { B00100, B01110, B11111, B10101, B00100, B00100, B00100, B00100 }; byte down[8] = { B00100, B00100, B00100, B00100, B10101, B11111, B01110, B00100 }; int thermoDO = 4; // Data Out Port SPI sur 4-5-6 int thermoCS = 5; //Chip Select int thermoCLK = 6; //Clock // Déclarer les pins utilisées MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); void setup() { Serial.begin(9600); //Pour afficher à l'écran du PC lcd.begin(); lcd.createChar(0, up); lcd.createChar(1, down); lcd.createChar(6, copyright); lcd.createChar(7, deg); lcd.createChar(5, e_acc); lcd.clear(); lcd.setCursor(0, 0); lcd.print("LCD1602+MAX6675"); lcd.setCursor(4, 1); lcd.write(6); lcd.print("Sammy76"); delay(2000); //Attendre l'initialisation du module MAX mini 500 lcd.clear(); lcd.setCursor(0, 0); lcd.print("Temp"); lcd.write(5); lcd.print("rature:"); lcd.print(consigne); } void loop() { // Boucle de mesure de la température lcd.setCursor(0, 1); lcd.print(" "); //Efface la ligne lcd.setCursor(0, 1); lcd.print(thermocouple.readCelsius()); lcd.write(7); lcd.print("C"); lcd.setCursor(9, 1); lcd.print(thermocouple.readFahrenheit()); lcd.print("F"); lcd.setCursor(15, 0); if (thermocouple.readCelsius() > consigne) { lcd.write(1); //down } if (thermocouple.readCelsius() < consigne) { lcd.write(0); //up } if (thermocouple.readCelsius() == consigne) { lcd.print("="); } delay(2000); //2 secondes }
//************************************************************* // Boussole //************************************************************* /*LCD1602 sur i2C et HMC5803L sur i2C * 1 VCC alimentation du module --> Vcc 3.3v à 5V 2 GND masse--> Gnd 3 SCL Serial Clock --> A5 4 SDA Serial Data --> A4 5 DRDY --> n/a, Data ReaDY non utilisé. */ #include "Wire.h" //Librairie Wire pour la communication I2C #include "LiquidCrystal_I2C.h" LiquidCrystal_I2C lcd(0x3f, 16, 2); //Adresse LCD1602 0x3F byte copyright[8] = { B01110, B10101, B11011, B11001, B11001, B11011, B10101, B01110 }; byte up[8] = { B00100, B01110, B11111, B10101, B00100, B00100, B00100, B00100 }; #define HMC5803L_Address 0x1E //Adresse I2C du module #define X 3 //Adresses de registres pour les données X Y et Z #define Y 7 #define Z 5 double Xmagnetic; double Ymagnetic; double Zmagnetic; double Module_magnetic; double angle; void setup() { Serial.begin(9600); lcd.begin(); lcd.createChar(0,up); lcd.createChar(6,copyright); lcd.clear(); lcd.setCursor(0, 0); lcd.print("LCD1602+HMC5803L"); lcd.setCursor(0, 1); lcd.print(" "); lcd.write(6); lcd.print("Sammy76"); delay(5000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("x"); lcd.setCursor(8, 0); lcd.print("y"); lcd.setCursor(0, 1); lcd.print("z"); lcd.setCursor(8, 1); lcd.print("a"); Wire.begin(); //Initialisation de la livrairie Wire Init_HMC5803L(); //Initialiser le module boussole } // Boucle de mesures de champ magnétique void loop() { Xmagnetic = HMC5803L_Read(X); //lecture sur 3 axes et sortie sur le port sériel Ymagnetic = HMC5803L_Read(Y); Zmagnetic = HMC5803L_Read(Z); /* Serial.print("X"); Serial.print (Xmagnetic); Serial.print("Y"); Serial.print (Ymagnetic); Serial.print("Z"); Serial.print (Zmagnetic); */ lcd.setCursor(1, 0); lcd.print(" "); lcd.setCursor(1, 0); lcd.print(Xmagnetic); lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(9, 0); lcd.print(Ymagnetic); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(1, 1); lcd.print(Zmagnetic); //Module du champ Module_magnetic = Xmagnetic * Xmagnetic + Ymagnetic * Ymagnetic + Zmagnetic * Zmagnetic; Module_magnetic = sqrt(Module_magnetic); /*Serial.print(" M= "); Serial.print(Module_magnetic); */ //Calculer l'angle de la boussole à partir de X et Y (à plat) angle= atan2(Ymagnetic,Xmagnetic) * (180 / 3.14159265); // angle en degres if (angle<0) {angle=angle+360;} /*Serial.print(" "); Serial.print("Angle "); //en degres Serial.println(angle);*/ lcd.setCursor(9, 1); lcd.print(" "); lcd.setCursor(9, 1); lcd.print(angle); lcd.setCursor(15, 1); if (round(angle)==0) { lcd.write(0); } else { lcd.print(" "); } delay(500); } // === Fonction qui initialise le module boussole (à lancer une seule fois) void Init_HMC5803L(void) { /* Set the module to 8x averaging and 15Hz measurement rate */ Wire.beginTransmission(HMC5803L_Address); Wire.write(0x00); Wire.write(0x70); Wire.write(0x01); Wire.write(0xA0); //Règle un gain de 5 Wire.endTransmission(); } // === Fonction qui lit le module boussole (registre d'un des 3 axes, retourne 16 bits) int HMC5803L_Read(byte Axis) { int Result; /* Initiate a single measurement */ Wire.beginTransmission(HMC5803L_Address); Wire.write(0x02); Wire.write(0x01); Wire.endTransmission(); delay(6); /* Move modules the resiger pointer to one of the axis data registers */ Wire.beginTransmission(HMC5803L_Address); Wire.write(Axis); Wire.endTransmission(); /* Read the data from registers (there are two 8 bit registers for each axis) */ Wire.requestFrom(HMC5803L_Address, 2); Result = Wire.read() << 8; Result |= Wire.read(); return Result; }
Modèle étanche | Boitier TO-92 |
/* Lecteur de température à partir d'un ou plusieurs DS18B20 Matériel : - LCD1602 sur I2C * Pin Connections: * SCL = A5 * SDA = A4 * VCC = 5V * GND = GND - Carte LCD/I2C - Capteur(s) DS18B20 : * Pin Connections: * Data = D2 * VCC = 5V * GND = GND */ #include "Wire.h" #include "OneWire.h" #include "LiquidCrystal_I2C.h" OneWire capteur(2);// crée un objet One Wire sur la broche voulue LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display uint8_t deg[8] = { B00110, B01001, B01001, B00110, B00000, B00000, B00000, B00000 }; uint8_t e_acc[8] = { B00010, B00100, B01110, B10001, B11111, B10000, B01110, B00000 }; int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2 //Temperature chip i/o OneWire ds(DS18S20_Pin); // on digital pin 2 byte adresse[8]; void setup(void) { int comp = 1; String kk; Serial.begin(9600); lcd.begin(); // initialize the lcd //lcd.cursor(); lcd.createChar(7, deg); lcd.createChar(8, e_acc); // Print a message to the LCD. lcd.backlight(); lcd.noAutoscroll(); lcd.setCursor(0, 0); lcd.print("Nano+I2C+DS18B20"); //Liste des capteurs while (capteur.search(adresse) == true) // tant qu'un nouveau capteur est détecté { kk = ""; for (int i = 0; i < 8; i++) { kk = kk + String(adresse[i], HEX); } Serial.println("Capteur " + String(comp) + ":" + kk + "\n"); lcd.setCursor(0, 1); lcd.print(kk); lcd.setCursor(0, 0); delay(2000); comp = comp + 1; } } void loop(void) { int comp = 1; while (capteur.search(adresse) == true) { //Une page par capteur float temperature = getTemp(adresse); float Fahrenheit = (9 / 5. * temperature) + 32; //lcd.clear(); //Serial.println(temperature); lcd.setCursor(0, 0); lcd.print("Temp"); lcd.write(8); lcd.print("rature " + String(comp) + " : "); lcd.noAutoscroll(); lcd.setCursor(0, 1); lcd.print(temperature); lcd.write(7); lcd.print("C--"); lcd.print(Fahrenheit); lcd.print("F"); delay(2000); //2 secondes comp = comp + 1; } //Page suivante lcd.setCursor(0, 0); lcd.print("Ca fonctionne!!!"); lcd.setCursor(0, 1); lcd.print("Youpi!!!! "); delay(2000); //2 secondes } float getTemp(byte addr[8]) { //returns the temperature from one DS18S20 in DEG Celsius byte data[12]; // if ( !ds.search(addr)) { // //no more sensors on chain, reset search // ds.reset_search(); // return -1000; // } if ( OneWire::crc8( addr, 7) != addr[7]) { Serial.println("CRC non valide!\n"); return -1000; } if ( addr[0] != 0x28) { Serial.println("Pas de la famille DS18B20.\n"); return -1000; } if ( addr[0] != 0x10 && addr[0] != 0x28) { Serial.println("Composant non reconnu\n"); return -1000; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end byte present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for (int i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } ds.reset_search(); byte MSB = data[1]; byte LSB = data[0]; float tempRead = ((MSB << 8) | LSB); //using two's compliment float TemperatureSum = tempRead / 16; return TemperatureSum; }
/* * Base: Etude du BMP180 (on n'utilise aucune bibliothèque dédiée) Copyright 2015 - Eric Sérandour http://labo.serandour.com Modif sammy76.free.fr Matériel : - LCD1602 sur I2C * Pin Connections: * SCL = A5 * SDA = A4 * VCC = 5V * GND = GND - Carte LCD/I2C - Capteur(s) Baromètre BMP180 : * Pin Connections: * SCL = A5 * SDA = A4 * VCC = 3.3V Attention ! * GND = GND * */ #include "LiquidCrystal_I2C.h" // Initialisation de la bibliothèque avec les numéros de broches utilisées LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display byte degre[8] = { // Déclaration d’un tableau de 8 octets pour le caractère °. B00111, // Définition de chaque octet au format binaire : B00101, // 1 pour un pixel affiché – 0 pour un pixel éteint. B00111, // Les 3 bits de poids forts sont ici inutiles. B00000, B00000, B00000, B00000, B00000 }; byte caractereDegre = 0; // *** BMP180 #include "Wire.h" // On importe la bibliothèque Wire pour l'I2C #define ADRESSE_BMP180 0x77 float pressionAbsolue = 0; float pressionRelative = 0; float altitude = 0; float temperature = 0; // Température à l'intérieur de la centrale float altitudeReference = 0; // Altitude connue rentrée au clavier float pressionReference = 0; // Pression à l'altitude de référence ////////////////////////////////////////////////////////////////////////////////////////// void setup() { lcd.begin(); lcd.clear(); Wire.begin(); initBarometre(ADRESSE_BMP180); } ////////////////////////////////////////////////////////////////////////////////////////// void loop() { afficherBarometre(ADRESSE_BMP180); } ////////////////////////////////////////////////////////////////////////////////////////// /* ALTI-BAROMETRE BMP180 */ ////////////////////////////////////////////////////////////////////////////////////////// void afficherBarometre(int adresseI2C) { // Réglage de l'alti-baromètre reglageAltimetre(adresseI2C); // Affichage des mesures lcd.createChar(caractereDegre, degre); // Création du caractère personnalisé degré boolean quitter = false; do { lcd.clear(); byte codeErreur = barometreRead(adresseI2C); if (codeErreur != 0) { lcd.setCursor(0, 0); lcd.print("BARO-ALTIMETRE"); lcd.setCursor(0, 1); lcd.print("ERREUR (CODE "); lcd.print(codeErreur); lcd.print(")"); delay(1000); quitter = true; } else { lcd.clear(); lcd.setCursor(0, 0); lcd.print("BAROMETRE "); lcd.print(temperature); lcd.write(caractereDegre); lcd.print("C"); lcd.setCursor(0, 1); lcd.print("Pa : "); lcd.print(pressionAbsolue); lcd.print(" hPa"); delay(1000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Pr : "); lcd.print(pressionRelative); lcd.print(" hPa"); lcd.setCursor(0, 1); lcd.print("H : "); lcd.print(altitude); lcd.print(" m"); delay(1000); } } while (quitter == false); } ////////////////////////////////////////////////////////////////////////////////////////// void reglageAltimetre(int adresseI2C) { altitudeReference = 140; //m barometreRead(adresseI2C); pressionReference = pressionAbsolue; } ////////////////////////////////////////////////////////////////////////////////////////// int16_t ac1, ac2, ac3, b1, b2, mb, mc, md; // Calibration coefficients uint16_t ac4, ac5, ac6; // Calibration coefficients // Ultra low power : oss = 0, osd = 5 ms // Standard : oss = 1, osd = 8 ms // High resolution : oss = 2, osd = 14 ms // Ultra high resolution : oss = 3, osd = 26 ms const uint8_t OSS = 3; // Set oversampling setting const uint8_t OSD = 26; // with corresponding oversampling delay ////////////////////////////////////////////////////////////////////////////////////////// void initBarometre(int adresseI2C) // Voir le Data sheet du BMP180, à la page 15. { // Read calibration data from the EEPROM of the BMP180 ac1 = readRegister16(adresseI2C, 0xAA); ac2 = readRegister16(adresseI2C, 0xAC); ac3 = readRegister16(adresseI2C, 0xAE); ac4 = readRegister16(adresseI2C, 0xB0); ac5 = readRegister16(adresseI2C, 0xB2); ac6 = readRegister16(adresseI2C, 0xB4); b1 = readRegister16(adresseI2C, 0xB6); b2 = readRegister16(adresseI2C, 0xB8); mb = readRegister16(adresseI2C, 0xBA); mc = readRegister16(adresseI2C, 0xBC); md = readRegister16(adresseI2C, 0xBE); } ////////////////////////////////////////////////////////////////////////////////////////// uint16_t readRegister16(int adresseI2C, uint8_t code) { uint16_t value = 0; Wire.beginTransmission(adresseI2C); // Start transmission to device Wire.write(code); // Sends register address to read from byte error = Wire.endTransmission(); // End transmission if (error == 0) { Wire.requestFrom(adresseI2C, 2); // Request 2 bytes from device while (Wire.available() < 2); // Wait until bytes are ready value = (Wire.read() << 8) + Wire.read(); } return value; } ////////////////////////////////////////////////////////////////////////////////////////// byte barometreRead(int adresseI2C) // Suivant datasheet BOSH BMP180, à la page 15. { int32_t x1, x2, x3, b3, b5, b6, ut, up, t, p; uint32_t b4, b7; int16_t msb, lsb, xlsb; byte error = 0; // Read uncompensated temperature value (ut) Wire.beginTransmission(adresseI2C); // Start transmission to device Wire.write(0xf4); // Sends register address Wire.write(0x2e); // Write data error = Wire.endTransmission(); // End transmission if (error == 0) { // On continue delay(5); // Data sheet suggests 4.5 ms Wire.beginTransmission(adresseI2C); // Start transmission to device Wire.write(0xf6); // Sends register address to read from error = Wire.endTransmission(); // End transmission if (error == 0) { // On continue Wire.requestFrom(adresseI2C, 2); // Request 2 bytes (0xf6, 0xf7) while (Wire.available() < 2); // Wait until bytes are ready msb = Wire.read(); lsb = Wire.read(); ut = ((int32_t)msb << 8) + (int32_t)lsb; // Read uncompensated pressure value (up) Wire.beginTransmission(adresseI2C); // Start transmission to device Wire.write(0xf4); // Sends register address Wire.write(0x34 + (OSS << 6)); // Write data error = Wire.endTransmission(); // End transmission if (error == 0) { // On continue delay(OSD); // Oversampling setting delay Wire.beginTransmission(adresseI2C); // Start transmission to device Wire.write(0xf6); // Sends register address to read from error = Wire.endTransmission(); // End transmission if (error == 0) { // On continue Wire.requestFrom(adresseI2C, 3); // Request 3 bytes (0xf6, 0xf7, 0xf8) while (Wire.available() < 3); // Wait until bytes are ready msb = Wire.read(); lsb = Wire.read(); xlsb = Wire.read(); up = (((int32_t)msb << 16) + ((int32_t)lsb << 8) + ((int32_t)xlsb)) >> (8 - OSS); // Calcul de la température vraie x1 = (ut - (int32_t)ac6) * (int32_t)ac5 >> 15; x2 = ((int32_t)mc << 11) / (x1 + (int32_t)md); b5 = x1 + x2; t = (b5 + 8) >> 4; temperature = t / 10.0f; // temperature in celsius // Calcul de la pression vraie // On étend la taille de certaines variables pour éviter des dépassements. // Par exemple, dans la 2ème ligne, x1 est int32_t, b2 est int16_t // et b6 est int_32t d'où le (int32_t)b2. // Pour gagner en vitesse de calcul, on utilise << ou >> : // << : un décalage de 1 bit vers la gauche revient à multiplier par 2 // >> : un décalage de 1 bit vers la droite revient à diviser par 2 b6 = b5 - 4000; x1 = ((int32_t)b2 * (b6 * b6 >> 12)) >> 11; x2 = (int32_t)ac2 * b6 >> 11; x3 = x1 + x2; b3 = ((((int32_t)ac1 * 4 + x3) << OSS) + 2) >> 2; x1 = (int32_t)ac3 * b6 >> 13; x2 = ((int32_t)b1 * (b6 * b6 >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; b4 = ((uint32_t)ac4 * (uint32_t)(x3 + 32768)) >> 15; b7 = ((uint32_t)up - (uint32_t)b3) * (uint32_t)(50000 >> OSS); if (b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; p = p + ((x1 + x2 + 3791) >> 4); pressionAbsolue = p / 100.0f; // pression en hPa // Calculate pressure at sea level pressionRelative = pressionAbsolue / pow((1.0f - (altitudeReference / 44330.0f)), 5.255f); // Calculate absolute altitude float pression0 = pressionReference / pow((1.0f - (altitudeReference / 44330.0f)), 5.255f); altitude = 44330.0f * (1 - pow(pressionAbsolue / pression0, (1 / 5.255f))); } } } } return error; }
Pour la précision, nous utiliserons la tension de référence interne soit pour le ATMEGA328 1,1V ±0.1 V.
C'est un mesure peut précise, le test avec un Arduino Nano donne :
1.089 V à une température ambiante de 21°C. soit 1089/1024=1,06mA de précision.
1.084 V à une température ambiante de -18 °C soit 1089/1024=1,05mA de précision.
L'écart entre les deux ne fait varier la résolution de l'ADC que de 10µA, ce qui est acceptable.
/* (c) Sammy76.free.fr 2015 Milli-ampèremètre Arduino NANO V3.0 Interval ref=1,089V Avec Max451 1V/A Précision : 1089/1024=1,063mA Voir pour ACS712-5A 185mV/A Précision : 1089/1024/0.185=5,75mA Entrée A0 : */ const int CurrentIn = A0; //Avec MAX451 int RawValue = 0; float Current = 0; void setup() { Serial.begin(9600); analogReference(INTERNAL); //DEFAULT 5V, INTERNAL 1,1V, ou EXTERNAL. pinMode(CurrentIn, INPUT); } void loop() { RawValue = analogRead(CurrentIn); Current = (RawValue * 1089.0 / 1024.0); // //Conversion sur 10 bits Serial.print("Courant = "); Serial.print(Current, 1); //1 digit après point decimale Serial.println(" mA"); // Délai entre deux affichages delay(100); }
// Test de commandes AT avec module HC-06 Bluetooth // Connection du HC-06 avec le monitor serie // // The HC-06 defaults to AT mode when first powered on. // The default baud rate is 9600 // The Hc-06 requires all AT commands to be in uppercase. //NL+CR should not be added to the command string #include "SoftwareSerial.h" SoftwareSerial HC06(11, 10); // RX | TX // Connect the HC-06 TX to the Arduino RX on pin 11. // Connect the HC-06 RX to the Arduino TX on pin 10. void setup() { Serial.begin(9600); Serial.println("Enter AT commands:"); // HC-06 default serial speed is 9600 HC06.begin(9600); } void loop() { // Keep reading from HC-06 and send to Arduino Serial Monitor if (HC06.available()) { Serial.write(HC06.read()); } // Keep reading from Arduino Serial Monitor and send to HC-06 if (Serial.available()) { HC06.write(Serial.read()); } }
1. Test communication Send: AT (please send it every second) Back: OK 2. Reset the Bluetooth serial baud rate Send: AT+BAUD1 Back: OK1200 Send: AT+BAUD2 Back: OK2400 …… 1---------1200 2---------2400 3---------4800 4---------9600 (Default) 5---------19200 6---------38400 7---------57600 8---------115200 9---------230400 A---------460800 B---------921600 C---------1382400 3. Reset the Bluetooth name Send: AT+NAMEname la taille maxi est 20 caractères Back: OKname Exemple :AT+NAMEHC-06 Le nouveau nom visible sera HC-06 4. change the Bluetooth pair password Send: AT+PINxxxx Back:OKsetpin Exemple :AT+PIN8888 Le nouveau code pour accès est le 8888. Le code par default est "1234" 5. No parity check ( The version, higher than V1.5, can use this command ) Send: AT+PN (This is the default value) Back: OK NONE 6. Set odd parity check ( The version, higher than V1.5, can use this command ) Send: AT+PO Back: OK ODD 7. Set even parity check( The version, higher than V1.5, can use this command ) Send: AT+PE Back: OK EVEN 8. Get the AT version Send: AT+VERSION Back: LinvorV1.n
#include "SoftwareSerial.h" #include "Wire.h" #include "LiquidCrystal_I2C.h" #define lcd_adr 0x3F LiquidCrystal_I2C lcd(lcd_adr, 16, 2); uint8_t a224[8] = {8, 4, 14, 1, 15, 17, 15, 0}; // à uint8_t a231[8] = {0, 14, 16, 16, 17, 14, 4, 12}; // ç uint8_t a232[8] = {8, 4, 14, 17, 31, 16, 14, 0}; //è uint8_t a233[8] = {2, 4, 14, 17, 31, 16, 14, 0}; // é uint8_t a234[8] = {4, 10, 14, 17, 31, 16, 14, 0}; // ê uint8_t a235[8] = {10, 0, 14, 17, 31, 16, 15, 0}; // ë uint8_t a249[8] = {4, 10, 0, 17, 17, 19, 13, 0}; // û uint8_t a252[8] = {10, 0, 17, 17, 17, 19, 13, 0}; // ü SoftwareSerial HC06(11, 10); const char DOUT_LED = 9; String messageRecu; char change(char k) { if (k == 0xFFFFFFC3) { delay(3); k = HC06.read(); switch (k) { case 0xFFFFFFA0: k = 0x0; break; //à case 0xFFFFFFA7: k = 0x1; break; // ç case 0xFFFFFFA8: k = 0x2; break; //è case 0xFFFFFFA9: k = 0x3; break; //é case 0xFFFFFFAA: k = 0x4; break; //ê case 0xFFFFFFAB: k = 0x5; break; //ë case 0xFFFFFFBC: k = 0x6; break; // û case 0xFFFFFFBB: k = 0x7; break; // ü } } return k; } void sendmessage(void) { lcd.clear(); lcd.setCursor(0, 0); lcd.print(messageRecu); } void setup() { HC06.begin(9600); pinMode(DOUT_LED, OUTPUT); digitalWrite(DOUT_LED, LOW); lcd.begin(); lcd.createChar(0, a224);//à lcd.createChar(1, a231);//ç lcd.createChar(2, a232);//è lcd.createChar(3, a233);//é lcd.createChar(4, a234);//ê lcd.createChar(5, a235);//ë lcd.createChar(6, a249);//ù lcd.createChar(7, a252);//ü } void loop() { while (HC06.available()) { delay(3); char c = HC06.read(); messageRecu += change(c); } if (messageRecu.length() > 0) { if (messageRecu == "LED:1") { digitalWrite(DOUT_LED, HIGH); } if (messageRecu == "LED:0") { digitalWrite(DOUT_LED, LOW); } if (messageRecu != "LED:0" && messageRecu != "LED:1") { sendmessage(); } messageRecu = ""; } }
// library #include "VirtualWire.h" int i=0; void setup() { //Serial.begin(9600); pinMode(13, OUTPUT); // virtual wire vw_set_tx_pin(12); // pin vw_setup(4000); // bps } void loop() { sendString("Arduino "+String(i), true); delay(1000); digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) delay(200); // wait for a second digitalWrite(13, LOW); // turn the LED off by making the voltage LOW i++; } void sendString(String message, bool wait) { byte messageLength = message.length() + 1; // convert string to char array char charBuffer[messageLength]; message.toCharArray(charBuffer, messageLength); vw_send((uint8_t *)charBuffer, messageLength); if (wait) vw_wait_tx(); //Serial.println("sent: " + message); }Réception du signal RF XY-MK-5V
// library #include "VirtualWire.h" byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message void setup() { Serial.begin(9600); Serial.println("device is ready..."); vw_set_rx_pin(12); vw_setup(4000); // bps vw_rx_start(); } void loop() { if (vw_get_message(message, &messageLength)) // non-blocking { Serial.print("received: "); for (int i = 0; i < messageLength; i++) { Serial.write(message[i]); } Serial.println(); } }
Avec un seul poussoir, nous avons vu que l’entrée analogique de l’Arduino était tirée à la masse via une résistance de 10kΩ. L’appui sur le poussoir amenait cette entrée à 5V. Pour la suite, on va inverser la connexion. Connexion d’un poussoir à l’entrée analogique de l’Arduino, état de repos à +5V L’entrée analogique est tirée à +5V et l’appui sur le poussoir amène cette entrée à la masse. En effet, avec plusieurs poussoirs, cette façon de faire est plus commode car, sur le réseau, la masse est distribuée partout alors que ce n’est pas le cas pour le +5V. |
Lorsque B0 est pressé, nous avons le même comportement, l’entrée analogique est à 0V. Lorsque B1 est pressé, les deux résistances sont en série entre 5V et 0V et l’entrée analogique est à la tension qui existe entre les deux résistances. On voit qu’il s’agit d’un diviseur de tension, et donc l’entrée analogique est à 2,5V. Évidemment, on ne peut pas presser 2 poussoirs en même temps, l’Arduino ne verra que le poussoir de rang le plus bas. |
Avec 8 poussoirs, il faut diviser les 1024 valeurs possibles en 8 intervalles de 1024 ÷ 8 = 128 valeurs. Plus on ajoute des poussoirs et plus cet intervalle devient petit. Plus cet intervalle devient petit et plus il est nécessaire d’avoir des résistances précises. Or, les résistances standards ont des valeurs déterminées et sont précises à 5%. Si les intervalles sont trop petits, il devient impossible de distinguer deux valeurs voisines de façon fiable. Cela limite le nombre de poussoirs que l’on peut connecter mais 8 poussoirs ne devraient pas poser de problème. |
Appuis | Tension | Valeur | Sur la figure ci-contre, la plage de valeurs analogiques a été découpée en 8 intervalles. Il faut donc déterminer les résistances R1 à R7 de manière à obtenir plus ou moins la tension voulue. On va voir que ça se fait assez bien. |
---|---|---|---|
Rien | 5V | 1023 | |
BT7 | 4.375V | 895 | |
BT6 | 3.75V | 767 | |
BT5 | 3.125V | 639 | |
BT4 | 2.5V | 511 | |
BT3 | 1.875V | 383 | |
BT2 | 1.25V | 255 | |
BT1 | 0.625V | 127 | |
BT0 | 0V | 0 |
Avant tout nous allons choisir un courant maximum d'environ 15mA en entrée, soit une résistance, afin d'absorber les bruits : Valeur de R1 pour U1=0,625V Suivant la règle du pont diviseur $R_1=\dfrac{330\cdot V_s}{V_{cc}-V_s}=\dfrac{330\times 0,625}{5-0,625}=47,142857\Omega$ ce qui donne un valeur standard de $47\Omega$ $R2=\dfrac{330\times 1,25}{5-1,25}-R_1=62,857143\Omega$ Soit $62\Omega$ $R3=\dfrac{330\times 1,875}{5-1,875}-R_1-R_2=88\Omega$ Soit $82\Omega$ $...$ |
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
const byte NON_PRESSE = 0; const byte ENFONCE = 1; const byte PRESSE = 2; byte etatAutomate = NON_PRESSE; int etatPoussoir = -1; const byte AUCUN_EVENEMENT = 0; const byte EVENEMENT_PRESSE = 1; const byte EVENEMENT_RELACHE = 2; const int pinPoussoirs = 0; //A0 int lirePoussoirs() { int resultat; int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128; int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */ switch (etatAutomate) { case NON_PRESSE: if (numPoussoir < 8) etatAutomate = ENFONCE; break; case ENFONCE: if (numPoussoir < 8) { etatAutomate = PRESSE; nouvelEtatPoussoir = numPoussoir; } else { etatAutomate = NON_PRESSE; } break; case PRESSE: if (numPoussoir == 8) { etatAutomate = NON_PRESSE; nouvelEtatPoussoir = -1; } break; } return nouvelEtatPoussoir; } /* * construction d'un événement en comparant * le nouvel état des poussoirs avec l'état précédent. */ byte lireEvenement(int *numPoussoir) { byte evenement; int nouvelEtatPoussoir = lirePoussoirs(); if (nouvelEtatPoussoir == etatPoussoir) evenement = AUCUN_EVENEMENT; if (nouvelEtatPoussoir >= 0 && etatPoussoir == -1) evenement = EVENEMENT_PRESSE; if (nouvelEtatPoussoir == -1 && etatPoussoir >= 0) evenement = EVENEMENT_RELACHE; etatPoussoir = nouvelEtatPoussoir; *numPoussoir = etatPoussoir; return evenement; } void setup() { Serial.begin(9600); } void loop() { int numPoussoir; byte evenement = lireEvenement(&numPoussoir); switch (evenement) { case EVENEMENT_PRESSE: Serial.print("Presse : "); Serial.println(numPoussoir); break; case EVENEMENT_RELACHE: Serial.print("Relache : "); Serial.println(numPoussoir); break; } delay(3); }Attention à la précision des résistances (E24 c'est mieux), une autre solution serai d'utiliser des diodes.
#define BPPin A7 // The buttons and the 100K pulldown are connected to A7 //================================================================================= BEGIN loadbp uint8_t loadbp(){ //Load BP with diode uint8_t result_bp=0; uint16_t bpReading; while (result_bp==0){ bpReading = analogRead(BPPin); // Analog playback from the buttons. result_bp=(bpReading+ 64) / 128; // (0.6V per diode) (5V/0.6~ 8 diodes) (1024/8=128) middle (256/2=64) delay(100); //Avoids the bounce } delay(100); //Avoids the bounce return result_bp-5; //The value 5 depends on the power supply of the circuit. } //================================================================================= END loadbp void setup(void) { Serial.begin(115200); } void loop(void) { switch(loadbp()){ case 1:Serial.println(F("UP")); break; case 2:Serial.println(F("DOWN")); break; case 3:Serial.println(F("SELECT")); break; } }
Avec une veille dans le temps durant 8s en consommation minimum.
Le programme propose une répétition de 8s plusieurs fois, ceci permet une consommation très réduite de l'Arduino et permet de faire une alimentation par batterie ou piles.
#include <avr/sleep.h> #include <avr/wdt.h> const byte LED = 13; volatile int rept = 5; //Nombre de répétition 225x8S pour 30min prévoir 30min*60s/8s=225cycles //*********************************** WATCHDOG TIMER *************************************** // Interruption watchdog ISR (WDT_vect) { wdt_disable(); // desactive watchdog } // end of WDT_vect // paramètre : 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9=8 sec void setup_watchdog(int ii) { byte bb; int ww; if (ii > 9 ) ii = 9; bb = ii & 7; if (ii > 7) bb |= (1 << 5); bb |= (1 << WDCE); ww = bb; // Clear the reset flag MCUSR &= ~(1 << WDRF); // start timed sequence WDTCSR |= (1 << WDCE) | (1 << WDE); // set new watchdog timeout value WDTCSR = bb; WDTCSR |= _BV(WDIE); } void sleep_watchdog() { //Veille temporisée setup_watchdog(9); //Programme le watchdog à 8s wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); } // fin de la veille //*********************************** FIN WATCHDOG TIMER *************************************** void flash (int nbr) { for (byte i = 0; i < nbr; i++) { digitalWrite (LED, HIGH); delay (50); digitalWrite (LED, LOW); delay (50); } } void setup () { // paramètre : 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9=8 sec pinMode (LED, OUTPUT); Serial.begin(9600); } void loop (){ Serial.print("Rept="); int temps=5*4-rept*4; Serial.print(temps); Serial.println(" s"); if (rept > 1) { flash (1); //1 flash toute les tempo rept--; } else { rept = 5; flash (1); //Ou programme de mesure } sleep_watchdog(); }
L'interruption sur la broche D2, en Pull-up permet de sortir du mode veille.
Les différents type de changement d'état:
#include <avr/sleep.h> #include <avr/power.h> void setup() { pinMode(13, OUTPUT); } void wakeCallback() //Ne pas supprimer { //Au moment du réveil, si il y un truc spécial hors loop } void sleepPwrDown() { set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); attachInterrupt(0, wakeCallback, CHANGE); //Changement d'état power_all_disable(); sleep_mode(); //Attente de l'interruption 0 //sleep_disable(); power_all_enable(); //Réactivation de toutes les fonctions } void loop() { for ( int i = 0 ; i < 5 ; i++ ) { digitalWrite(13, LOW); delay(500); digitalWrite(13, HIGH); delay(500); } digitalWrite(13, LOW); sleepPwrDown(); digitalWrite(13, HIGH); }