/* ex0010_blink_pin13 Fait clignoter la LED de la PIN 13 régulièrement */ void setup() { //============ // Initialise la PIN digital 13 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino pinMode(13, OUTPUT); } // setup void loop() { //=========== digitalWrite(13, HIGH); // set LED on delay(500); // wait for some milliseconds digitalWrite(13, LOW); // set the LED off delay(500); // wait for some milliseconds } // loop
/* ex0020_blink_pin13_12_11 Fait clignoter la LED de la PIN 13 régulièrement, la PIN 12 deux fois plus lentement, la PIN 11 quatre fois plus lentement. */ void setup() { //============ // Initialise les PINs digital 13, 12 et 11 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino pinMode(13, OUTPUT); pinMode(12, OUTPUT); pinMode(11, OUTPUT); // Fait clignoter les LED en 13, 12 et 10, 15 fois à une période de 2x100=200 [ms] for (int nn=1; nn<=15; nn++) { digitalWrite(13, HIGH); digitalWrite(12, HIGH); digitalWrite(11, HIGH); delay(100); digitalWrite(13, LOW); digitalWrite(12, LOW); digitalWrite(11, LOW); delay(100); } // for } // setup void loop() { //=========== digitalWrite(13, HIGH); // set the LED on digitalWrite(12, HIGH); digitalWrite(11, HIGH); delay(500); // wait for some milliseconds digitalWrite(13, LOW); // set the LED off delay(500); // wait for some milliseconds digitalWrite(13, HIGH); digitalWrite(12, LOW); delay(500); digitalWrite(13, LOW); delay(500); // wait for some milliseconds digitalWrite(13, HIGH); digitalWrite(12, HIGH); digitalWrite(11, LOW); delay(500); digitalWrite(13, LOW); delay(500); // wait for some milliseconds digitalWrite(13, HIGH); digitalWrite(12, LOW); delay(500); digitalWrite(13, LOW); delay(500); // wait for some milliseconds } // loop
/* ex0030_attenue_pin11_pause Fait varier l'intensité de la LED connectée à la PIN 11, en faisant une petite pause lorsque la PIN 11 est à 0 */ #define pinA 11 // Définition d'une constante. int nBrightness = 0; // Intensité de la LED int nFadeAmount = 1; // Quantité de variation de l'intensité void setup() { //============= // Initialise le PIN digital pinA comme OUTPUT pinMode(pinA, OUTPUT); } void loop() { //============ // Etablit l'intensité de la LED connectée à la PIN pinA analogWrite(pinA, nBrightness); // Change l'intensité de la LED nBrightness = nBrightness + nFadeAmount; // Si on atteint une extreme, change le sens de variation d'intensité if (nBrightness == 0 || nBrightness == 255) { nFadeAmount = -nFadeAmount; // Si l'intensité est à son minimum, éteint la LED et attend un petit moment if (nBrightness == 0) { digitalWrite(pinA, LOW); delay(500); } } // wait for 10 milliseconds to see the dimming effect delay(10); } // loop
/* ex0040_lecture_bouton Lecture de l'état du bouton connecté à la PIN 12 S'il est pressé, allume la LED connectée à la PIN 13 durant un instant */ #define pinOut 13 // Définition de constantes. #define pinIn 12 void setup() { //============ // Initialise la PIN digital 13 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino // Initialise la PIN digital pinIn comme INPUT pinMode(pinOut, OUTPUT); pinMode(pinIn, INPUT); digitalWrite(pinOut, LOW); // set the LED off } // setup void loop() { //=========== if (digitalRead(pinIn) == 1) { // On a pressé sur le bouton qui met la PIN pinIn à l'état haut (HIGH) digitalWrite(pinOut, HIGH); // set LED on delay(1000); // wait for some milliseconds } digitalWrite(pinOut, LOW); // set the LED off delay(50); // Juste pour voir qu'elle s'éteint, meme si le bouton reste pressé } // loop
/* ex0050_lecture_bouton_Serial_print Lecture de l'état du bouton connecté à la PIN 12 S'il est pressé, allume la LED connectée à la PIN 13 et affiche dans le "moniteur série" (Ctrl+Maj+M) l'état de la PIN 12, c'est-à-dire l'état "pressé" ou non du bouton. Ce programme utilise la PIN 1 (tx) pour la communication série. S'il y avait lecture "Serial.read()", la PIN 0 (rx) serait utilisée. Le défaut, c'est qu'on détecte plusieurs fois que le bouton est pressé. C.f. ex0051_lecture_bouton_Serial_print pour une amélioration C.f. ex0052_lecture_bouton_Serial_print pour une meilleure amélioration */ #define pinOut 13 // Définition de constantes. #define pinIn 12 int nCompteur = 0; void setup() { //============ // Initialise la PIN digital 13 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino // Initialise la PIN digital pinIn comme INPUT pinMode(pinOut, OUTPUT); pinMode(pinIn, INPUT); digitalWrite(pinOut, LOW); // set the LED off Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== if (digitalRead(pinIn) == 1) { // On a pressé sur le bouton qui met la PIN pinIn à l'état haut (HIGH) digitalWrite(pinOut, HIGH); // set LED on nCompteur = nCompteur + 1; Serial.println(nCompteur); // rien correspond à DEC // "println" envoie un retour à la ligne, contrairement à "print". // Serial.print(nCompteur, DEC); // sortie par défaut, sortie sous forme de string // Si nCompteur = 37, sortie = "37", donc deux caractères // Si nCompteur = 254, sortie = "254", donc trois caractères // Serial.print(nCompteur, BIN); // sortie binaire sous forme de string // Serial.print(nCompteur, HEX); // sortie hexadécimale sous forme de string // Serial.print(nCompteur, BYTE); // sortie sous forme de nombre // Si bIn = 37, sortie = 37, un nombre // Serial.write(nCompteur); // sortie sous forme du nombre se trouvant dans la variable } else { digitalWrite(pinOut, LOW); // set the LED off } } // loop
/* ex0051_lecture_bouton_Serial_print_ameliore Lecture de l'état du bouton connecté à la PIN 12 S'il est pressé, allume la LED connectée à la PIN 13 et affiche dans le "moniteur série" (Ctrl+Maj+M) l'état de la PIN 12, c'est-à-dire l'état "pressé" ou non du bouton. Ce programme utilise la PIN 1 (tx) pour la communication série. S'il y avait lecture "Serial.read()", la PIN 0 (rx) serait utilisée. Amélioration de ex0050_lecture_bouton_Serial_print pour une amélioration Il y a encore le problème que parfois, une pression sur le bouton est comptée à double. C'est typique des rebonds. C.f. ex0052_lecture_bouton_Serial_print_amelioration_bis pour une meilleure amélioration */ #define pinOut 13 // Définition de constantes. #define pinIn 12 int nCompteur = 0; int nEtatLast = 0; // mémorise le dernier état du bouton void setup() { //============ // Initialise la PIN digital pinOut comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino // Initialise la PIN digital pinIn comme INPUT pinMode(pinOut, OUTPUT); pinMode(pinIn, INPUT); digitalWrite(pinOut, LOW); // set the LED off Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== if (digitalRead(pinIn) == 1) { // On a pressé sur le bouton qui met la PIN pinIn à l'état haut (HIGH) // Test qu'il n'était pas déjà pressé avant. if (nEtatLast == 0) { nEtatLast = 1; // Mémorise qu'on a pressé sur le bouton digitalWrite(pinOut, HIGH); // set LED on nCompteur = nCompteur + 1; Serial.println(nCompteur); // rien correspond à DEC // "println" envoie un retour à la ligne, contrairement à "print". // Serial.print(nCompteur, DEC); // sortie par défaut, sortie sous forme de string // Si nCompteur = 37, sortie = "37", donc deux caractères // Si nCompteur = 254, sortie = "254", donc trois caractères // Serial.print(nCompteur, BIN); // sortie binaire sous forme de string // Serial.print(nCompteur, HEX); // sortie hexadécimale sous forme de string // Serial.print(nCompteur, BYTE); // sortie sous forme de nombre // Si bIn = 37, sortie = 37, un nombre // Serial.write(nCompteur); // sortie sous forme du nombre se trouvant dans la variable } } else { // bouton relaché nEtatLast = 0; // Mémorise qu'on a relaché le bouton digitalWrite(pinOut, LOW); // set the LED off } } // loop
/* ex0052_lecture_bouton_Serial_print_ameliore_bis Lecture de l'état du bouton connecté à la PIN 12 S'il est pressé, allume la LED connectée à la PIN 13 et affiche dans le "moniteur série" (Ctrl+Maj+M) l'état de la PIN 12, c'est-à-dire l'état "pressé" ou non du bouton. Ce programme utilise la PIN 1 (tx) pour la communication série. S'il y avait lecture "Serial.read()", la PIN 0 (rx) serait utilisée. Amélioration de ex0051_lecture_bouton_Serial_print_ameliore Une petite amélioration en ajoutant une attente lorsque le bouton a été pressé, pour éviter les rebonds et compter à double une pression sur le bouton. */ #define pinOut 13 // Définition de constantes. #define pinIn 12 int nCompteur = 0; int nEtatLast = 0; // mémorise le dernier état du bouton void setup() { //============ // Initialise la PIN digital 13 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino // Initialise la PIN digital pinIn comme INPUT pinMode(pinOut, OUTPUT); pinMode(pinIn, INPUT); digitalWrite(pinOut, LOW); // set the LED off Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== if (digitalRead(pinIn) == 1) { // On a pressé sur le bouton qui met la PIN pinIn à l'état haut (HIGH) // Test qu'il n'était pas déjà pressé avant. if (nEtatLast == 0) { nEtatLast = 1; // Mémorise qu'on a pressé sur le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds digitalWrite(pinOut, HIGH); // set LED on nCompteur = nCompteur + 1; Serial.println(nCompteur); // rien correspond à DEC } } else { // bouton relaché nEtatLast = 0; // Mémorise qu'on a relaché le bouton digitalWrite(pinOut, LOW); // set the LED off } } // loop
/* ex0055_lecture_bouton_frequence_variable Lecture de l'état du bouton connecté à la PIN 12 S'il est pressé, augmente la valeur d'un compteur. Lecture de l'état du bouton connecté à la PIN 11 S'il est pressé, diminue la valeur d'un compteur. Affiche dans le "moniteur série" (Ctrl+Maj+M) la valeur du compteur. En plus, fait clignoter une LED a une fréquence égale à (1/2) de celle du compteur. Évite que le compteur soit plus petit que 1. Des améliorations viendrons dans une version qui utilisent une variable de temps et la fonction de lecture de temps : micros(); */ #define pinOut 13 // Définition de constantes. #define pinInA 12 #define pinInB 11 int nCompteur = 5; int nEtatLast12 = 0; // mémorise le dernier état du bouton 12 int nEtatLast11 = 0; // mémorise le dernier état du bouton 11 byte bEtatLED = LOW; // L'état de la LED void setup() { //============ // Initialise la PIN digital 13 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino // Initialise les PINs digitals pinInA et pinInB comme INPUT pinMode(pinOut, OUTPUT); pinMode(pinInA, INPUT); pinMode(pinInB, INPUT); digitalWrite(pinOut, LOW); // set the LED off Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== if (digitalRead(pinInA) == 1) { // On a pressé sur le bouton qui met la PIN pinInA à l'état haut (HIGH) // Test qu'il n'était pas déjà pressé avant. if (nEtatLast12 == 0) { nEtatLast12 = 1; // Mémorise qu'on a pressé sur le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds nCompteur = nCompteur + 1; Serial.println(nCompteur); } } else { // bouton relaché nEtatLast12 = 0; // Mémorise qu'on a relaché le bouton } if (digitalRead(pinInB) == 1) { // On a pressé sur le bouton qui met la PIN pinInB à l'état haut (HIGH) // Test qu'il n'était pas déjà pressé avant. if (nEtatLast11 == 0) { nEtatLast11 = 1; // Mémorise qu'on a pressé sur le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds nCompteur = nCompteur - 1; if (nCompteur < 1) nCompteur = 1; // Test que le compteur ne soit pas inférieur à 1. Serial.println(nCompteur); } } else { // bouton relaché nEtatLast11 = 0; // Mémorise qu'on a relaché le bouton } // Change l'état de la LED bEtatLED = 1 - bEtatLED; // change son état digitalWrite(pinOut, bEtatLED); delay(1000 / nCompteur); // attente correspondant à la fréquence désirée. } // loop
/* ex0060_lecture_Serial_read Si le caractère '0' est envoyé, éteint la LED connectée à la PIN 13 Si le caractère '1' est envoyé, allume la LED connectée à la PIN 13 Si le caractère '2' est envoyé, éteint la LED connectée à la PIN 12 Si le caractère '3' est envoyé, allume la LED connectée à la PIN 12 Si le caractère '4' est envoyé, éteint la LED connectée à la PIN 11 Si le caractère '5' est envoyé, allume la LED connectée à la PIN 11 Il affiche à travers le port série le nombre total de caractères qu'il a lu. Ce programme utilise la PIN 1 (tx) pour la communication série. Il utilise aussi la PIN 0 (rx) pour la lecture série "Serial.read()". */ #define pinA 13 // Définition de constantes. #define pinB 12 #define pinC 11 int nCompteur = 0; char cIn = '0'; // Pour la lecture du caractère envoyé par le port série. void setup() { //============ // Initialise les PINs digital pinA, pinB et pinC comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino pinMode(pinA, OUTPUT); pinMode(pinB, OUTPUT); pinMode(11, OUTPUT); Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== if (Serial.available()) { // des données sont disponibles sur le port série cIn = Serial.read(); // Lecture d'un caractère disponible sur le port série if (cIn == '1') { digitalWrite(pinA, HIGH); // set LED on } else if (cIn == '0') { digitalWrite(pinA, LOW); // set LED off } else if (cIn == '3') { digitalWrite(pinB, HIGH); // set LED on } else if (cIn == '2') { digitalWrite(pinB, LOW); // set LED off } else if (cIn == '5') { digitalWrite(pinC, HIGH); // set LED on } else if (cIn == '4') { digitalWrite(pinC, LOW); // set LED off } //else // On ignore la valeur des autres caratères // Indique le nombre total de caractères lus. nCompteur = nCompteur + 1; Serial.println(nCompteur); } } // loop
/* ex0070_lecture_analogique_resistance_variable Lecture d'une tension variable, réglée avec une résistance variable. Affiche à travers le port série la tension lue. Ce programme utilise la PIN 1 (tx) pour la communication série. Il utilise aussi la PIN 0 (rx) pour la lecture série "Serial.read()". */ int nSensorValue = 0; // Valeur lue sur le port analogique A0 int nSensorValueOld = 0; // Dernière valeur lue sur le port analogique A0 int nOutputValue = 0; // Valeur écrite sur la PIN 11, pour faire varier l'intensité de la LED void setup() { //============ // Initialise la PIN digital 11 comme OUTPUT pinMode(11, OUTPUT); Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== nSensorValue = analogRead(A0); // Lecture de la tension sur le port analogique A0 // La tension varie entre 0 et 5 Volts, correspondant // aux nombres entre 0 et 1023. if (abs(nSensorValue - nSensorValueOld) > 10) { // La valeur du port analogique A0 a changé, nSensorValueOld = nSensorValue; // Mémorise la nouvelle valeur du port analogique A0 // Convertie la valeur lue, qui est entre 0 et 1023 en un nombre entre 0 et 255. nOutputValue = map(nSensorValue, 0, 1023, 0, 255); analogWrite(11, nOutputValue); // Change la luminosité de la LED // affiche la valeur lue Serial.println(nSensorValue); } } // loop
# py0020_serial_arduino.py # Test de communication à travers le port série avec un arduino # Depuis Synaptic, j'ai installé le module "python-serial" (sous linux) # c.f. https://playground.arduino.cc/Interfacing/Python # c.f. Arduino : ex0070_lecture_analogique_resistance_variable.ino import serial ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1) # timeout en secondes nVal = 0 # Valeur reçue par le port série nCpt = 0 # compteur de sécurité, pour être sur que le programme s'arrête. strS = "chaine de caractères" # pour récupérer la chaine de caractères du port série # Lectures pour vider le buffer du port série. strS = ser.readline() strS = ser.readline() # Boucle pour attendre de recevoir un nombre du port série while (nVal < 1015) & (nCpt < 30): nCpt = nCpt + 1 strS = ser.readline() # Lecture du port série # print(strS) # pour information # Conversion du nombre reçu sous forme de tableau en nombre. nVal = 0 for cc in strS: if (cc >= ord('0')) and (cc <= ord('9')): nVal = 10 * nVal + cc - ord('0'); if (len(strS) > 0): # Un nombre a été reçu du port série, affiche-le print(nVal) print("Terminé")
/* ex0080_temps_bouton_presse Lecture de l'état du bouton connecté à la PIN 12 S'il est pressé, allume la LED connectée à la PIN 13 Mesure en micro secondes durant combien de temps il est pressé affiche dans le "moniteur série" (Ctrl+Maj+M) ce temps. Ce programme utilise la PIN 1 (tx) pour la communication série. S'il y avait lecture "Serial.read()", la PIN 0 (rx) serait utilisée. Avec une petite amélioration en ajoutant une attente lorsque le bouton a été pressé, pour éviter les rebonds et compter à double une pression sur le bouton. */ int nEtatLast = 0; // mémorise le dernier état du bouton unsigned long lwTimeStart = 0; // Temps en micros secondes du départ de bouton appuyé unsigned long lwTimeStop = 0; // Temps en micros secondes d'arret du bouton void setup() { //============ // Initialise la PIN digital 13 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino // Initialise la PIN digital 12 comme INPUT pinMode(13, OUTPUT); pinMode(12, INPUT); digitalWrite(13, LOW); // set the LED off Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== if (digitalRead(12) == 1) { // On a pressé sur le bouton qui met la PIN 12 à l'état haut (HIGH) // Test qu'il n'était pas déjà pressé avant. if (nEtatLast == 0) { lwTimeStart = micros(); nEtatLast = 1; // Mémorise qu'on a pressé sur le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds digitalWrite(13, HIGH); // set LED on } } else { // bouton relaché if (nEtatLast == 1) { // On vient de relacher le bouton lwTimeStop = micros(); nEtatLast = 0; // Mémorise qu'on a relaché le bouton Serial.println(lwTimeStop - lwTimeStart); // Affiche en micro secondes le temps durant lequel le bouton était pressé digitalWrite(13, LOW); // set the LED off } } } // loop
/* ex0085_lecture_bouton_frequence_variable_ameliore Amélioration de "ex0055_lecture_bouton_frequence_variable" Une autre amélioration est disponible sous : "ex0086_lecture_bouton_frequence_variable_ameliore_bis" en ayant une fréquence beaucoup plus précise, en utilisant la fonction "micros()". Lecture de l'état du bouton connecté à la PIN 12 S'il est pressé, augmente la valeur d'un compteur. Lecture de l'état du bouton connecté à la PIN 11 S'il est pressé, diminue la valeur d'un compteur. Affiche dans le "moniteur série" (Ctrl+Maj+M) la valeur du compteur. En plus, fait clignoter une LED a une fréquence égale à (1/2) de celle du compteur. Évite que le compteur soit plus petit que 1. */ #define pinOut 13 // Définition de constantes. #define pinInA 12 #define pinInB 11 int nCompteur = 5; int nEtatLast12 = 0; // mémorise le dernier état du bouton 12 int nEtatLast11 = 0; // mémorise le dernier état du bouton 11 byte bEtatLED = LOW; // L'état de la LED unsigned long lwTimeNow = 0; // Temps actuel en micros secondes unsigned long lwTimeNext = 0; // Temps définissant le prochain changement d'état en micros secondes // qui aura lieu lorsque (lwTimeNow - lwTimeNext >= lwTimeDelta= unsigned long lwTimeDelta = 200000; // Temps en micros secondes à attendre avant le prochain changement d'état void setup() { //============ // Initialise la PIN digital pinOut comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino // Initialise les PINs digitals pinInA et pinInB comme INPUT pinMode(pinOut, OUTPUT); pinMode(pinInA, INPUT); pinMode(11, INPUT); digitalWrite(13, LOW); // set the LED off Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. lwTimeNow = micros(); lwTimeNext = micros(); } // setup void loop() { //=========== // Test s'il faut changé l'état de la LED lwTimeNow = micros(); if (lwTimeNow - lwTimeNext >= lwTimeDelta) { // Change l'état de la LED bEtatLED = 1 - bEtatLED; // change son état digitalWrite(pinOut, bEtatLED); lwTimeNext = lwTimeNow; // Temps définissant le prochain changement d'état } if ((lwTimeNow - lwTimeNext < lwTimeDelta - 1200) || (nCompteur > 800)) { // Ne lit sur un bouton que si le temps de traitement est suffisamment long if (digitalRead(pinInA) == 1) { // On a pressé sur le bouton qui met la PIN pinInA à l'état haut (HIGH) // Test qu'il n'était pas déjà pressé avant. if (nEtatLast12 == 0) { nEtatLast12 = 1; // Mémorise qu'on a pressé sur le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds nCompteur = nCompteur + 1; Serial.println(nCompteur); lwTimeDelta = 1000000 / nCompteur; // Temps en micros secondes à attendre avant le prochain changement d'état } } else { // bouton relaché if (nEtatLast12 == 1) { nEtatLast12 = 0; // Mémorise qu'on a relaché le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds } } if (digitalRead(pinInB) == 1) { // On a pressé sur le bouton qui met la PIN pinInB à l'état haut (HIGH) // Test qu'il n'était pas déjà pressé avant. if (nEtatLast11 == 0) { nEtatLast11 = 1; // Mémorise qu'on a pressé sur le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds nCompteur = nCompteur - 1; if (nCompteur < 1) nCompteur = 1; // Test que le compteur ne soit pas inférieur à 1. Serial.println(nCompteur); lwTimeDelta = 1000000 / nCompteur; // Temps en micros secondes à attendre avant le prochain changement d'état } } else { // bouton relaché if (nEtatLast11 == 1) { nEtatLast11 = 0; // Mémorise qu'on a relaché le bouton delay(1); // attente d'une milliseconde, pour éviter les rebonds } } } } // loop
/* ex0090_lecture_analogique_photo_resistance Lecture d'une tension variable, réglée par la luminosité arrivant sur une photo résistance. Allume des LEDs parmis 3, en fonction de la luminosité. Donne sur les LEDs un codage binaire de l'intensité lue. */ int nSensorValue = 0; // Valeur lue sur le port analogique A0 int nConvertValue = 0; // Valeur lue, convertit dans un autre intervalle void setup() { //============ // Initialise les PINs digital 13, 12 et 11 comme OUTPUT // La PIN 13 a une LED connectée sur la plupart des cartes Arduino pinMode(13, OUTPUT); pinMode(12, OUTPUT); pinMode(11, OUTPUT); // Pour TESTER //Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== nSensorValue = analogRead(A0); // Lecture de la tension sur le port analogique A0 // La tension varie entre 0 et 5 Volts, correspondant // aux nombres entre 0 et 1023. // Convertie la valeur lue, qui est entre 0 et 1023 en un nombre entre 0 et 7. nConvertValue = map(nSensorValue, 0, 1023, 0, 7); // Test le niveau global d'intensité if (nConvertValue >= 4) { digitalWrite(13, HIGH); } else { digitalWrite(13, LOW); } if ((nConvertValue % 4) >= 2) { digitalWrite(12, HIGH); } else { digitalWrite(12, LOW); } if ((nConvertValue % 2) >= 1) { digitalWrite(11, HIGH); } else { digitalWrite(11, LOW); } // affiche la valeur convertie POUR TESTER // Serial.println(nConvertValue); delay(500); } // loop
/* ex0100_mesure_temps_aide_photo_resistance Mesure du temps de passage d'un objet devant une photorésistance Le temps sera transmis à travers le port série. Mesure durant combien de microsecondes la photorésistance recoit une luminosité faible. L'utilisation de la lecture analogique est lente, elle prend environ 100 micro-secondes, donc la précision est limitée. Seul l'entrée analogique A0 est utilisée. La PIN 13 est utilisée pour indiquer que la mesure est en cours. Ce programme utilise la PIN 1 (tx) pour la communication série. Il utilise aussi la PIN 0 (rx) pour la lecture série "Serial.read()". */ int nSensorValue = 0; // Valeur lue sur le port analogique A0 int nSensorValueOld = 0; // Dernière valeur lue sur le port analogique A0 unsigned long lwTimeStart = 0; // Temps en micros secondes du départ de bouton appuyé unsigned long lwTimeStop = 0; // Temps en micros secondes d'arret du bouton void setup() { //============ // Initialise la PIN digital 13 comme OUTPUT pinMode(13, OUTPUT); digitalWrite(13, LOW); nSensorValueOld = analogRead(A0); // Lecture de la tension sur le port analogique A0 // La tension varie entre 0 et 5 volts, correspondant // aux nombres entre 0 et 1023. Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== nSensorValue = analogRead(A0); // Lecture de la tension sur le port analogique A0 // La tension varie entre 0 et 5 volts, correspondant // aux nombres entre 0 et 1023. if ((nSensorValue < 500) & (nSensorValueOld > 500)) { // Début de la mesure de temps lwTimeStart = micros(); nSensorValueOld = nSensorValue; // < 500, donc une mesure est en cours digitalWrite(13, HIGH); // Allume la LED pour indiquer qu'une mesure est en cours } if ((nSensorValue > 550) & (nSensorValueOld < 500)) { // Fin de la mesure de temps lwTimeStop = micros(); nSensorValueOld = nSensorValue; // > 500, donc une prochaine mesure peut etre faite digitalWrite(13, LOW); // Eteint la LED, ce qui indique la fin de mesure. // Affiche le temps Serial.println(lwTimeStop - lwTimeStart); } } // loop
/* ex0110_photo_resistance_lien_analogique_digital L'utilisation de la lecture analogique est lente, elle prend environ 100 micro-secondes. C'est la raison pour laquelle, il peut etre préférable d'utiliser une entrée digitale pour mesurer l'état de la résistance variable. Le but de ce code est de voir pour quelle plage de valeurs mesurées sur A0, une mesure digitale donne 0. La PIN 13 est utilisée pour indiquer la valeur digitale lue. Ce programme utilise la PIN 1 (tx) pour la communication série. Il utilise aussi la PIN 0 (rx) pour la lecture série "Serial.read()". RESULTATS : Il y a une hystérésis, l'état digital dépend de son éta précédent. Si l'état de la PIN 8 est à 1, A0 doit descendre en dessous de 450 pour que la PIN 8 passe à 0 Si l'état de la PIN 8 est à 0, A0 doit monter en-dessus de 520 pour que la PIN 8 passe à 1 */ int nSensorValue = 0; // Valeur lue sur le port analogique A0 int nDigitalValue = 0; // Valeur lue sur l'entrée digitale 8 void setup() { //============ pinMode(13, OUTPUT); // Initialise la PIN digital 13 comme OUTPUT pinMode( 8, INPUT); // Initialise la PIN digital 8 comme INPUT digitalWrite(13, LOW); Serial.begin(115200); // Initialise la communication série à une haute vitesse. // La vitesse de 9600 bauds est souvent utilisée par défaut. } // setup void loop() { //=========== nSensorValue = analogRead(A0); // Lecture de la tension sur le port analogique A0 // La tension varie entre 0 et 5 volts, correspondant // aux nombres entre 0 et 1023. nDigitalValue = digitalRead( 8); // Lecture de l'état de l'entrée de la PIN 8 // La LED indique l'état digital lu. if (nDigitalValue > 0) digitalWrite(13, HIGH); else digitalWrite(13, LOW); // Affiche les états lus, analogique et digital Serial.print("A0 = "); Serial.print(nSensorValue); Serial.print(" PIN8 = "); Serial.println(nDigitalValue); // Ici, l'affichage passe à la ligne delay(500); } // loop
/* ex0120_buzzer_avec_photo_resistance Un buzzer émet un son à une fréquence dépendante de la valeur lue sur l'entrée A0, déterminée par la lumière arrivant sur une photo-résistance. */ int nSensorValue = 0; // Valeur lue sur le port analogique A0 unsigned long lwTimeLast = 0; // Dernier temps lu en micros secondes unsigned long lwTimeNow = 0; // Temps lu en micros secondes void setup() { //============ pinMode(12, OUTPUT); lwTimeLast = micros(); // Lecture du temps au départ lwTimeNow = micros(); // Lecture du temps au départ } // setup void loop() { //=========== nSensorValue = analogRead(A0); // Lecture de la tension sur le port analogique A0 // La tension varie entre 0 et 5 volts, correspondant // aux nombres entre 0 et 1023. // Attente, jusqu'à ce que le temps atteigne une demi période while (lwTimeNow - lwTimeLast < 5*nSensorValue) lwTimeNow = micros(); digitalWrite(12, HIGH); lwTimeLast = lwTimeNow; // mémorise le changement d'état // Nouvelle lecture de l'entrée analogique, pour régler la période. nSensorValue = analogRead(A0); // Attente, jusqu'à ce que le temps atteigne une demi période while (lwTimeNow - lwTimeLast < 5*nSensorValue) lwTimeNow = micros(); digitalWrite(12, LOW); lwTimeLast = lwTimeNow; // mémorise le changement d'état } // loop
/* ex0125_liquidCrystal_Simple_Hello_World.ino Utilise l'affichage LCD (à cristaux liquides), pour afficher du texte. Une version plus simple à utiliser et plus complète est présenté dans "ex0130_liquid_crystal_hello_world.ino" C'est un "Shield", la connexion est plus simple et de plus, 5 boutons en plus du bouton reset sont ajoutés, pour avoir des entrées possibles. Ainsi, l'Arduino devient autonome pour beaucoup d'applications, sans nécessité d'un ordinateur pour l'utiliser et afficher des résultats. Ici, l'afficheur écrit "Hello World!" et "Bonjour a tous!" Affichage d'un texte. Lecture de l'état des Pushbutton. Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hello World!" to the LCD and shows the time. The circuit: * LCD RS pin to digital pin 2 * LCD Enable pin to digital pin 3 * LCD D4 pin to digital pin 4 * LCD D5 pin to digital pin 5 * LCD D6 pin to digital pin 6 * LCD D7 pin to digital pin 7 * 10K resistor: * ends to +5V and ground * wiper to LCD VO pin (pin 3) Voir : http://www.arduino.cc/en/Tutorial/LiquidCrystal PINs qui restent libre et utilisables : 13, 12, 11, 10, 9, 8, 1 et 0 Les PINs 0 et 1 sont utilisés pour la transmission série par USB, L'afficheur HD44780s peut être préprogrammé avec deux jeux de caractères, Soit asiatique, soit européen. c.f. : http://www.martyncurrey.com/arduino-with-hd44780-based-lcds/ Si le jeu par défaut est asiatique, il n'y a pas de caractères accentués. On peut en créer 8, mais l'affichage se complique un peu. Aussi c.f. : http://arduino-projects4u.com/ldc-character/ */ // Inclus la librairie qui gère l'affichage #include <LiquidCrystal.h> // Initialisation, pour indiquer quelles sont les PINs utilisées par l'afficheur LCD //LiquidCrystal lcd(RS, E, D4, D5, D6, D7); LiquidCrystal lcd( 2, 3, 4, 5, 6, 7); // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Un "array" de caractères, pour conversion de nombre en un String. String strS = ""; // Une chaine de caractères. // temps en micro secondes unsigned long lwTemps = 0; // sur 32 bits, de 0 à 2^32 -1 = 4'294'967'295 int sensorValue = 0; // valeur de la résistance variable, lue sur l'entrée analogique A0. // Pour créer des caractères personnalisées. Matrices 8x5 (8 lignes et 5 colonnes) // Pour des exemples, voir : https://www.hackmeister.dk/2010/08/custom-lcd-characters-with-arduino/ // Pour créer des caractères simplement : https://omerk.github.io/lcdchargen/ byte smiley[8] = { B00000, B10001, B00000, B00000, B10001, B01110, B00000, B00000 }; byte agrave[8] = { // caractère "a accent grave" B01000, B00100, B01110, B00001, B01111, B10001, B01111, B00000 }; void setup() { //============ // Indique que l'afficheur LCD a deux lignes de 16 caractères lcd.begin(16, 2); // Création d'un caractère personnalisé, correspondant au code '0' // Les codes 0 à 7 sont disponnibles. lcd.createChar(0, smiley); lcd.createChar(1, agrave); // Affiche un message au départ, pour vérifier le bon fonctionnement. lcd.setCursor(0, 0); // Première colonne, première ligne lcd.print("Hello, World!"); lcd.setCursor(14, 0); // suit le texte par un smiley lcd.write(byte(0)); lcd.setCursor(0, 1); // Première colonne, deuxième ligne lcd.print("Bonjour "); lcd.setCursor(8, 1); // Première colonne, deuxième ligne lcd.write(byte(1)); // pour afficher le "a accent grave" lcd.setCursor(9, 1); // Première colonne, deuxième ligne lcd.print(" Tous!"); // Les caractères accentués ne passent pas. delay(3000); // Attente de 2 secondes lcd.setCursor(0, 0); // Première ligne lcd.print(" "); // efface le texte 16 caractères lcd.setCursor(0, 1); // Deuxième ligne lcd.print(" "); // efface le texte 16 caractères //lcd.autoscroll(); } // setup void loop() { //=========== // Affiche le temps écoulé depuis le dernier Reset, en secondes. delay(200); // attente en [ms] // Pour sprintf, c.f. https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm // %d ou %i pour signed decimal integer // %u pour unsigned decimal integer // %ld ou %li pour long signed decimal integer // %lu pour long unsigned decimal integer lwTemps = millis(); // temps en millisecondes. remis à 0 toutes les 4'294,967 secondes ( = 71,5827 minutes) //sprintf(acStr, "%8.3f", millis()/1000.0); // Ne fonctionne pas //sprintf(acStr, "%9lu", millis()); // Fonctionne bien dtostrf(millis()/1000.0, 12, 3, acStr); // Marche bien pour convertir un float en un string, avec un format // millis() retourne le nombre de millisecondes écoulé depuis la mise sous tension ou le reset de l'Arduino // Affichage du temps sur la 1ère ligne lcd.setCursor(0, 0); lcd.print(acStr); // La lecture des boutons se fait par l'intermédiaire du port A0 sensorValue = analogRead(0); sprintf(acStr, "%4d ", sensorValue); // Affichage de la valeur de la résistance variable sur la 2ème ligne lcd.setCursor(0, 1); lcd.print(acStr); lcd.setCursor(14, 1); // suit le texte par un smiley lcd.write(byte(0)); } // loop
/* ex0126_mesure_temperature_DS18B20.ino Exemple de code pour lire un unique capteur DS18B20 sur un bus 1-Wire. Programme et information récupérée de : https://www.carnetdumaker.net/articles/mesurer-une-temperature-avec-un-capteur-1-wire-ds18b20-et-une-carte-arduino-genuino/ Pour installer la librairie "OneWire", téléchargez le fichier .zip "OneWire.zip" ou "OneWire-master.zip" et enregistrez-le dans un dossier de votre choix. Lieu de téléchargement : https://github.com/PaulStoffregen/OneWire Cliquez sur "Clone or download" > Download ZIP. Depuis le logiciel Arduino, allez dans "Croquis" > "Inclure une bibliothèque" > "Ajoutez la bibliothèque .Zip..." Sélectionnez le fichier "OneWire.zip" que vous venez de télécharger. La librairie devrait ainsi etre installée. Cela a bien fonctionné avec la version 1.8.3. Les librairies sont stockées sous : $HOME/sketchbook/libraries c.f. : https://www.arduino.cc/en/Reference/Libraries Avec l'ancienne versions 1.0.5 de Arduino, le fichier "OneWire-master.zip" n'a pas été accepté. J'ai décompressé son contenu, renommé "OneWire-master" en "OneWire" et compressé dans "OneWire.zip", ensuite l'installation a fonctionnée. */ /* Dépendance pour le bus 1-Wire */ #include <OneWire.h> /* Broche du bus 1-Wire */ const byte pinBROCHE_ONEWIRE = 7; /* Code de retour de la fonction getTemperature() */ enum DS18B20_RCODES { READ_OK, // Lecture ok NO_SENSOR_FOUND, // Pas de capteur INVALID_ADDRESS, // Adresse reçue invalide INVALID_SENSOR // Capteur invalide (pas un DS18B20) }; // Création de l'objet OneWire pour manipuler le bus 1-Wire OneWire ds(pinBROCHE_ONEWIRE); byte getTemperature(float *temperature, byte reset_search) { //========================================================== // Fonction de lecture de la température via un capteur DS18B20. byte data[9], addr[8]; // data[] : Données lues depuis le scratchpad // addr[] : Adresse du module 1-Wire détecté /* Reset le bus 1-Wire ci nécessaire (requis pour la lecture du premier capteur) */ if (reset_search) { ds.reset_search(); } /* Recherche le prochain capteur 1-Wire disponible */ if (!ds.search(addr)) { // Pas de capteur return NO_SENSOR_FOUND; } /* Vérifie que l'adresse a été correctement reçue */ if (OneWire::crc8(addr, 7) != addr[7]) { // Adresse invalide return INVALID_ADDRESS; } /* Vérifie qu'il s'agit bien d'un DS18B20 */ if (addr[0] != 0x28) { // Mauvais type de capteur return INVALID_SENSOR; } /* Reset le bus 1-Wire et sélectionne le capteur */ ds.reset(); ds.select(addr); /* Lance une prise de mesure de température et attend la fin de la mesure */ ds.write(0x44, 1); delay(800); /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */ ds.reset(); ds.select(addr); ds.write(0xBE); /* Lecture du scratchpad */ for (byte i = 0; i < 9; i++) { data[i] = ds.read(); } /* Calcul de la température en degré Celsius */ *temperature = ((data[1] << 8) | data[0]) * 0.0625; // Pas d'erreur return READ_OK; } // getTemperature void setup() { //============ // Initialisation du port série pour afficher la température dans le "Moniteur série". Serial.begin(115200); } // setup void loop() { //=========== float temperature; delay(1000); // Lit la température ambiante byte bErr = getTemperature(&temperature, true); if (bErr != READ_OK) { // Erreur qui ne devrait pas se produire ?!? Serial.print("Erreur de lecture du capteur, erreur n° : "); Serial.println(bErr); // Cela ne donne pas beaucoup d'information, mais c.f. "enum DS18B20_RCODES ci-dessus" } else { /* Affiche la température */ Serial.print(F("Temperature : ")); Serial.print(temperature, 2); Serial.println("°C"); } } // loop
/* ex0127_liquidCrystal_Temperature_measure.ino c.f. ex0126_mesure_temperature_DS18B20.ino Mesure la température et l'affiche sur l'écran à LCD Mesure de température avec une précision de 0,5 à 0,25 °C, en utilisant le chip DS18B20. Utilise l'affichage LCD (à cristaux liquides), pour afficher du texte. Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hello World!" to the LCD and shows the time. The circuit: * LCD RS pin to digital pin 2 * LCD Enable pin to digital pin 3 * LCD D4 pin to digital pin 4 * LCD D5 pin to digital pin 5 * LCD D6 pin to digital pin 6 * LCD D7 pin to digital pin 7 * 10K resistor: * ends to +5V and ground * wiper to LCD VO pin (pin 3) Voir : http://www.arduino.cc/en/Tutorial/LiquidCrystal PINs qui restent libre et utilisables : 13, 12, 11, 10, 9, 8, 1 et 0 Les PINs 0 et 1 sont utilisés pour la transmission série par USB, L'afficheur HD44780s peut être préprogrammé avec deux jeux de caractères, Soit asiatique, soit européen. c.f. : http://www.martyncurrey.com/arduino-with-hd44780-based-lcds/ Si le jeu par défaut est asiatique, il n'y a pas de caractères accentués. On peut en créer 8, mais l'affichage se complique un peu. Aussi c.f. : http://arduino-projects4u.com/ldc-character/ */ // Inclus la librairie qui gère l'affichage #include <LiquidCrystal.h> /* Dépendance pour le bus 1-Wire */ #include <OneWire.h> // Initialisation, pour indiquer quelles sont les PINs utilisées par l'afficheur LCD //LiquidCrystal lcd(RS, E, D4, D5, D6, D7); LiquidCrystal lcd( 2, 3, 4, 5, 6, 7); // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Un "array" de caractères, pour conversion de nombre en un String. String strS = ""; // Une chaine de caractères. /* Broche du bus 1-Wire */ const byte pinBROCHE_ONEWIRE = 12; /* Code de retour de la fonction getTemperature() */ enum DS18B20_RCODES { READ_OK, // Lecture ok NO_SENSOR_FOUND, // Pas de capteur INVALID_ADDRESS, // Adresse reçue invalide INVALID_SENSOR // Capteur invalide (pas un DS18B20) }; // Création de l'objet OneWire pour manipuler le bus 1-Wire OneWire ds(pinBROCHE_ONEWIRE); byte getTemperature(float *temperature, byte reset_search) { //========================================================== // Fonction de lecture de la température via un capteur DS18B20. byte data[9], addr[8]; // data[] : Données lues depuis le scratchpad // addr[] : Adresse du module 1-Wire détecté /* Reset le bus 1-Wire ci nécessaire (requis pour la lecture du premier capteur) */ if (reset_search) { ds.reset_search(); } /* Recherche le prochain capteur 1-Wire disponible */ if (!ds.search(addr)) { // Pas de capteur return NO_SENSOR_FOUND; } /* Vérifie que l'adresse a été correctement reçue */ if (OneWire::crc8(addr, 7) != addr[7]) { // Adresse invalide return INVALID_ADDRESS; } /* Vérifie qu'il s'agit bien d'un DS18B20 */ if (addr[0] != 0x28) { // Mauvais type de capteur return INVALID_SENSOR; } /* Reset le bus 1-Wire et sélectionne le capteur */ ds.reset(); ds.select(addr); /* Lance une prise de mesure de température et attend la fin de la mesure */ ds.write(0x44, 1); delay(800); /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */ ds.reset(); ds.select(addr); ds.write(0xBE); /* Lecture du scratchpad */ for (byte i = 0; i < 9; i++) { data[i] = ds.read(); } /* Calcul de la température en degré Celsius */ *temperature = ((data[1] << 8) | data[0]) * 0.0625; // Pas d'erreur return READ_OK; } // getTemperature void setup() { //============ // Indique que l'afficheur LCD a deux lignes de 16 caractères lcd.begin(16, 2); // Affiche un message au départ, pour vérifier le bon fonctionnement. lcd.setCursor(0, 0); // Première colonne, première ligne lcd.print("Temperature"); lcd.setCursor(14, 0); // suit le texte par un smiley lcd.setCursor(0, 1); // Première colonne, deuxième ligne lcd.print("mesure "); lcd.setCursor(8, 1); // Première colonne, deuxième ligne delay(3000); // Attente de 2 secondes lcd.setCursor(0, 0); // Première ligne lcd.print(" "); // efface le texte 16 caractères lcd.setCursor(0, 1); // Deuxième ligne lcd.print(" "); // efface le texte 16 caractères //lcd.autoscroll(); } // setup void loop() { //=========== // Affiche la température lue avec un chip DS18b20 delay(200); // attente en [ms] // Pour sprintf, c.f. https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm // %d ou %i pour signed decimal integer // %u pour unsigned decimal integer // %ld ou %li pour long signed decimal integer // %lu pour long unsigned decimal integer float temperature; delay(1000); // Lit la température ambiante byte bErr = getTemperature(&temperature, true); if (bErr != READ_OK) { // Erreur qui ne devrait pas se produire ?!? sprintf(acStr, "Erreur n° :%4d", bErr); strS = acStr; lcd.setCursor(0, 0); lcd.print(strS); } else { /* Affiche la température */ dtostrf( temperature, 6, 2, acStr); strS = acStr; strS = "Temp = " + strS + "C"; lcd.setCursor(0, 0); lcd.print(strS); } } // loop
/* ex0130_liquid_crystal_hello_world Utilise l'affichage LCD (à cristaux liquides), pour afficher du texte. De plus, il existe un "shield" qui ajoute 5 boutons en plus du bouton reset, pour avoir des entrées possibles. Ainsi, l'Arduino devient autonome pour beaucoup d'applications, sans nécessité d'un ordinateur pour l'utiliser et afficher des résultats. La lecture des boutons est lente, elle prend plus de 5 milli-secondes, mais elle se fait en un seul appelle à la fonction : read_LCD_buttons() Pour une version que je préfère, c.f. : ex0131_liquid_crystal_hello_world Ici, l'afficheur écrit "Hello World!" et "Bonjour a tous!" Puis mesure le temps et indique quelle touche est pressée. Affichage d'un texte. Lecture de l'état des Pushbutton. Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hello World!" to the LCD and shows the time. The circuit: * LCD RS pin to digital pin 8 * LCD Enable pin to digital pin 9 * LCD D4 pin to digital pin 4 * LCD D5 pin to digital pin 5 * LCD D6 pin to digital pin 6 * LCD D7 pin to digital pin 7 * 10K resistor: * ends to +5V and ground * wiper to LCD VO pin (pin 3) http://www.arduino.cc/en/Tutorial/LiquidCrystal c.f. : https://arduino-info.wikispaces.com/LCD-Pushbuttons PINs qui restent libre et utilisables : 13, 12, 11, 3, 2, 1 et 0 La PIN 10 sert à allumer ou éteindre la "backlight", la rétro - lumière pinMode(10, OUTPUT); // Permet d'éteindre ou d'allumer la "backlight" digitalWrite(10, HIGH); // allume la "backlight" digitalWrite(10, LOW); // éteind la "backlight" Les PINs 0 et 1 sont utilisés pour la transmission série par USB, */ // Inclus la librairie qui gère l'affichage #include <LiquidCrystal.h> // Déclaration de Constantes #define btnNONE 0 #define btnSELECT 1 #define btnLEFT 2 #define btnDOWN 3 #define btnUP 4 #define btnRIGHT 5 int nNumButton = 0; // N° du bouton pressé int nNumButtonLast = 0; // N° du dernier bouton pressé // Initialisation, pour indiquer quelles sont les PINs utilisées par l'afficheur LCD LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Un "array" de caractères, pour conversion de nombre en un String. String strS = ""; // Une chaine de caractères. // Indique le bouton pressé String astrS[6]; // Indices vont de astrS[0] à astrS[5], l'indice 6 n'est pas valide ! void setup() { //============ // Indique que l'afficheur LCD a deux lignes de 16 caractères lcd.begin(16, 2); // Affiche un message au départ, pour vérifier le bon fonctionnement. lcd.setCursor(0, 0); // Première colonne, première ligne lcd.print("hello, world!"); lcd.setCursor(0, 1); // Première colonne, deuxième ligne lcd.print("bonjour a tous!"); // Les caractères accentués ne passent pas. delay(2000); lcd.setCursor(0, 0); // Première ligne lcd.print(" "); // efface le texte 16 caractères lcd.setCursor(0, 1); // Deuxième ligne lcd.print(" "); // efface le texte 16 caractères //lcd.autoscroll(); // Texte qui peut etre affiché astrS[btnNONE] = "None "; astrS[btnSELECT] = "Select"; astrS[btnLEFT] = "Left "; astrS[btnDOWN] = "Down "; astrS[btnUP] = "Up "; astrS[btnRIGHT] = "Right "; pinMode(10, OUTPUT); // Permet d'allumer ou d'éteindre le rétro-éclairage. digitalWrite(10, HIGH); // allume le rétro-éclairage } // setup int read_LCD_buttons() { // ====================== // Lecture du bouton appuié int nAdc_key_in = analogRead(0); // Lecture du bouton pressé delay(5); // Attente, pour laisser des rebonds se terminer. int nAdc_Delta = (analogRead(0) - nAdc_key_in); // Deuxième lecture du bouton, pour vérification. if (5 < abs(nAdc_Delta)) return btnNONE; // Si la deuxième lecture est trop différente de la première, ignore le bouton. // Mes valeurs lues sont : 0, 130, 306, 479, 720, 1023 // Right Up Down Left Select none // On additionne environ 50 à ces valeurs pour tester dans quelle tranche la valeur a été lue if (nAdc_key_in > 800) return btnNONE; // Ce test vient en premier, car c'est la réponse la plus habituelle if (nAdc_key_in > 550) return btnSELECT; // entre 479 et 800 if (nAdc_key_in > 380) return btnLEFT; // entre 306 et 479 if (nAdc_key_in > 180) return btnDOWN; // entre 130 et 306 if (nAdc_key_in > 70) return btnUP; // entre 0 et 130 return btnRIGHT; // adc__key_in est plus petit que 71 } void loop() { //=========== // Affichage du temps sur la 2ème ligne lcd.setCursor(0, 1); // Affiche le temps en secondes, depuis le départ. //delay(100); // Pour sprintf, c.f. https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm // %d ou %i pour signed decimal integer // %u pour unsigned decimal integer // %ld ou %li pour long signed decimal integer // %lu pour long unsigned decimal integer //sprintf(acStr, "%8.3f", millis()/1000.0); // Ne fonctionne pas //sprintf(acStr, "%9lu", millis()); // Fonctionne bien dtostrf(millis()/1000.0, 12, 3, acStr); // Marche bien pour convertir un float en un string, avec un format // millis() retourne le nombre de millisecondes écoulé depuis la mise sous tension ou le reset de l'Arduino lcd.print(acStr); // La lecture des boutons se fait par l'intermédiaire du port A0 int sensorValue = analogRead(0); //sprintf(acStr, "%4d %4d ", sensorValue, read_LCD_buttons()); // Fonctionne bien sprintf(acStr, "%4d ", sensorValue); if (nNumButton != btnNONE) nNumButtonLast = nNumButton; // mémorise le dernier bouton pressé nNumButton = read_LCD_buttons(); // Lecture du bouton pressé strS = acStr + astrS[nNumButton]; lcd.setCursor(0, 0); lcd.print(strS); if (nNumButton == btnSELECT) { if (nNumButtonLast == btnDOWN) digitalWrite(10, LOW); // éteind le rétro-éclairage if (nNumButtonLast == btnUP) digitalWrite(10, HIGH); // allume le rétro-éclairage } } // loop
/* ex0131_liquid_crystal_hello_world Utilise l'affichage LCD (à cristaux liquides), pour afficher du texte. De plus, il existe un "shield" qui ajoute 5 boutons en plus du bouton reset, pour avoir des entrées possibles. Ainsi, l'Arduino devient autonome pour beaucoup d'applications, sans nécessité d'un ordinateur pour l'utiliser et afficher des résultats. La lecture des boutons se fait en plusieurs passes, mais chaque passe prend environ 100 micro-secondes. C'est un avantage pour les applications sensibles au temps, telles que les générateurs de fréquences. Ici, l'afficheur écrit "Hello World!" et "Bonjour a tous!" Puis mesure le temps et indique quelle touche est pressée. Affichage d'un texte. Lecture de l'état des Pushbutton. Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hello World!" to the LCD and shows the time. The circuit: * LCD RS pin to digital pin 8 * LCD Enable pin to digital pin 9 * LCD D4 pin to digital pin 4 * LCD D5 pin to digital pin 5 * LCD D6 pin to digital pin 6 * LCD D7 pin to digital pin 7 * 10K resistor: * ends to +5V and ground * wiper to LCD VO pin (pin 3) http://www.arduino.cc/en/Tutorial/LiquidCrystal c.f. : https://arduino-info.wikispaces.com/LCD-Pushbuttons PINs qui restent libre et utilisables : 13, 12, 11, 3, 2, 1 et 0 La PIN 10 sert à allumer ou éteindre la "backlight", la rétro - lumière pinMode(10, OUTPUT); // Permet d'éteindre ou d'allumer la "backlight" digitalWrite(10, HIGH); // allume la "backlight" digitalWrite(10, LOW); // éteind la "backlight" Les PINs 0 et 1 sont utilisés pour la transmission série par USB, */ // Inclus la librairie qui gère l'affichage #include <LiquidCrystal.h> // Déclaration de Constantes #define btnNONE 0 #define btnSELECT 1 #define btnLEFT 2 #define btnDOWN 3 #define btnUP 4 #define btnRIGHT 5 int nNumButton = 0; // N° du bouton pressé int nNumButtonLast = 0; // N° du dernier bouton pressé // Initialisation, pour indiquer quelles sont les PINs utilisées par l'afficheur LCD //LiquidCrystal lcd(RS, E, D4, D5, D6, D7); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Un "array" de caractères, pour conversion de nombre en un String. String strS = ""; // Une chaine de caractères. // Indique le bouton pressé String astrS[6]; // Indices vont de astrS[0] à astrS[5], l'indice 6 n'est pas valide ! unsigned long lwTempsStart = 0; // temps en milli secondes du départ unsigned long lwTempsStop = 0; // temps en milli secondes de l'arret void setup() { //============ // Indique que l'afficheur LCD a deux lignes de 16 caractères lcd.begin(16, 2); // Affiche un message au départ, pour vérifier le bon fonctionnement. lcd.setCursor(0, 0); // Première colonne, première ligne lcd.print("hello, world!"); lcd.setCursor(0, 1); // Première colonne, deuxième ligne lcd.print("bonjour a tous!"); // Les caractères accentués ne passent pas. delay(2000); lcd.setCursor(0, 0); // Première ligne lcd.print(" "); // efface le texte 16 caractères lcd.setCursor(0, 1); // Deuxième ligne lcd.print(" "); // efface le texte 16 caractères //lcd.autoscroll(); // Texte qui peut etre affiché astrS[btnRIGHT] = "Right "; astrS[btnUP] = "Up "; astrS[btnDOWN] = "Down "; astrS[btnLEFT] = "Left "; astrS[btnSELECT] = "Select"; astrS[btnNONE] = "None "; pinMode(10, OUTPUT); // Permet d'allumer ou d'éteindre le rétro-éclairage. digitalWrite(10, HIGH); // allume le rétro-éclairage } // setup int read_LCD_buttons() { // ====================== // Lecture du bouton appuié // Il faut détecter 10 fois de suite le même bouton pour qu'on estime détecté le bon bouton pressé. // L'avantage de cette manière de faire est que la lecture des boutons ne prend que // le temps d'une lecture analogique, soit environ 100 micro secondes. int nAdc_key_in = 0; byte bButton = btnNONE; // Button pressed according to the value of adc_key_in static byte bButtonLast = btnNONE; // Last button static byte bButtonCount = 0; // compte le nombre de fois que le même boutton est détecté à la suite. nAdc_key_in = analogRead(0); // Lecture de la valeur du bouton pressé. // La lecture des boutons sont centrée autour des valeurs 0, 144, 329, 504, 741 // J'ai ajouté environ 50 à ces valeurs pour la détection des boutons if (nAdc_key_in > 790) { // Aucun bouton pressé. bButtonLast = btnNONE; bButtonCount = 0; return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result } else if (nAdc_key_in > 555) bButton = btnSELECT; else if (nAdc_key_in > 380) bButton = btnLEFT; else if (nAdc_key_in > 195) bButton = btnDOWN; else if (nAdc_key_in > 55) bButton = btnUP; else bButton = btnRIGHT; if (bButton == bButtonLast) { // Le même bouton a été détecté if (bButtonCount > 10) return bButton; // Le même bouton a été détecté .. fois de suite, donc c'est le bon bButtonCount++; // compte combien de fois de suite le même bouton est détecté. } else { // Un nouveau bouton est détecté. bButtonLast = bButton; bButtonCount = 1; } return btnNONE; // On est pas encore sûr que le bon bouton est bButton. } // read_LCD_buttons void loop() { //=========== // Affichage du temps sur la 2ème ligne lcd.setCursor(0, 1); // print the number of seconds since reset: //delay(100); // Pour sprintf, c.f. https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm // %d ou %i pour signed decimal integer // %u pour unsigned decimal integer // %ld ou %li pour long signed decimal integer // %lu pour long unsigned decimal integer //sprintf(acStr, "%8.3f", millis()/1000.0); // Ne fonctionne pas //sprintf(acStr, "%9lu", millis()); // Fonctionne bien //dtostrf(millis()/1000.0, 12, 3, acStr); // Marche bien pour convertir un float en un string, avec un format // millis() retourne le nombre de millisecondes écoulé depuis la mise sous tension ou le reset de l'Arduino //lcd.print(acStr); // La lecture des boutons se fait par l'intermédiaire du port A0 int sensorValue = analogRead(0); //sprintf(acStr, "%4d %4d ", sensorValue, read_LCD_buttons()); // Fonctionne bien sprintf(acStr, "%4d ", sensorValue); if (nNumButton != btnNONE) nNumButtonLast = nNumButton; // mémorise le dernier bouton pressé nNumButton = read_LCD_buttons(); // Lecture du bouton pressé strS = acStr + astrS[nNumButton]; lcd.setCursor(0, 0); lcd.print(strS); if (nNumButton == btnLEFT) { // temps de départ lwTempsStart = millis(); } if ((nNumButton == btnRIGHT) && (lwTempsStart > 0)) { // temps de d'arret lwTempsStop = millis(); dtostrf((lwTempsStop - lwTempsStart)/1000.0, 12, 3, acStr); lcd.setCursor(0, 1); lcd.print(acStr); lwTempsStart = 0; } if (lwTempsStart > 0) { // affichage du temps lwTempsStop = millis(); dtostrf((lwTempsStop - lwTempsStart)/1000.0, 12, 3, acStr); lcd.setCursor(0, 1); lcd.print(acStr); } if (nNumButton == btnSELECT) { if (nNumButtonLast == btnDOWN) digitalWrite(10, LOW); // éteind le rétro-éclairage if (nNumButtonLast == btnUP) digitalWrite(10, HIGH); // allume le rétro-éclairage } } // loop
/* ex0140_Frequences_HP_Menu_LiquidCrystal Pour faire vibrer un H.P. a une fréquence précise, de quelques dizaines de Hz. Montre également l'utilisation d'un menu avec l'afficheur à critaux liquide Connections : LCD Arduino (pin) ou tension 1 - Vss = 0 V 2 - Vcc = 5 V 3 - V0 = Tension variable réglée par une résistance variable, pour la lumineusité de l'affichage 4 - RS = pin 7 (Register Select) 5 - R/W = 0 V donc uniquement en Write 6 - E = pin 6 Enable, mise à haut pour accepter les données. 7 .. 10 = connecté à la commande de rétro-éclairage "back light" 11 - D4 = pin 5, données sur 4 bits 12 - D5 = pin 4, données sur 4 bits 13 - D6 = pin 3, données sur 4 bits 14 - D7 = pin 2, données sur 4 bits 15 - LED + = 220 Ohm - +5V 16 - LED - = 0V Autres connexions : push button 1 - pin 8 push button 2 - pin 9 push button 3 - pin 10 push button 4 - pin 11 Tension réglée par une résistance variable - Analog 0 Tension réglée par une résistance variable - Analog 1 Sortie commande de la LED - pin 13, juste pour montrer que le code a été chargé. This example code is in the public domain. c.f. : http://www.arduino.cc/en/Tutorial/LiquidCrystal c.f. : https://arduino-info.wikispaces.com/LCD-Pushbuttons Pin qui restent libre et utilisables : pin 0, pin 1, utilisé pour la transmission par USB, ======================================================== */ // include the library code: #include <LiquidCrystal.h> // Déclaration de Constantes #define btnNONE 0 #define btnSELECT 1 #define btnLEFT 2 #define btnDOWN 3 #define btnUP 4 #define btnRIGHT 5 #define pinFreqP 2 // pour générer une fréquence #define pinFreqN 3 // = état opposé à celui de pintFreqP lors du fonctionnement. #define pinFreqOnOff 11 // pour enclencher ou arrêter le générateur de fréquences // initialize the library with the numbers of the interface pins //LiquidCrystal lcd(RS, E, D4, D5, D6, D7); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); String strS = ""; // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Pour conversion de nombre en un string. int nButtonPush = btnNONE; // Bouton pressé byte bMenu1 = 4; // indique le menu sélectionné byte bMenu1_Last = 0; // indique le dernier menu sélectionné // que lorsque adc_key_in a suffisemment changé. String strCode = ""; // pour indiquer l'état du code byte bEtat0 = 0; // Etat du signal 0 de la LED de la pin 13 byte bEtat1 = 0; // Etat du signal 1, LOW=0 ou HIGH=1 byte bEtat_enable = 0; // Etat de la pin "enable" du contrôle de l'Haut-Parleur unsigned long lwFrequ1 = 30000; // Fréquence au millième de Herz du signal 1 (PINs 2 et 3) unsigned long lwTemps = 0; // temps en micro secondes unsigned long lwTempsActionLast = 0; // temps en micro secondes de la dernière commande unsigned long lwTempsNext1 = 0; // Temps en micro secondes de la prochaine transition du signal 1 (PINs 2 et 3) unsigned long lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période en micro-secondes du signal 1 (PINs 2 et 3) unsigned long lwTempsSignal0 = 100000; // temps en micros-seconde d'un état du signal de la pin 13 unsigned long lwTempsLast0 = 0; // temps de la dernière transision du signal 0 LED de la pin 13 void setup() { //============ // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("Pour H.P. freq."); delay(800); lcd.setCursor(0, 0); lcd.print(" "); // efface le texte //lcd.autoscroll(); lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période du signal 1 lwTemps = micros(); lwTempsNext1 = lwTemps; pinMode(13, OUTPUT); // clignote, pour indiquer que tout fonctionne correctement. pinMode(pinFreqOnOff, OUTPUT); // pinMode( pinFreqN, OUTPUT); // controle une borne de l'haut-parleur pinMode( pinFreqP, OUTPUT); // controle l'autre borne de l'haut-parleur bEtat_enable = 0; // = LOW digitalWrite(pinFreqOnOff, LOW); // Arrêté digitalWrite( pinFreqN, LOW); // borne 1 à 0 V digitalWrite( pinFreqP, LOW); // borne 2 à 0 V AfficheEtat(); } // setup int read_LCD_buttons() { // ====================== // Lecture du bouton appuié // Il faut détecter 10 fois de suite le même bouton pour qu'on estime détecté le bon bouton pressé. // L'avantage de cette manière de faire est que la lecture des boutons ne prend que // le temps d'une lecture analogique, soit environ 100 micro secondes. int nAdc_key_in = 0; byte bButton = btnNONE; // Button pressed according to the value of adc_key_in static byte bButtonLast = btnNONE; // Last button static byte bButtonCount = 0; // compte le nombre de fois que le même boutton est détecté à la suite. nAdc_key_in = analogRead(0); // Lecture de la valeur du bouton pressé. // La lecture des boutons sont centrée autour des valeurs 0, 144, 329, 504, 741 // J'ai ajouté environ 50 à ces valeurs pour la détection des boutons if (nAdc_key_in > 790) { // Aucun bouton pressé. bButtonLast = btnNONE; bButtonCount = 0; return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result } else if (nAdc_key_in > 555) bButton = btnSELECT; else if (nAdc_key_in > 380) bButton = btnLEFT; else if (nAdc_key_in > 195) bButton = btnDOWN; else if (nAdc_key_in > 55) bButton = btnUP; else bButton = btnRIGHT; if (bButton == bButtonLast) { // Le même bouton a été détecté if (bButtonCount > 10) return bButton; // Le même bouton a été détecté .. fois de suite, donc c'est le bon bButtonCount++; // compte combien de fois de suite le même bouton est détecté. } else { // Un nouveau bouton est détecté. bButtonLast = bButton; bButtonCount = 1; } return btnNONE; // On est pas encore sûr que le bon bouton est bButton. } // read_LCD_buttons void AfficheEtat() { //================== // Affichage de la fréquence ou de la variation de fréquence, suivant le menu if (bMenu1 <= 5) { // Affiche Fréquence du signal 1 if (bMenu1 != bMenu1_Last) { lcd.setCursor(0, 0); if (bMenu1 == 1) lcd.print("Frequ +-0.001 Hz"); else if (bMenu1 == 2) lcd.print("Frequ +- 0.01 Hz"); else if (bMenu1 == 3) lcd.print("Frequ +- 0.10 Hz"); else if (bMenu1 == 4) lcd.print("Frequ +- 1 Hz "); else if (bMenu1 == 5) lcd.print("Frequ +- 10 Hz "); } dtostrf(lwFrequ1/1000.0, 8, 3, acStr); strS = acStr; strS = "Frequ.= " + strS; lcd.setCursor(0, 1); lcd.print(strS); } } // AfficheEtat void MenuTreat() { //================ // On a appuyé sur un bouton, traite l'action adéquat. // Mémorise le temps de la dernière action utilisateur, pour pas en faire plusieurs lorsqu'on presse sur un bouton lwTempsActionLast = micros(); if (bMenu1 == 1) { // Changement de fréquence du signal 1 de +-1 milli-Hz if (nButtonPush == btnUP) lwFrequ1 += 1; if (nButtonPush == btnDOWN) lwFrequ1 -= 1; } if (bMenu1 == 2) { // Changement de fréquence du signal 1 de +-10 milli-Hz if (nButtonPush == btnUP) lwFrequ1 += 10; if (nButtonPush == btnDOWN) lwFrequ1 -= 10; } if (bMenu1 == 3) { // Changement de fréquence du signal 1 de +-100 milli-Hz if (nButtonPush == btnUP) lwFrequ1 += 100; if (nButtonPush == btnDOWN) lwFrequ1 -= 100; } if (bMenu1 == 4) { // Changement de fréquence du signal 1 de +-1 Hz if (nButtonPush == btnUP) lwFrequ1 += 1000; if (nButtonPush == btnDOWN) lwFrequ1 -= 1000; } if (bMenu1 == 5) { // Changement de fréquence du signal 1 de +-10 Hz if (nButtonPush == btnUP) lwFrequ1 += 10000; if (nButtonPush == btnDOWN) lwFrequ1 -= 10000; } if ((1 <= bMenu1) && (bMenu1 <= 5)) { if (lwFrequ1 < 1000) lwFrequ1 = 1000; // Minimum = 1 Hertz if (lwFrequ1 > 1500000ul) lwFrequ1 = 1000; // Correction de l'erreur décrite ci-dessous. if (lwFrequ1 > 1200000ul) lwFrequ1 = 1200000ul; // Maximum = 1'200 Hertz // Ici, il y a une petite erreur (de sémentique). Le programme fonctionne correctement, // mais, il ne fait pas exactement ce qu'on veut. // Si Le changement de fréquence est de 10 Hz et qu'on diminue une fréquence de 1 à 9 Hz, // la fréquence finale sera de 800 Hz. Il suffit de rajouter la bonne ligne au bon endroit // pour corriger ce problème ! lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période en micro-secondes du signal } // Le bouton "Select" active ou désactive le signal if (nButtonPush == btnSELECT) { bEtat_enable = 1 - bEtat_enable; digitalWrite(pinFreqOnOff, bEtat_enable); // on - off digitalWrite( pinFreqP, bEtat1 & bEtat_enable); // off si signal désactivé digitalWrite( pinFreqN, (1 - bEtat1) & bEtat_enable); lwTempsNext1 = lwTemps; } AfficheEtat(); } // MenuTreat void Menu1_Change() { //=================== // Changement du Menu1 lwTempsActionLast = micros(); bMenu1_Last = bMenu1; // Mémorise le dernier menu if (nButtonPush == btnLEFT) { bMenu1 -= 1; if (bMenu1 == 0) bMenu1 = 5; // boucle } if (nButtonPush == btnRIGHT) { bMenu1 += 1; if (bMenu1 > 5) bMenu1 = 1; // boucle } AfficheEtat(); } // Menu1_Change void loop() { //=========== // Génère un signal carré d'une fréquence sélectionnable. // Serial.print(sensorValue, DEC); // Serial.println(); lwTemps = micros(); // Ne lit l'état des boutons que si un bouton a été traité il y a plus de 0,2 secondes = 200000 [us]. if (lwTemps - lwTempsActionLast > 200000ul) { // Lecture de l'état des boutons, pour changer la fréquence ou la phase du signal nButtonPush = read_LCD_buttons(); if ( (nButtonPush == btnLEFT) || (nButtonPush == btnRIGHT) ) Menu1_Change(); // Changement de menu if ( (nButtonPush == btnUP) || (nButtonPush == btnDOWN) || (nButtonPush == btnSELECT) ) MenuTreat(); // Un bouton pressé, traitement } // Test si un changement d'état du signal 1 est imminent if ((lwTemps - lwTempsNext1 + 1000ul >= lwDemiPeriode1) & bEtat_enable) { // Attente avant un changement d'état du signal 1 while (lwTemps - lwTempsNext1 < lwDemiPeriode1) { lwTemps = micros(); } // Attente bEtat1 = 1 - bEtat1; digitalWrite( pinFreqP, bEtat1); digitalWrite( pinFreqN, 1 - bEtat1); // Prochain changement d'état, faisant vibrer le Haut-Parleur. lwTempsNext1 = lwTempsNext1 + lwDemiPeriode1; } } // loop
/* ex0142_Menu_Do_Re_Mi_Fa_Sol.ino Joue les notes : "Do Ré Mi Fa Sol La Si Do". La fréquence de base est modifiable. La touche Select permet d'enclancher ou arrêter la génération du signal sur les pin 2 et 3. Utilise l'afficheur LCD 1602 avec 5 boutons, pour gérer un menu. Connections : LCD Arduino (pin) ou tension 1 - Vss = 0 V 2 - Vcc = 5 V 3 - V0 = Tension variable réglée par une résistance variable, pour la lumineusité de l'affichage 4 - RS = pin 8 (Register Select) 5 - R/W = 0 V donc uniquement en Write 6 - E = pin 9 Enable, mise à haut pour accepter les données. 7 .. 10 = connecté à la commande de rétro-éclairage "back light" 11 - D4 = pin 4, données sur 4 bits 12 - D5 = pin 5, données sur 4 bits 13 - D6 = pin 6, données sur 4 bits 14 - D7 = pin 7, données sur 4 bits 15 - LED + = 220 Ohm - +5V 16 - LED - = 0V Autres connexions : pin 2 et 3 pour le signal pin 13 pour indiquer si le HP est on ou off pin 0, pin 1, utilisées pour la transmission par USB, ADC 0 pour les lecture les boutons. c.f. : http://www.arduino.cc/en/Tutorial/LiquidCrystal c.f. : https://arduino-info.wikispaces.com/LCD-Pushbuttons ======================================================== */ // include the library code: #include <LiquidCrystal.h> // Déclaration de Constantes #define btnNONE 0 #define btnSELECT 1 #define btnLEFT 2 #define btnDOWN 3 #define btnUP 4 #define btnRIGHT 5 #define pinFreqP 2 // pour générer une fréquence #define pinFreqN 3 // = état opposé à celui de pintFreqP lors du fonctionnement. #define pinFreqOnOff 13 // pour enclencher ou arrêter le générateur de fréquences // Nombre de menus # define MENUMAX 4 int nn = 0; int adc_key_in = 0; byte bButton = btnNONE; // Button pressed according to the value of adc_key_in byte bButtonLast = btnNONE; // dernier bouton byte bButtonCount = 0; // compte le nombre de fois que le même bouton est détecté à la suite. // initialize the library with the numbers of the interface pins //LiquidCrystal lcd(RS, E, D4, D5, D6, D7); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); String strS = ""; // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Pour conversion de nombre en un string. int nButtonPush = btnNONE; // Bouton pressé byte bMenu1 = 4; // indique le menu sélectionné byte bMenu1_Last = 0; // indique le dernier menu sélectionné byte bEtat0 = 0; // Etat du signal 0, LOW=0 ou HIGH=1 byte bEtat1 = 0; // Etat du signal 1, LOW=0 ou HIGH=1 byte bEtat_enable = 0; // Etat de la pin "enable" du contrôle de l'Haut-Parleur unsigned long lwFrequ1 = 261630; // Fréquence au millième de Herz du Do3 (PINs 2 et 3) unsigned long lwTemps = 0; // temps en micro secondes unsigned long lwTempsActionLast = 0; // temps en micro secondes de la dernière commande unsigned long lwTempsNext1 = 0; // Temps en micro secondes de la prochaine transition du signal 1 (PINs 2 et 3) unsigned long lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période en micro-secondes du signal 1 (PINs 2 et 3) unsigned long lwTempsSignal0 = 100000; // temps en micros-seconde d'un état du signal de la pin 13 unsigned long lwTempsLast0 = 0; // temps de la dernière transision du signal 0 LED de la pin 13 unsigned long freqCalc = 0; unsigned long modeleTempsNote = 250000; unsigned long tempsNote = 0; unsigned short ptrStep = 1; void setup() { //============ // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.setCursor(0, 0); lcd.print("Do Re mi Fa ... "); lcd.setCursor(0, 1); lcd.print("ex0142 20181019 "); delay(1200); lcd.setCursor(0, 0); lcd.print(" "); // efface le texte lcd.setCursor(0, 1); lcd.print(" "); lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période du signal 1 lwTemps = micros(); lwTempsNext1 = lwTemps; pinMode( pinFreqOnOff, OUTPUT); // pinMode( pinFreqN, OUTPUT); // controle une borne de l'haut-parleur pinMode( pinFreqP, OUTPUT); // controle l'autre borne de l'haut-parleur bEtat_enable = 0; // = LOW digitalWrite( pinFreqOnOff, LOW); // Arrêté digitalWrite( pinFreqN, LOW); // borne 1 à 0 V digitalWrite( pinFreqP, LOW); // borne 2 à 0 V AfficheEtat(); } // setup int read_LCD_buttons() { // ====================== // Lecture du bouton appuié // Il faut détecter 10 fois de suite le même bouton pour qu'on estime détecté le bon bouton pressé. // L'avantage de cette manière de faire est que la lecture des boutons ne prend que // le temps d'une lecture analogique, soit environ 100 micro secondes. adc_key_in = analogRead(0); // read the value from the sensor // La lecture des boutons sont centrée autour des valeurs 0, 144, 329, 504, 741 // J'ai ajouté environ 50 à ces valeurs pour la détection des boutons if (adc_key_in > 790) { // Aucun bouton pressé. bButtonLast = btnNONE; bButtonCount = 0; return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result } else if (adc_key_in > 555) bButton = btnSELECT; else if (adc_key_in > 380) bButton = btnLEFT; else if (adc_key_in > 195) bButton = btnDOWN; else if (adc_key_in > 55) bButton = btnUP; else bButton = btnRIGHT; if (bButton == bButtonLast) { // Le même bouton a été détecté if (bButtonCount > 10) return bButton; // Le même bouton a été détecté .. fois de suite, donc c'est le bon bButtonCount++; // compte combien de fois de suite le même bouton est détecté. } else { bButtonLast = bButton; bButtonCount = 1; } return btnNONE; // On est pas encore sûr que le bon bouton est bButton. } // read_LCD_buttons void AfficheEtat() { //================== // Affichage de la fréquence ou de la variation de fréquence, suivant le menu // Affiche Fréquence du signal 1 if (bMenu1 != bMenu1_Last) { lcd.setCursor(0, 0); if (bMenu1 == 1) lcd.print("Frequ +- 0.10 Hz"); else if (bMenu1 == 2) lcd.print("Frequ +- 1 Hz"); else if (bMenu1 == 3) lcd.print("Frequ +- 10 Hz"); else if (bMenu1 == 4) lcd.print("Frequ +- 100 Hz"); } dtostrf(lwFrequ1/1000.0, 8, 3, acStr); strS = acStr; strS = "Frequ.= " + strS; lcd.setCursor(0, 1); lcd.print(strS); } // AfficheEtat void MenuTreat() { //================ // On a appuyé sur un bouton, traite l'action adéquat. // Mémorise le temps de la dernière action utilisateur, pour pas en faire plusieurs lorsqu'on presse sur un bouton lwTempsActionLast = micros(); if (bMenu1 == 1) { // Changement de fréquence du signal 1 de +-100 milli-Hz if (nButtonPush == btnUP) lwFrequ1 += 100; if (nButtonPush == btnDOWN) lwFrequ1 -= 100; } if (bMenu1 == 2) { // Changement de fréquence du signal 1 de +-1 Hz if (nButtonPush == btnUP) lwFrequ1 += 1000; if (nButtonPush == btnDOWN) lwFrequ1 -= 1000; } if (bMenu1 == 3) { // Changement de fréquence du signal 1 de +-10 Hz if (nButtonPush == btnUP) lwFrequ1 += 10000; if (nButtonPush == btnDOWN) lwFrequ1 -= 10000; } if (bMenu1 == 4) { // Changement de fréquence du signal 1 de +-100 Hz if (nButtonPush == btnUP) lwFrequ1 += 100000ul; if (nButtonPush == btnDOWN) lwFrequ1 -= 100000ul; } if ( (1 <= bMenu1) && (bMenu1 <= MENUMAX) ) { if (lwFrequ1 < 1000) lwFrequ1 = 1000; // Minimum = 1 Hertz if (lwFrequ1 > 15000000ul) lwFrequ1 = 1000; // Si "undeerflow", assure que la fréquence soit de 1 Hz. if (lwFrequ1 > 10000000ul) lwFrequ1 = 10000000ul; // Maximum = 10'000 Hertz. Bien avant, on est limité par la vitesse de la boucle "loop". lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période en micro-secondes du signal, sera changé à la fin de la mélodie } // Le bouton "Select" active ou désactive le signal if (nButtonPush == btnSELECT) { bEtat_enable = 1 - bEtat_enable; digitalWrite( pinFreqOnOff, bEtat_enable); // on - off digitalWrite( pinFreqP, bEtat1 & bEtat_enable); // off si signal désactivé digitalWrite( pinFreqN, (1 - bEtat1) & bEtat_enable); } ptrStep=0; // Pour démarrer avec un Do defTemps(-360, 4); // Pause AfficheEtat(); } // MenuTreat void Menu1_Change() { //=================== // Changement du Menu1 // Ne fait rien ici, mais gardé pour conserver la structure habituelle des menus. lwTempsActionLast = micros(); bMenu1_Last = bMenu1; // Mémorise le dernier menu if (nButtonPush == btnLEFT) { bMenu1 -= 1; if (bMenu1 == 0) bMenu1 = MENUMAX; // boucle } if (nButtonPush == btnRIGHT) { bMenu1 += 1; if (bMenu1 > MENUMAX) bMenu1 = 1; // boucle } AfficheEtat(); } // Menu1_Change void defTemps(int nPow, int nDuration) { //====================================== // Change la note et la durée et prépare le passage à la note suivante. freqCalc = lwFrequ1 * pow(1.05946, nPow) ; tempsNote = lwTemps + modeleTempsNote*nDuration; ptrStep += 1; } // defTemps void son() { //========== // Test si un changement d'état du signal 1 est imminent if ((lwTemps - lwTempsNext1 + 1000ul >= lwDemiPeriode1) & bEtat_enable) { // Attente avant un changement d'état du signal 1 (stabiliser) while (lwTemps - lwTempsNext1 < lwDemiPeriode1) { lwTemps = micros(); } // Attente digitalWrite( pinFreqN, bEtat1); bEtat1 = 1 - bEtat1; digitalWrite( pinFreqP, bEtat1); // Prochain changement d'état, faisant vibrer le Haut-Parleur. lwTempsNext1 = lwTempsNext1 + lwDemiPeriode1; } } // son void loop() { //=========== // Génère un signal carré d'une fréquence sélectionnable. //Serial.print(sensorValue, DEC); //Serial.println(); lwTemps = micros(); // Ne lit l'état des boutons que si un bouton a été traité il y a plus de 0,2 secondes = 200000 [us]. if (lwTemps - lwTempsActionLast > 200000ul) { // Lecture de l'état des boutons, pour changer la fréquence ou la phase du signal nButtonPush = read_LCD_buttons(); if ( (nButtonPush == btnLEFT) || (nButtonPush == btnRIGHT) ) Menu1_Change(); // Changement de menu if ( (nButtonPush == btnUP) || (nButtonPush == btnDOWN) || (nButtonPush == btnSELECT) ) MenuTreat(); // Un bouton pressé, traitement } // Pour jouer la gamme. if (lwTemps >= tempsNote) { switch (ptrStep) { case 1: lwTempsNext1 = lwTemps; // Pour initialiser le générateur de fréquence. defTemps(0, 2); // Do break; case 2: defTemps(2, 2); // Re break; case 3: defTemps(4, 2); // Mi break; case 4: defTemps(5, 2); // Fa break; case 5: defTemps(7, 2); // Sol break; case 6: defTemps(9, 2); // La break; case 7: defTemps(11, 2); // Si break; case 8: defTemps(12, 2); // Do break; case 9: defTemps(-360, 10); // Pause ptrStep=1; // Revient au départ. break; } // Pour debugging sprintf(acStr, "Step = %3d", ptrStep); strS = acStr; //lcd.setCursor(0, 0); lcd.print(strS); } lwDemiPeriode1 = 500000000ul / freqCalc; // Demi période en micro-secondes du signal son(); } // loop // FIN
/* ex0143_Menu_Jai_du_bon_tabac.ino Joue la mélodie : J'ai du bon tabac dans ma tabatière. Permet aussi de jouer la gamme et de jouer la mélodie de "Frère Jacques". Utilise l'afficheur LCD 1602 avec 5 boutons pour gérer un menu. Connections : LCD Arduino (pin) ou tension 1 - Vss = 0 V 2 - Vcc = 5 V 3 - V0 = Tension variable réglée par une résistance variable, pour la lumineusité de l'affichage 4 - RS = pin 8 (Register Select) 5 - R/W = 0 V donc uniquement en Write 6 - E = pin 9 Enable, mise à haut pour accepter les données. 7 .. 10 = connecté à la commande de rétro-éclairage "back light" 11 - D4 = pin 4, données sur 4 bits 12 - D5 = pin 5, données sur 4 bits 13 - D6 = pin 6, données sur 4 bits 14 - D7 = pin 7, données sur 4 bits 15 - LED + = 220 Ohm - +5V 16 - LED - = 0V Autres connexions : pin 2 et 3 pour le signal pin 13 pour indiquer si le HP est on ou off pin 0, pin 1, utilisées pour la transmission par USB, ADC 0 pour les lecture les boutons. c.f. : http://www.arduino.cc/en/Tutorial/LiquidCrystal c.f. : https://arduino-info.wikispaces.com/LCD-Pushbuttons ======================================================== */ // include the library code: #include <LiquidCrystal.h> // Déclaration de Constantes #define btnNONE 0 #define btnSELECT 1 #define btnLEFT 2 #define btnDOWN 3 #define btnUP 4 #define btnRIGHT 5 #define pinFreqP 2 // pour générer une fréquence #define pinFreqN 3 // = état opposé à celui de pintFreqP lors du fonctionnement. #define pinFreqOnOff 13 // pour enclencher ou arrêter le générateur de fréquences // Nombre de menus # define MENUMAX 1 int nn = 0; int adc_key_in = 0; byte bButton = btnNONE; // Button pressed according to the value of adc_key_in byte bButtonLast = btnNONE; // dernier bouton byte bButtonCount = 0; // compte le nombre de fois que le même bouton est détecté à la suite. // initialize the library with the numbers of the interface pins //LiquidCrystal lcd(RS, E, D4, D5, D6, D7); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); String strS = ""; // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Pour conversion de nombre en un string. int nButtonPush = btnNONE; // Bouton pressé byte bMenu1 = 1; // indique le menu sélectionné byte bMenu1_Last = 0; // indique le dernier menu sélectionné // que lorsque adc_key_in a suffisemment changé. byte bEtat1 = 0; // Etat du signal 1, LOW=0 ou HIGH=1 byte bEtat_enable = 0; // Etat de la pin "enable" du contrôle de l'Haut-Parleur unsigned long lwFrequ1 = 261630; // Fréquence au millième de Herz du Do3 (PINs 2 et 3) unsigned long lwTemps = 0; // temps en micro secondes unsigned long lwTempsActionLast = 0; // temps en micro secondes de la dernière commande unsigned long lwTempsNext1 = 0; // Temps en micro secondes de la prochaine transition du signal 1 (PINs 2 et 3) unsigned long lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période en micro-secondes du signal 1 (PINs 2 et 3) unsigned long lwTempsSignal0 = 100000; // temps en micros-seconde d'un état du signal de la pin 13 unsigned long lwTempsLast0 = 0; // temps de la dernière transision du signal 0 LED de la pin 13 unsigned long freqCalc = 0; unsigned long modeleTempsNote = 250000; unsigned long tempsNote = 0; unsigned short ptrStep = 1; #define pause -360 #define sol2 -5 #define do3 0 #define re3 2 #define mi3 4 #define fa3 5 #define sol3 7 #define la3 9 #define si3 11 #define do4 12 #define re4 14 // La gamme //int anNotes[] = {0,2, 2,2, 4,2, 5,2, 7,2, 9,2, 11,2, 12,2, 0,0}; // 0,0 marque la fin int anNotes1[] = {do3,2, re3,2, mi3,2, fa3,2, sol3,2, la3,2, si3,2, do4,2, 0,0}; // 0,0 marque la fin // Frère Jacques int anNotes2[] = { do3,2, re3,2, mi3,2, do3,2, do3,2, re3,2, mi3,2, do3,2, mi3,2, fa3,2, sol3,4, mi3,2, fa3,2, sol3,4, sol3,1, la3,1, sol3,1, fa3,1, mi3,2, do3,2, sol3,1, la3,1, sol3,1, fa3,1, mi3,2, do3,2, do3,2, sol2,2, do3,4, do3,2, sol2,2, do3,4, 0,0}; // 0,0 marque la fin // J'ai du bon tabac c.f. https://www.apprendrelaflute.com/j-ai-du-bon-tabac-dans-ma-tabatiere int anNotes3[] = { sol3,2, la3,2, si3,2, sol3,2, la3,4, la3,2, si3,2, do4,4, do4,4, si3,4, si3,4, sol3,2, la3,2, si3,2, sol3,2, la3,4, la3,2, si3,2, do4,4, re4,4, sol3,6, pause,2, re4,4, re4,2, do4,2, si3,4, la3,2, si3,2, do4,4, re4,4, la3,6, pause,2, re4,4, re4,2, do4,2, si3,4, la3,2, si3,2, do4,4, re4,4, la3,6, pause,2, pause,8, 0,0}; // 0,0 marque la fin int* panNotes = anNotes3; // Pointe sur la mélodie à jouer. int nNumMelodie = 3; // Numéro de la mélodie jouée. int* apanNotes[] = {anNotes1, anNotes1, anNotes2, anNotes3}; // Tableau de pointeurs sur des tableaux de notes. void setup() { //============ // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.setCursor(0, 0); lcd.print("jai du bon tabac"); lcd.setCursor(0, 1); lcd.print("ex0143 20200621 "); delay(1200); lcd.setCursor(0, 0); lcd.print(" "); // efface le texte lcd.setCursor(0, 1); lcd.print(" "); lwDemiPeriode1 = 500000000ul / lwFrequ1; // Demi période du signal 1 lwTemps = micros(); lwTempsNext1 = lwTemps; //pinMode(13, OUTPUT); // clignote, pour indiquer que tout fonctionne correctement. (test) pinMode( pinFreqOnOff, OUTPUT); // pinMode( pinFreqN, OUTPUT); // controle une borne de l'haut-parleur pinMode( pinFreqP, OUTPUT); // controle l'autre borne de l'haut-parleur bEtat_enable = 1; // = HIGH digitalWrite( pinFreqOnOff, bEtat_enable); // Indique si marche ou arrêt digitalWrite( pinFreqN, LOW); // borne 1 à 0 V digitalWrite( pinFreqP, LOW); // borne 2 à 0 V AfficheEtat(); } // setup int read_LCD_buttons() { // ====================== // Lecture du bouton appuié // Il faut détecter 10 fois de suite le même bouton pour qu'on estime détecté le bon bouton pressé. // L'avantage de cette manière de faire est que la lecture des boutons ne prend que // le temps d'une lecture analogique, soit environ 100 micro secondes. adc_key_in = analogRead(0); // read the value from the sensor // La lecture des boutons sont centrée autour des valeurs 0, 144, 329, 504, 741 // J'ai ajouté environ 50 à ces valeurs pour la détection des boutons if (adc_key_in > 790) { // Aucun bouton pressé. bButtonLast = btnNONE; bButtonCount = 0; return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result } else if (adc_key_in > 555) bButton = btnSELECT; else if (adc_key_in > 380) bButton = btnLEFT; else if (adc_key_in > 195) bButton = btnDOWN; else if (adc_key_in > 55) bButton = btnUP; else bButton = btnRIGHT; if (bButton == bButtonLast) { // Le même bouton a été détecté if (bButtonCount > 10) return bButton; // Le même bouton a été détecté .. fois de suite, donc c'est le bon bButtonCount++; // compte combien de fois de suite le même bouton est détecté. } else { bButtonLast = bButton; bButtonCount = 1; } return btnNONE; // On est pas encore sûr que le bon bouton est bButton. } // read_LCD_buttons void AfficheEtat() { //================== // Affichage de la fréquence ou de la variation de fréquence, suivant le menu // Affiche la mélodie jouée lcd.setCursor(0, 0); lcd.print("Melodie : "); lcd.setCursor(0, 1); if (nNumMelodie == 1) strS = "La Gamme "; else if (nNumMelodie == 2) strS = "Frere Jacques "; else if (nNumMelodie == 3) strS = "Jai du bon tabac"; lcd.print(strS); } // AfficheEtat void MenuTreat() { //================ // On a appuyé sur un bouton, traite l'action adéquat. // Mémorise le temps de la dernière action utilisateur, pour pas en faire plusieurs lorsqu'on presse sur un bouton lwTempsActionLast = micros(); if (bMenu1 == 1) { // Changement de mélodie if (nButtonPush == btnUP) { // Passage à la mélodie suivante nNumMelodie++; if (nNumMelodie > 3) nNumMelodie = 1; panNotes = apanNotes[nNumMelodie]; // pointe sur la mélodie à jouer. } if (nButtonPush == btnDOWN) { // Passage à la mélodie précédente nNumMelodie--; if (nNumMelodie <= 0) nNumMelodie = 3; panNotes = apanNotes[nNumMelodie]; // pointe sur la mélodie à jouer. } ptrStep = 0; // Démarre depuis le début de la mélodie. defTemps(-360, 10); // Pause } // Le bouton "Select" active ou désactive le signal if (nButtonPush == btnSELECT) { bEtat_enable = 1 - bEtat_enable; // on - off digitalWrite(pinFreqOnOff, bEtat_enable); digitalWrite( pinFreqP, bEtat1 & bEtat_enable); // off si signal désactivé digitalWrite( pinFreqN, (1 - bEtat1) & bEtat_enable); } AfficheEtat(); } // MenuTreat void Menu1_Change() { //=================== // Changement du Menu1 // Structure habituelle des menus. lwTempsActionLast = micros(); bMenu1_Last = bMenu1; // Mémorise le dernier menu if (nButtonPush == btnLEFT) { bMenu1 -= 1; if (bMenu1 == 0) bMenu1 = MENUMAX; // boucle } if (nButtonPush == btnRIGHT) { bMenu1 += 1; if (bMenu1 > MENUMAX) bMenu1 = 1; // boucle } AfficheEtat(); } // Menu1_Change void defTemps(int nPow, int nDuration) { //====================================== // Change la note et la durée et prépare le passage à la note suivante. lwTempsNext1 = lwTemps; // Pour initialiser le générateur de fréquence. freqCalc = lwFrequ1 * pow(1.05946, nPow) ; tempsNote = lwTemps + modeleTempsNote*nDuration; ptrStep += 1; } // defTemps void son() { //========== // Teste si un changement d'état du signal 1 est imminent. if ((lwTemps - lwTempsNext1 + 1000ul >= lwDemiPeriode1) & bEtat_enable) { // Attente avant un changement d'état du signal 1 (stabiliser) while (lwTemps - lwTempsNext1 < lwDemiPeriode1) { lwTemps = micros(); } // Attente digitalWrite( pinFreqN, bEtat1); bEtat1 = 1 - bEtat1; digitalWrite( pinFreqP, bEtat1); // Prochain changement d'état, faisant vibrer le Haut-Parleur. lwTempsNext1 = lwTempsNext1 + lwDemiPeriode1; } } // son void loop() { //=========== // Génère un signal carré d'une fréquence sélectionnable. // Serial.print(sensorValue, DEC); // Serial.println(); lwTemps = micros(); // Ne lit l'état des boutons que si un bouton a été traité il y a plus de 0,2 secondes = 200000 [us]. if (lwTemps - lwTempsActionLast > 200000ul) { // Lecture de l'état des boutons, pour changer la fréquence ou la phase du signal nButtonPush = read_LCD_buttons(); if ( (nButtonPush == btnLEFT) || (nButtonPush == btnRIGHT) ) Menu1_Change(); // Changement de menu if ( (nButtonPush == btnUP) || (nButtonPush == btnDOWN) || (nButtonPush == btnSELECT) ) MenuTreat(); // Un bouton pressé, traitement } if(tempsNote <= lwTemps) { defTemps(panNotes[2*ptrStep - 2], panNotes[2*ptrStep-1]); if (panNotes[2*ptrStep-3] == 0) { // Fin de la mélodie defTemps(-360, 10); // Pause ptrStep=1; // Revient au départ. } // Pour debugging sprintf(acStr, "Step = %3d", ptrStep); strS = acStr; lcd.setCursor(0, 0); lcd.print(strS); } lwDemiPeriode1 = 500000000ul / freqCalc; // Demi période en micro-secondes du signal son(); } // loop // FIN
/* * ex0220_ultrasonic_sensor_HC_SR04.ino * Ultrasonic Sensor HC-SR04 and Arduino Tutorial* * * Crated by Dejan Nedelkovski, * www.HowToMechatronics.com * * c.f. http://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/ */ // defines pins numbers const int trigPin = 12; const int echoPin = 11; // defines variables long duration; // durée en micro-secondes int distance; // distance en centimètres void setup() { //============ pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin, INPUT); // Sets the echoPin as an Input Serial.begin(9600); // Starts the serial communication } // setup void loop() { //=========== // Envoie le signal de début de mesure sur le "trigPin" digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); // Met le "trigPin" à l'état haut durant 10 micro-secondes. delayMicroseconds(10); digitalWrite(trigPin, LOW); // Lecture sur "l'echoPin" du temps d'aller-retour, en microseconds duration = pulseIn(echoPin, HIGH); // Calcule de la distance entre le sonnar et l'objet qui a réfléchi l'impulsion sonor distance= duration*0.340/2; // 0.340 [mm / micro-secondes] est la vitesse du son dans l'air // Affiche le résultat Serial.print("temps [micro-secondes] = "); Serial.print(duration); Serial.print(" Distance [mm] : "); Serial.println(distance); delay(1000); // Attente } // loop /* Version pour l'afficheur LCD #include <LiquidCrystal.h> // includes the LiquidCrystal Library LiquidCrystal lcd(1, 2, 4, 5, 6, 7); // Creates an LCD object. Parameters: (rs, enable, d4, d5, d6, d7) const int trigPin = 12; const int echoPin = 11; long duration; int distanceCm, distanceInch; void setup() { lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distanceCm= duration*0.034/2; distanceInch = duration*0.0133/2; lcd.setCursor(0,0); // Sets the location at which subsequent text written to the LCD will be displayed lcd.print("Distance: "); // Prints string "Distance" on the LCD lcd.print(distanceCm); // Prints the distance value from the sensor lcd.print(" cm"); delay(10); lcd.setCursor(0,1); lcd.print("Distance: "); lcd.print(distanceInch); lcd.print(" inch"); delay(10); } */
/* ex380_moteur_pas_a_pas.ino Stepper Motor Control - speed control This program drives a unipolar or bipolar stepper motor. The motor is attached to digital pins 8 - 11 of the Arduino. A potentiometer is connected to analog input 0. The motor will rotate in a clockwise direction. The higher the potentiometer value, the faster the motor speed. Because setSpeed() sets the delay between steps, you may notice the motor is less responsive to changes in the sensor value at low speeds. Created 30 Nov. 2009 Modified 28 Oct 2010 by Tom Igoe */ #include <Stepper.h> const int stepsPerRevolution = 32; // change this to fit the number of steps per revolution // for your motor #define pinIN1 8 // IN1 on the ULN2003 driver 1 #define pinIN2 9 // IN2 on the ULN2003 driver 1 #define pinIN3 10 // IN3 on the ULN2003 driver 1 #define pinIN4 11 // IN4 on the ULN2003 driver 1 // initialize the stepper library on pins 8 through 11: //Stepper myStepper(stepsPerRevolution, 10, 11, 9, 8); // 11, 10, 9, 8 pas bon //Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11); // Tourne dans le sens des aiguilles d'une montre //Stepper myStepper(stepsPerRevolution, 9, 10, 11, 8); // Tourne dans l'autre sens (sens trigonométrique), mais pas bien //Stepper myStepper(stepsPerRevolution, 10, 11, 8, 9); // Tourne dans le sens des aiguilles d'une montre //Stepper myStepper(stepsPerRevolution, 11, 8, 9, 10); // Tourne dans l'autre sens (sens trigonométrique), mais pas bien //Stepper myStepper(stepsPerRevolution, 11, 9, 10, 8); // Tourne dans le sens trigonométrique, bien //Stepper myStepper(stepsPerRevolution, pinIN4, pinIN2, pinIN3, pinIN1); // Tourne dans le sens trigonométrique, bien Stepper myStepper(stepsPerRevolution, pinIN1, pinIN3, pinIN2, pinIN4); // Tourne dans le sens des aiguilles d'une montre, bien int stepCount = 0; // number of steps the motor has taken void setup() { //============ // nothing to do inside the setup } // setup void loop() { //=========== // read the sensor value: int sensorReading = analogRead(A0); // map it to a range from 0 to 100: int motorSpeed = map(sensorReading, 0, 1023, 0, 100); motorSpeed = 10; // set the motor speed: if (motorSpeed > 0) { myStepper.setSpeed(motorSpeed); // step 1/16 of a revolution: myStepper.step(stepsPerRevolution / 16); } } // loopex0ex380_moteur_pas_a_pas.ino
/* ex381_moteur_pas_a_pas.ino Pilote de moteur pas à pas (Stepper motor) Tiré du site Web : http://42bots.com/tutorials/28byj-48-stepper-motor-with-uln2003-driver-and-arduino-uno/ La librairie utilisée ici est meilleure que la librairie standard. J'ai téléchargé la librairie "AccelStepper.h" du site : http://www.airspayce.com/mikem/arduino/AccelStepper/ Précisément de : http://www.airspayce.com/mikem/arduino/AccelStepper/AccelStepper-1.57.zip Je l'ai installé en faisant : Croquis > Inclure un librairie > Ajouter la librairie .ZIP ... J'ai sélectionné le fichier : "AccelStepper-1.57.zip" que j'ai téléchargé de l'adresse indiquée ci-dessus. J'ai changé les n° de pin pour avoir la bonne correspondance. Compilé + Téléverser, cela a immédiatement fonctionné. Le moteur accélère, puis décélère et repard dans l'autre sens de manière identique. C'est la librairie qui se charge de faire tout le travail. ***********************************************************/ #include <AccelStepper.h> #define HALFSTEP 8 // c.f. AccelStepper.h // 8 signifie qu'il y a 4 fils et que l'on utilise les demis pas. #define FULL4WIRE 4 // c.f. AccelStepper.h // 4 signifie qu'il y a 4 fils et que l'on n'utilise PAS les demis pas. // Motor pin definitions #define motorPin1 8 // IN1 on the ULN2003 driver 1 #define motorPin2 9 // IN2 on the ULN2003 driver 1 #define motorPin3 10 // IN3 on the ULN2003 driver 1 #define motorPin4 11 // IN4 on the ULN2003 driver 1 // Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48 AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4); //AccelStepper stepper1(FULL4WIRE, motorPin1, motorPin3, motorPin2, motorPin4); void setup() { //============ stepper1.setMaxSpeed(1000.0); stepper1.setAcceleration(100.0); stepper1.setSpeed(200); stepper1.moveTo(20000); } // setup void loop() { //=========== //Change direction when the stepper reaches the target position if (stepper1.distanceToGo() == 0) { stepper1.moveTo(-stepper1.currentPosition()); } stepper1.run(); } // loopPas d'image associée, le branchement étant très simple et décrit dans le site : une bonne référence (en anglais).
/* ex0385_moteur_pas_a_pas_LiquidCrystal.ino Avec l'afficheur à cristaux liquide et 5 boutons de commande. Le but est d'utiliser un chip L293 pour piloter un moteur pas à pas bipolaire (28B>J-48). Il manque beaucoup de fonctionnalités, telles que : ° Une rampe d'accélération ° un changement de sens de rotation ° aller à une position donnée et s'arrêter Connections : LCD Arduino (pin) ou tension 1 - Vss = 0 V 2 - Vcc = 5 V 3 - V0 = Tension variable réglée par une résistance variable, pour la lumineusité de l'affichage 4 - RS = pin 7 (Register Select) 5 - R/W = 0 V donc uniquement en Write 6 - E = pin 6 Enable, mise à haut pour accepter les données. 7 .. 10 = connecté à la commande de rétro-éclairage "back light" 11 - D4 = pin 5, données sur 4 bits 12 - D5 = pin 4, données sur 4 bits 13 - D6 = pin 3, données sur 4 bits 14 - D7 = pin 2, données sur 4 bits 15 - LED + = 220 Ohm - +5V 16 - LED - = 0V c.f. : http://www.arduino.cc/en/Tutorial/LiquidCrystal c.f. : https://arduino-info.wikispaces.com/LCD-Pushbuttons Pin qui restent libre et utilisables : 13, 12, 11, 3, 2, 0, 1 pin 0, pin 1, utilisé pour la transmission par USB, ======================================================== */ // include the library code: #include <LiquidCrystal.h> /*-----( Declare Constants )-----*/ #define pinFreqP 3 // pour générer une fréquence #define pinFreqOnOff 11 // pour enclencher ou arrêter le générateur de fréquences #define btnNONE 0 #define btnSELECT 1 #define btnLEFT 2 #define btnDOWN 3 #define btnUP 4 #define btnRIGHT 5 int nn = 0; int adc_key_in = 0; byte bButton = btnNONE; // Button pressed according to the value of adc_key_in byte bButtonLast = btnNONE; // Last button byte bButtonCount = 0; // compte le nombre de fois que le même boutton est détecté à la suite. // initialize the library with the numbers of the interface pins //LiquidCrystal lcd(RS, E, D4, D5, D6, D7); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); String strS = ""; // c.f. : https://www.arduino.cc/en/Reference/StringObject char acStr[20]; // Pour conversion de nombre en un string. int nButtonPush = btnNONE; // Bouton pressé byte bMenu1 = 1; // indique le menu sélectionné byte bMenu1_Last = 0; // indique le dernier menu sélectionné // que lorsque adc_key_in a suffisemment changé. String strCode = ""; // pour indiquer l'état du code unsigned long lwTempsNow = 0; // temps en micro secondes unsigned long lwTempsStart = 0; // temps au départ unsigned long lwTempsAffiche = 0; // temps du dernier affichage unsigned long lwTempsActionLast = 0; // temps en micro secondes de la dernière commande // Les 4 pins de contrôle du moteur pas à pas bipolaire #define pinO1 2 #define pinO2 3 #define pinO3 11 #define pinO4 12 int nCpt = 0; // Compteur pour le moteur pas à pas, compte le 4 étapes d'un pas byte bTourne = 0; // 0 == ne tourne pas, 1 == Full steps, 2 == HALF steps unsigned long lwTempsNextStep = 0; // temps pour le prochain pas unsigned long lwTempsDeltaStep = 20000; // temps entre deux pas void setup() { //============ // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.setCursor(0, 0); lcd.print("Moteur pas a pas"); lcd.setCursor(0, 1); lcd.print("Base sur un L293"); delay(2000); lcd.setCursor(0, 0); lcd.print(" "); // efface le texte lcd.setCursor(0, 1); lcd.print(" "); // efface le texte //lcd.autoscroll(); lwTempsNow = micros(); lwTempsStart = lwTempsNow; pinMode(pinO1, OUTPUT); pinMode(pinO2, OUTPUT); pinMode(pinO3, OUTPUT); pinMode(pinO4, OUTPUT); digitalWrite(pinO1, LOW); digitalWrite(pinO2, LOW); digitalWrite(pinO3, LOW); digitalWrite(pinO4, LOW); AfficheEtat(); delay(1000); } // setup int read_LCD_buttons() { // ====================== // Lecture du bouton appuié // Il faut détecter 10 fois de suite le même bouton pour qu'on estime détecté le bon bouton pressé. // L'avantage de cette manière de faire est que la lecture des boutons ne prend que // le temps d'une lecture analogique, soit environ 100 micro secondes. adc_key_in = analogRead(0); // read the value from the sensor // La lecture des boutons sont centrée autour des valeurs 0, 144, 329, 504, 741 // J'ai ajouté environ 50 à ces valeurs pour la détection des boutons if (adc_key_in > 790) { // Aucun bouton pressé. bButtonLast = btnNONE; bButtonCount = 0; return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result } else if (adc_key_in > 555) bButton = btnSELECT; else if (adc_key_in > 380) bButton = btnLEFT; else if (adc_key_in > 195) bButton = btnDOWN; else if (adc_key_in > 55) bButton = btnUP; else bButton = btnRIGHT; if (bButton == bButtonLast) { // Le même bouton a été détecté if (bButtonCount > 10) return bButton; // Le même bouton a été détecté .. fois de suite, donc c'est le bon bButtonCount++; // compte combien de fois de suite le même bouton est détecté. } else { bButtonLast = bButton; bButtonCount = 1; } return btnNONE; // On est pas encore sûr que le bon bouton est bButton. } // read_LCD_buttons void AfficheEtat() { //================== // Affichage de l'état du menu sélectionné if (bMenu1 == bMenu1_Last) return; // rien à faire if (bMenu1 == 1) { strS = "Mode de rotation :"; lcd.setCursor(0, 0); lcd.print(strS); if (bTourne == 0) strS = " STOP "; else if (bTourne == 1) strS = " FULL steps "; else if (bTourne == 2) strS = " HALF steps "; lcd.setCursor(0, 1); lcd.print(strS); } else if (bMenu1 == 2) { strS = "Delta steps (s):"; lcd.setCursor(0, 0); lcd.print(strS); sprintf(acStr, "delta-T=%8ld", lwTempsDeltaStep); strS = acStr; lcd.setCursor(0, 1); lcd.print(strS); } else if (bMenu1 <= 5) { // sprintf(acStr, "T = %7ld ", lwTempsNow - lwTempsStart); strS = ""; dtostrf( (lwTempsNow - lwTempsStart)/1000000.0, 8, 1, acStr); // temps au dixième de seconde strS = strS + acStr; lcd.setCursor(0, 0); lcd.print(strS); // dtostrf(lwFrequ1/1000.0, 8, 3, acStr); sprintf(acStr, "Tourne=%2d", bTourne); strS = acStr; if (bTourne == 0) strS = strS + " STOP "; else strS = strS + " "; lcd.setCursor(0, 1); lcd.print(strS); } } // AfficheEtat void MenuTreat() { //================ // On a appuyé sur un bouton, traite l'action adéquat. // Mémorise le temps de la dernière action utilisateur, pour pas en faire plusieurs lorsqu'on presse sur un bouton lwTempsActionLast = micros(); if (bMenu1 == 1) { // Arrêt du moteur ou changement de entre HALF step et FULL step if ( (nButtonPush == btnUP) || (nButtonPush == btnDOWN) ) { // Départ du chronomètre = départ des mesures lwTempsStart = lwTempsNow; lwTempsAffiche = lwTempsNow; lwTempsNextStep = lwTempsNow; if (nButtonPush == btnUP) { bTourne++; if (bTourne > 2) bTourne = 0; } if (nButtonPush == btnDOWN) { bTourne--; if (bTourne > 250) bTourne = 2; } // 0 - 1 = 255 if (bTourne == 0) { // Arrêt la rotation nCpt = 0; digitalWrite(pinO1, LOW); digitalWrite(pinO2, LOW); digitalWrite(pinO3, LOW); digitalWrite(pinO4, LOW); } else if (bTourne == 1) { // Utilise les pas entiers nCpt = 0; digitalWrite(pinO1, HIGH); digitalWrite(pinO2, LOW); digitalWrite(pinO3, LOW); digitalWrite(pinO4, HIGH); } else if (bTourne == 2) { // Utilise les demi-pas nCpt = 0; digitalWrite(pinO1, HIGH); digitalWrite(pinO2, LOW); digitalWrite(pinO3, LOW); digitalWrite(pinO4, LOW); } } } // bMenu1 == 1 else if (bMenu1 == 2) { // Change la vitesse de rotation if (nButtonPush == btnUP) { // Accélère lwTempsDeltaStep -= 1000; if (lwTempsDeltaStep < 1000) lwTempsDeltaStep = 1000; } if (nButtonPush == btnDOWN) { // Ralenti lwTempsDeltaStep += 1000; } } else if ((1 <= bMenu1) && (bMenu1 <= 5)) { // } AfficheEtat(); } // MenuTreat void Menu1_Change() { //=================== // Changement du Menu1 lwTempsActionLast = micros(); bMenu1_Last = bMenu1; // Mémorise le dernier menu if (nButtonPush == btnLEFT) { bMenu1 -= 1; if (bMenu1 == 0) bMenu1 = 2; // boucle } if (nButtonPush == btnRIGHT) { bMenu1 += 1; if (bMenu1 > 2) bMenu1 = 1; // boucle } AfficheEtat(); } // Menu1_Change void loop() { //=========== // Génère un signal carré d'une fréquence sélectionnable. // Serial.print(sensorValue, DEC); // Serial.println(); lwTempsNow = micros(); // Ne lit l'état des boutons que si un bouton a été traité il y a plus de 0,2 secondes = 200000 [us]. // Et si un nouveau pas moteur n'est pas imminant. if ( (lwTempsNow - lwTempsActionLast >> 200000ul) && (lwTempsNow + 1000ul - lwTempsNextStep < lwTempsDeltaStep) ) { // Lecture de l'état des boutons, pour changer la fréquence ou la phase du signal nButtonPush = read_LCD_buttons(); if ( (nButtonPush == btnLEFT) || (nButtonPush == btnRIGHT) ) Menu1_Change(); // Changement de menu if ( (nButtonPush == btnUP) || (nButtonPush == btnDOWN) || (nButtonPush == btnSELECT) ) MenuTreat(); // Un bouton pressé, traitement } //nADvalue = analogRead(A1); // Lecture de la tension sur le port analogique A0 // La tension varie entre 0 et 5 Volts, correspondant // aux nombre entre 0 et 1023. if (bTourne == 0) lwTempsNextStep = lwTempsNow; if ( (bTourne > 0) && (lwTempsNow - lwTempsNextStep > lwTempsDeltaStep) ) { lwTempsNextStep += lwTempsDeltaStep; if (bTourne == 1) { // tourne par pas entier, les deux bobines sont toujours sous tension. if (nCpt == 0) { // 1001 digitalWrite(pinO3, LOW); digitalWrite(pinO1, HIGH); } else if (nCpt == 1) { // 0011 digitalWrite(pinO4, LOW); digitalWrite(pinO2, HIGH); } else if (nCpt == 2) { // 0110 digitalWrite(pinO1, LOW); digitalWrite(pinO3, HIGH); } else if (nCpt == 3) { // 1100 digitalWrite(pinO2, LOW); digitalWrite(pinO4, HIGH); } nCpt++; if (nCpt >= 4) nCpt = 0; // boucle de 0 à 3 } if (bTourne == 2) { // tourne par demi-pas, une fois sur deux, une bobine est hors tension. if (nCpt == 0) { // 0001 digitalWrite(pinO4, LOW); } else if (nCpt == 1) { // 0011 digitalWrite(pinO2, HIGH); } else if (nCpt == 2) { // 0010 digitalWrite(pinO1, LOW); } else if (nCpt == 3) { // 0110 digitalWrite(pinO3, HIGH); } else if (nCpt == 4) { // 0100 digitalWrite(pinO2, LOW); } else if (nCpt == 5) { // 1100 digitalWrite(pinO4, HIGH); } else if (nCpt == 6) { // 1000 digitalWrite(pinO3, LOW); } else if (nCpt == 7) { // 1001 digitalWrite(pinO1, HIGH); } nCpt++; if (nCpt >= 8) nCpt = 0; // boucle de 0 à 7 } } if (lwTempsNow - lwTempsAffiche > 1000000ul) { // Affiche les mesures toutes les secondes AfficheEtat(); lwTempsAffiche = lwTempsNow; } } // loop
Plan du Site :
Home
Microcontroleur
code_exemples.html
( = http://www.juggling.ch/gisin/microcontroleur/code_exemples.html )
Page mise à jour le 25 juin 2020 par Bernard Gisin
( Envoyer un e-mail )
Hébergement par : www.infomaniak.ch