//Template generale Arduino26a0819 //Ce texte est seulement pour reference , ne pas tenter de le compiler! #include //1k de memoire 8bits #include "TimerOne.h" //librairie non officielle #include //librairie officielle SoftwareSerial monBT(10, 11); //Objet monBT , RX sur D10, TX sur D11 #define led 9 //Sur D9 #define ledOn digitalWrite(led,1) //Plus court à écrire #define r 5 //une valeur //***********VARIABLES********************* char cd = 'a'; //Single quote, un car pas une string String maStr = "Hello"; //Objet String, double quotes String Ligne; const float monPI = 3.1416; //Flottant 32b = 8+24, 7 chiffres int unsigned long D = 210000; int a = 10, b = 3; int c = 45; int IntLigne = 0; //St Ligne convertie en entier int xval = 0; int yval = 0; int Nb[] = {0, 1, 8} ; //Tableau int Vb[100]; //Reserve 100 entiers en mémoire int Dinj[12,45,48][25,47 33];//Tableau à 2 dimensions char touches[LIGNES][COLONNES] = { // tableau de char à 2 dimensions {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} };// On le remplit ligne par ligne {{Ligne1}, {Ligne2}...}Rappel: l'index débute à 0 int *pN; //pointeur à un type int, non initialisé int *pB = &Nb[2]; //pointeur vers cet element soit 8 volatile int varIsr = 0; //Voir ISR //*****************FONCTIONS************************* void monISR() //pas de millis() car elle s'arrete ds une ISR { varIsr++; //Volatile pour ne pas etre viré par le compilo optimiseur } //*******************setup************* void setup() { pinMode(led, OUTPUT); //ou INPUT ouINPUT_PULLUP // Rien à declarer pour les entrée analogiques Serial.begin(9600); monBT.begin(115200); //Demarre BT //***********************loop()****************** void loop() { a = digitalRead(7); a = analogRead(0) ; //Lit A0 analogWrite(r, 210);//PWM sur pins3,5,6,9,10,11, de 0 à 255, T =2ms switch (a) { case 1: delay(1000); break; case 5: delay(2000); break; } maStr = maStr + "Bonjour" ;//Append a = maStr.toInt(); //Convertit en entier maStr = Serial.readStringUntil('\r'); //ou (10) for ( int i = 5; i < 152; i++) {} //si le deuxième champs est faux, sortie de boucle //les autres champs sont quelconques//break permet de sortir de FOR et WHILE a = millis(); //ms depuis le reset a = micros(); //µs delay(a); //ms delayMicroseconds(a);//µs //Timer0 8b utilisé par milli(), delay(2000); analogWrite pin 5 et 6 seulement //Timer1 16b Servo lib, analogWrite 9 et 10 //Rimer2 8b analogWrite 3 et 11 if (Serial.available()) //Si car dans le buffer { int b = Serial.parseInt();//Lit et conversion en int ou Serial.parseFloat() } a = constrain(a, 100, 300); //a sera entre 100 et 300, au pire sur une de ces bornes yval = map(xval, 0, 1023, 20, 412); //interpole pour calculer yval(xval) //xval varie de 0 à 1023, yval varie de 20 à 412 } //*****************Pointeurs************* /*Vaste sujet, terrifiant par certains aspects car generateur de bugs complexes. Il est vrai que le langage C crée la confusion dès le début par la syntaxe de déclaration des variables de type pointeur : int *ptA ; crée la variable ptA comme pointeur ( c’est à dire une adresse) vers toute variable de type int (entier). La confusion vient de l’astérisque "*" utilisée ensuite, dans un sens totalement différent, comme signe d’indirection.Par exemple : maVal = *ptA ; qui attribue à maVal, la valeur trouvée à l’adresse pointée par ptA. Si le langage comportait un mot réservé, disons "ptr" pour déclarer un pointeur, on aurait alors comme déclaration int ptr ptA ; Variable ptA, déclarée pointeur vers toute valeur entière, puis accès à cette valeur par indirection maVal = *ptA ; // "*" signifiant l’indirection En résumé, un pointeur contient une adresse.De plus un pointeur sait vers quel type de données il pointe ( ici un entier ). Notons que l’on ne peut imprimer la valeur d’un pointeur par Serial.print(ptA) ; par exemple. pN = &a;//pN pointeur initialisé vers a qui vaut 10 b = *pN; //Dereference pN, on obtient la valeur à l'adresse pointée, soit 10 Serial.println(b);//Imprime 10 Serial.println(*pB); //Comme *pB = &Nb[2], imprime 8 Serial.println(F("Hello")); //Chaine stockée dans les 32 k de flash et non dans les 2k de variables Serial.println("\t"); //tab ou \n ou \r pour new line , carriage return Timer1.initialize( a ); //a en µs Timer1.attachInterrupt(monISR); Timer1.stop(); attachInterrupt(0, monISR, RISING); //D2 ici car 0, sinon D3 avec 1. // autres valeurs FALLING, CHANGE,LOW,HIGH }*/ *******************************//Template_Debug********************** //Pour generer des points d'arret et affichage //Details sur http://a110a.free.fr/SPIP172/article.php3?id_article=144 /* Pour générer des pa() et pc() ,points d'arret et d'affichage de variable #define DEBUG // A mettre une fois en debut de sketch, puis à commenter pour ne plus generer les pa(), pc()quand on pense qute tout fonctionne //Macro pa(v)de debug pour imprimer le numéro de ligne, le nom d’une variable, sa valeur, puis s’arrêter et attendre un clic de souris sur le bouton ’Envoyer’en haut de l’écran sériel pour continuer. #define pa(v) Serial.print("Ligne_") ; Serial.print(__LINE__) ; Serial.print(" ; ") ;Serial.print(#v) ;Serial.print(" = ") ; Serial.println((v)) ; Serial.println(" Clic bouton ’Envoyer’ pour continuer") ;while (Serial.available()==0) ; {int k_ = Serial.parseInt() ;} //Macro pc(v)de debug pour imprimer le numéro de ligne, le nom d’une variable, sa valeur, puis continuer l’execution #define pc(v) Serial.print("Ligne_") ; Serial.print(__LINE__) ; Serial.print(" ; ") ;Serial.print(#v) ;Serial.print(" = ") ; Serial.println((v)) ; //***********Ensuite on insère ces triplets pour chaque pa() ou pc() #ifdef DEBUG pa(maVar1); // Arret , affiche et attente avant de continuer #endif #ifdef DEBUG pc(maVar2); // Affiche et continue saans attente #endif */ //Dialogue_Arduino_Smartphone_18_11_17 //Deux fonctions: AttendreLigne() et VoirSiLignePresente() //**************** AttendreLigne())********************** //Pour échanger une ligne de texte entre Smartphone et Arduinor //ligne entrée au clavier du Smartphone //Necessite un module HC 05 ou 06 connecté à l'Arduino en 9600bps //Pour s'affranchir des caractères de controle ( CR,LF,...) qui diffèrent suivant les applications Bluetooth //Certaines applis comme BlueTerm+ n'ont pas de buffer, un car tapé part tout de suite //Suivant les applis,on émet la chaine par une touche "Send ASCII" ou "Submit" ou "Enter" ... // La String "Ligne recevra" la chaine entrée sans le ou les car de fin de ligne //Application recommandée: "Bluetooth Terminal HC-05 " (OK aussi pour le HC06) //Autres applis: "Bluetooth Terminal-Domolin"," BlueTerm+",... //********************VoirSiLignePresente()*************** //Pour tester "au vol" si une ligne a été entré au clavier du smartphone. //On recupère Ligne ="" si aucun car tapé //*****************Comportement du buffer****************** //BT.available() a pour valeur le nombre de car dans le buffer //compris les car de fin de ligne CR(13) LF(10) //BT.read() retourne le premier car non lu et -1 si BT.available()=0 //c'est à dire si le buffer est vide //******************************************** #include SoftwareSerial BT(10, 11); // RX,TX respectivement vers le HC05/06 à 9600bps String Ligne; //On y accumule les car valides mais non les fin de ligne char carLu;//Recoit le car entré int intLigne = 0; //Ligne convertie en entier, à tout hasard /////////////////////////////////////////// void AttendreLigne()/////////////////////////////////// { //On n'en ressort qu'avec Ligne remplie while (BT.available() == 0); //on attend qu'un car soit present dans le buffer VoirSiLignePresente();//On va remplir Ligne } void monDelay_ms(int unsigned long delai)///////////////////////////// { //Attente en ms, remplace delay(), interdite avec les IT volatile float ct = 0; volatile float duree = delai * 100 / 1.25; //100 pour 1.25ms environ while (ct < duree) ct++ ;//Pour ne pas manquer un car } void VoirSiLignePresente()////////////////////////////////////// { //Si aucun car dans le buffer d'entrée, on ressort immediatement //sinon on accumule dans Ligne Ligne = ""; //String donc double quote while (BT.available() > 0) // BT.available()= nombre de car dans le buffer { monDelay_ms(300);//Pour ne pas manquer un car.Assez lent pour l'appli BlueTerm +,par exemple //qui envoie chaque car immediatement, sans touche "Envoi". Qd on entre 2 chiffres, il faut ces 300ms char carLu; carLu = BT.read(); //Si pas de car en attente ds buffer on sort tt de suite // if ((carLu >= 32 ////Car valable,alphabetique, on le garde // ) && (carLu <= 122))Ligne = Ligne + carLu; // Tous les autres car, tels CR,LF, !,&, + etc sont ignorés if ((carLu == 13) || (carLu == 10)); //ignorer CR et LF uniquement, garder les autres car else Ligne = Ligne + carLu; //Car valable,alphabetique ou autre, on le garde } //Le buffer est vide intLigne = Ligne.toInt(); //Convertir en entier a tout hasard } void setup() { //Pour tester AttendreLigne() BT.begin(9600);//La liaison série soft D10 et D11 vers module Bt HC05 ou 06 Serial.begin(9600);//!!!VERIFIER cette vitesse!! Serial.println("Salut, entrer une ligne depuis le sphone "); AttendreLigne(); Serial.println(Ligne); delay(1000); } /////////////////////////// void loop() { //Pour tester VoirSiLignePresente() Serial.println("On attend une ligne"); VoirSiLignePresente();// Si buffer vide on ressort tout de suite Serial.println(Ligne); delay(1000); } // testé dans Injecteur banc, attente d'une ligne complète void LireVal() //Attend une ligne de car terminée par CR ou LF et la convertit en entiers { char carLu; // Stock le car lu String Ligne = ""; //Accumule les car reçus du clavier while (1) { //On en sortira par CR ou LF // while (Serial.available() == 0); //Attendre un car pour le moniteur while (BT.available() == 0); //Attendre un car // carLu = Serial.read(); //Lit ce car pour le moniteur carLu = BT.read(); //Lit ce car delay(100); //Indispensable if ((carLu == 13 ) || (carLu == 10)) break;//Sortir Ligne = Ligne + carLu; //cumuler } Val = Ligne.toInt(); // convertir en entier, en general c'est utile // while (Serial.available() != 0)carLu = Serial.read(); //Purge pour le moniteur while (BT.available() != 0)carLu = BT.read(); //Purge } //*************************************************** //////////////////////////////////Et quand on est vraiment paumé //concernant les caractères émis par l'appli on essaie ce RENIFLEUR //Renifleur de caracteres sur liaison serie 181117 //On affiche sur le PC tous les car emis //les caract CR (13) Carriage Return et LF(10) Line Feed sont //detectés et affichés en toutes lettres "CR" et "LF" //Utile pour connaitre les car émis par une appli de type Terminal //Par exemple: "Bluetooth Terminal HC05" emet CR LF en fin de ligne //"Bluetooth Terminal-Domolin" emet LF en fin de ligne //"Blue Terml +" emet car par car, donc pas de LF mais un CR sur demande //Ici un module Bluetooth Hc05 ou06 est couplé en D10,D11. #include SoftwareSerial BT(10, 11); // RX,TX respectivement vers le HC05/06 à 9600bps char carLu; //caractere venant du module BT void setup() { BT.begin(9600);//La liaison série soft D10 et D11 vers module Bt HC05 ou 06 !!!VERIFIER cette vitesse!! Serial.begin(9600); Serial.println("Salut"); BT.println("Salut"); BT.println(); BT.println(); } void loop() { while (BT.available() == 0);//rien à lire { Serial.println(); Serial.print("BT.available() ligne 23= "); Serial.println(BT.available()); delay(1000); carLu = BT.read();// 1 car arrivé Serial.print("BT.available()ligne 27 = "); Serial.println(BT.available()); delay(1000); if (carLu == 13) { Serial.println("CR"); // carLu = 0;//Ne pas afficher à l'ecran } if (carLu == 10) { Serial.print("LF"); // carLu = 0;//Ne pas afficher à l'ecran } if (carLu != 0)Serial.println(carLu); } } //*****************Ecrire du code HTML en memoire Flash const char Mypage[] PROGMEM=R"------(Html)------" // //PROGMEM to store webpage HTML data const char MAIN_page[] PROGMEM = R"=====( //**************Code Html )====="; //************************* //************************* //Timer1_Timer2_Exemple //Les deux timers du Nano/Uno //Aller chercher les deux librairies sur; //https://github.com/PaulStoffregen/TimerOne //https://github.com/wimleers/flexitimer2 //Les mettre dans le repertoire " libraries" //Timr1 a pour unité les microsecondes //L'unité de Timer2 est ajustable //1.0/1000 pour 1 ms //0.1/1000 pour 100µs recommandé //0.01/1000 pour 10µs a des pbs de precision #include"TimerOne.h" #include void isr_Fin_T1() { Timer1.stop();//S'execute quand Timer1 overflow //Code ici } void isr_Fin_T2 () { FlexiTimer2::stop();//S'execute quand Timer2 overflow //Code ici } void setup() { Timer1.attachInterrupt(isr_Fin_T1); //Une fois pour toutes //Noter que l'isr attachée au Timer2 est déclarée à chaque appel } void loop() { //Lancer TMR1 et TMR2 pour 1200µs Timer1.initialize(1200); FlexiTimer2::set(12 / 100, 0.1 / 1000, isr_Fin_T2); FlexiTimer2::start(); }