La librairie EEPROM fait ça très bien toute seule ...
https://www.arduino.cc/en/Reference/EEPROMUpdate
ou alors à la main :
https://www.arduino.cc/en/Reference/EEPROMPut
https://www.arduino.cc/en/Reference/EEPROMGet
-----
La librairie EEPROM fait ça très bien toute seule ...
https://www.arduino.cc/en/Reference/EEPROMUpdate
ou alors à la main :
https://www.arduino.cc/en/Reference/EEPROMPut
https://www.arduino.cc/en/Reference/EEPROMGet
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Moi : 'non', mais google 'oui'
Quand au timer, ce n'est justement qu'un compteur qui s'incrémente sur un front : un front d'une horloge si tu veux compter du temps ... ou un front d'une pin si tu veux compter de impulsions
Tu peux commencer là : https://www.locoduino.org/spip.php?article84
Dernière modification par Seb.26 ; 24/03/2020 à 10h16.
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Bonjour seb.26
Pour l'eeprom tous ce que je voulais savoir c'etait si c'etait possible d'incrementee l'adresse de depart.
Ce qui n'empeche pas d'apprecier fortement les conseils et techniques donner par freepicbasic concernant le regroupement des variables en structure.
Je jetterai volontier un coup d'oeil à tes liens merci.
Concernant le frequencemetre du timers.. j'ai trouvé ça! Je pense que c'est exactement ce dons tu me parles!
(J'ai pas bien dormis ^^ )
https://www.robot-maker.com/ouvrages...vec-le-timer1/
Ça m'a permis d'y voir un peu plus clair, bon c'est lourd quand meme pour mon niveau et je n'ai pas encore put zieuter les codes.
Il me reste encore a creuser.. notamment par exemple le mode permettant de passer en falling plutot que rising.. bref..du travail de fond en perspective. Surtout que pour ce cas. Il ne s'agit que du timer1.
Merci pour les infos.
Oui, c'est ça, mais ce site a le don pour rendre compliqué un truc simple ... je trouve même la datasheet plus agréable ...Concernant le frequencemetre du timers.. j'ai trouvé ça! Je pense que c'est exactement ce dons tu me parles!
(J'ai pas bien dormis ^^ )
https://www.robot-maker.com/ouvrages...vec-le-timer1/
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
ça donne l'ampleur de la nébulosité du site LOL.
Est ce vraiment nécessaire pour faire au max 300hz ?
Pour mesurer des Mhz , oui surement !
J'ai trouvé cette page qui en parle;
https://www.reddit.com/r/arduino/com..._clock_source/
Sur le TMR0 il permet de sélectionner une pin D4 externe comme entrée du counter0 et choisir le front.
A vérifier si TMR1 peut aussi avoir une pin externe comme entrée ...
// start Timer 0
// External clock source on T0 pin (D4). Clock on rising edge.
TCCR0B = bit (CS02) | bit (CS01) | bit (CS00);
sei(); pour arrêter les int et cli(); pour remettre les int.
Quand on lit le counter on arrête puis on le remet , seulement pendant quelques instructions , le temps le plus court possible, on lit et on efface le counter et on remet l int.
Sur Microchip il y a pas mal d'exemples sur le net, sur Arduino je n'ai pas trouvé d'exemple tout fait.
Timer 1 a aussi une pin externe voir l'image jointe.
Quand on parle de nebulositee..là je suis en plein dedans..effectivement ça a vraiment l'air super interessant..
Decidement les trains sont vraiment à l'honneur pour ces choses. Je suis actuellement ça!
https://lesiteferroviaire.pagesperso...r-compteur.htm
Ça a l'air plutot bien detailler. Et y'a vraiment de quoi faire on dirait. Reste à voir si ma ptite tête sera à la hauteur..
Freepicbasic j'ai regarder ton lien. Et le mec dis que son prog marche pas. Par contre sympa l'image avec les cs12 11 10..
Il y a le mode a mettre pour rising et falling.
Bon j'ai encore BEAUCOUP de travail..mais deja ce que je crois avoir compris..
Les timers peuvent etre detourner pour etre incrementer..non pas par l'horloge du CPU mais par une broche exterieur.
T0 ou D4 pour timer0,
et T1 ou D5 pour timer1.
Il me manque encore l'info pour timer2.
Il faut du coup ce servir de leur flag de debordement comme condition de lecture / operation avec millis?
Mais theoriquement?..Ça bloque deja le timer0 qui gere millis?non!?
Là j'avoue que j'ai enormement de mal..
Sans pretendre y arriver, je compter faire flagger les t0 et t2 (8bits )
Apres avoir configurer leur nombre de depart( gruge de la remise a 0..exemple 50 comptages donc partir a 205)
Mais je vois mal le truc pour le coup..un timer ne peut pas?,et servir pour millis, et servir a compter je suppose.?
C'est chaud ton truc seb.26! Aller..j'y retourne. En brasse couler lestee..
Dernière modification par 2 terium ; 24/03/2020 à 17h08.
La mise en route du compteur externe est assez simple;
Le problème c est que l'on va utiliser un second timer pour avoir la base temps.Code:TCCR1A = 0b00000000; TCCR1B = 0b01000111; //CS10, CS11, CS12 à 1 : External clock source on T1 pin. Clock on rising edge. TCNT1 = 0x0000;
Et que sur Arduino les timers sont utilisés pour certaines fonctions.
Comme le PWM les servos et l horloge interne millis()
Sur le Nano ou Uno;
On condamne donc les pins 9,10 a ne pas faire de PWM.The Arduino has 3Timers and 6 PWM output pins. The relation between timers and PWM outputs is:
Pins 5 and 6: controlled by timer0
Pins 9 and 10: controlled by timer1
Pins 11 and 3: controlled by timer2
Si on utilise Timer1 et que l'on utilise millis comme base de temps (Timer0) sans int il suffit de lire TCNT1 et de le remettre à 0 puis faire le calcul.
Avec l'int il faudra utiliser aussi un Timer, Il faudrait savoir si le fait d'utiliser Timer0 influence ou bloque la fonction millis...?
Effectivement, certains timer sont nécessaire à Arduino (pour millis() et les PWM par exemple)
https://www.locoduino.org/spip.php?article84
Pour ta mesure, tu peux aussi dire que tu vas lire la valeur du timer toutes les 100ms (via millis()) et après lecture, tu remets à 0 ... pas besoin des IT du timer
Dernière modification par Seb.26 ; 25/03/2020 à 09h37.
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
millis(); utilise le Timer0...Pour ta mesure, tu peux aussi dire que tu vas lire la valeur du timer toutes les 100ms (via millis()) et après lecture, tu remets à 0 ... pas besoin des IT du timer
Mais on ne casse rien en l'utilisant.
On pourrait avoir un problème de temps réel en lisant millis , mais à 300hz , ça ira ...
Code://unsigned long My100ms; //int Count; if (millis()>=My100ms) { My100ms=millis() + 100; cli(); Count = TCNT1; TCNT1 = 0; sti(); ... calcul }
Bah si tu utilise le Timer0 pour compter les impulsions, plus rien ne marche dans Arduino, dons si : tu casses tout ... ??!!
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
il ne faut pas faire ce genre de code ...
Mais plutôt :
Et tu n'auras pas de soucis avec le débordement du uint32_t ;=Code:uint32_t lastMillis = 0; if( millis()-lastMillis >= 100 ) // 100ms { // ... calcul lastMillis = millis(); }
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Oui, bien sur , mais ça m'étonnerais que la moto fonctionne plusieurs jours sans s'arrêter avant de dépasser ...Et tu n'auras pas de soucis avec le débordement du uint32_t ;=
Dans une appli qui dure des jours , oui ça serait important !
La soustraction prend un peu de temps surtout avec des longs , la comparaison simple est surement plus rapide.
(Il faudrait voir le code asm pour savoir ce que fait le compilateur avec ce - 100.)
En temps réel avec des fréquences élevées ça peut avoir une importance, et aussi pour la précision.
J'aurais dû mettre la soustraction après la lecture du compteur.
Vu la fréquence ici, ça change pas beaucoup.
C est un choix à faire.
Petite recherche sur l'horloge Arduino
Bon , il y de quoi faire avant de dépasser LOL
http://arlotto.univ-tln.fr/arduino/a...nt-la-fonction
Pour une appli qui serait sous tension pendant plus de 50 jours ça aurait une importance.Le compteur de millisecondes est au format unsigned long int donc sur 32bits pour le compilateur avr-gcc. Il
est initialisé au reset et revient donc à zéro au bout de 2³² ms soit 4294967296 ms et donc 4294967296/(1000*3600*24) = 49,7 jours.
Mais dans le cas du dépassement après 50 jours ou retour à 0 du compteur ferait aussi une erreur.
Ou plutôt un bug bloquant ou plantage...
Il faudrait gérer ce cas particulier.
Messieurs!
Oui pour millis sans arrêt, il faut environ 50 jours!! par contre je confirme que touché au timers 0 met millis en vrac!!
"L’horloge 0 gère delay() and millis() et tout réglage modifie ces deux fonctions." (dans quelles étendues??)
Seb.26 ton truc sur le timers1 est en fait terriblement simple(c'en est presque ecoeurant de m’être autant manger le cerveau)!!
Voici le code que j'ai fais! Grâce aux deux précédentes interventions de Freepicbasic, ce que j'ai lût, et divers tests.
Il est fonctionnel! sans interruptions!
(dès qu'on met les mains dans le cambouis, on galère, mais on comprend mieux ^^!)
j'ai rajouté la ligne de code pour falling au cas où!Code HTML://Test utilisation timer T1 pour comptage impulsions //sur broche T1 qui est la broche D5 du nano unsigned long intervalRpm=200; // intervalle de relever de compteur (peut etre levé est remplacé en direct par la valeur voulue de partout!! unsigned long oldTime; unsigned int pulse; unsigned long compteurPulse; int rpmPin=5; // pin D5 prise RPM void setup () { #define DEBUG1 unsigned long oldTime=0; unsigned int pulse=0; unsigned long compteurPulse=0; pinMode(rpmPin,INPUT); ///////////////////////////////////////////////////////// Serial.begin(115200); #ifdef DEBUG1 Serial.print("***debut_programme***"); Serial.println(""); #endif DEBUG1 // initialisation du compteur T1 (PRISE RPM en FRONT MONTANT) TCCR1A = 0b00000000; TCCR1B = 0b01000111; //CS10, CS11, CS12 à 1 : External clock source on T1 pin. Clock on rising edge. //TCCR1B = 0b01000110; //CS10 à 0, CS11 et 12 à 1 : External clock source on T1 pin. Clock on falling edge. TCNT1 = 0x0000; // compteur à 0 } void loop () { rpmPin=digitalRead(5); if(millis()- oldTime>=intervalRpm) { pulse=TCNT1; TCNT1=0; oldTime=millis(); #ifdef DEBUG1 Serial.print ("pulse: "); Serial.print (pulse); Serial.println(""); #endif DEBUG1 } if(pulse!=0){ unsigned int rpm=0; rpm=((pulse*60000)/intervalRpm); compteurPulse += pulse; pulse=0; #ifdef DEBUG1 Serial.print ("RPM: "); Serial.print (rpm); Serial.println(""); Serial.print("compteurPulse: "); Serial.print(compteurPulse); Serial.println(""); #endif DEBUG1 } }
Le programme est très simple, c'est pour le principe!
J'ai comparé aussi les valeurs de retours entres attachinterrupt et timer/counter avec différents intervales, la stabilitée du timers est vraiment sympa! (voir PJ)
Je pense que les petits écart que l'on "peut" retrouver sont dû à ma maquette (1: le moteur est volant. 2: c'est des legos(frottements) et 3: la batterie s'use aussi...)
Test timer1 interval200ms.jpg
Test timer1 interval2s.jpg
Test attach interrupt.jpg
Dans tous les cas, on gagne tte les interruption de RPM!!
je voyais le truc beaucoup plus complexe à la base mais là c'est carrément abuser de simplicité! Je me demande même pourquoi en deux jour de web, je n'ai rien trouvé de ce type!!
Il semblerai que le timers2 n'ai pas de broche extérieur pour faire pareil, donc c'est dommage que timers0 soit réserver à millis()
(je suis presque sur que des malins peuvent intervertir les deux timers... mais moi, je ne m'y risquerai pas)
Dans tous les cas, même si je me servirai des interruptions pour D2 en KM/H, j'ai simplifier les RPM et "APPRIS" grâce à vos conseils!
Merci bien les gars!
dernières questions, vous vous devez savoir.
Pourquoi on retrouve beaucoup de variable en uint32_t ou uint16_t et qu'entendez vous par "IT" des timers ???
au plaisir, et encore merci!
Quand je lis ça je me demande une seule chose : pourquoi écrire quelque chose de faux par défaut et mettre quelque chose de juste quand c'est nécessaire ?? ...
-> Tu prends l'habitude de faire les choses comme elles doivent être faites et basta ... un problème de plus en moins ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
bah oui, c'est bien le but !
uint*_t = un type de donnée défini, par exemple uint16_t = "unsigned int 16 bits" ... donc tu sais ce que tu fais, alors que le int est assez flou en C ...Pourquoi on retrouve beaucoup de variable en uint32_t ou uint16_t et qu'entendez vous par "IT" des timers ???
( et ça oblige à se poser des questions sur ce que l'on va faire de cette variable ... et donc ne pas gaspiller RAM et CPU ... )
IT = InTerupts ... désolé du raccourci ...
Dernière modification par Seb.26 ; 26/03/2020 à 14h38.
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
bonjour à tous,
je profite de ce sujet sur les interruptions dans arduino pour éviter dans ouvrir un autre...
j'ai un problème d'interruption dans un code pour lire 5 débitmètres à effet hall sur un arduino uno et un lcd key pad.
le problème c'est que je peux lire les voie 1 et 2 qui sont sur les pin 2 et 3
mais pas les voies 3 4 5 sur les pins 11 12 13
les autres pins sont pris par le lcd.
j'ai cru voir que les pins 2 et 3 sont interrupts et pas les autres
y a t il un moyen de faire fonctionner différemment ou dois-je acheter une mega 2560 ?
Code:#include <LiquidCrystal.h> LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //pins const int voie1Pin = 2; //pin location of flow rate meter on voie1 line const int voie2Pin = 3; //pin location of flow rate meter on voie2 line const int voie3Pin = 11; //pin location of flow rate meter on voie3 line const int voie4Pin = 12; //pin location of flow rate meter on voie4 line const int voie5Pin = 13; //pin location of flow rate meter on voie5 line // variables volatile int voie1Pulsecount; //measuring the rising edges of the signal for the voie1 line volatile int voie2Pulsecount; //measuring the rising edges of the signal for the voie2 line volatile int voie3Pulsecount; //measuring the rising edges of the signal for the voie3 line volatile int voie4Pulsecount; //measuring the rising edges of the signal for the voie4 line volatile int voie5Pulsecount; //measuring the rising edges of the signal for the voie5 line unsigned int copyvoie1Pulsecount; unsigned int copyvoie2Pulsecount; unsigned int copyvoie3Pulsecount; unsigned int copyvoie4Pulsecount; unsigned int copyvoie5Pulsecount; double voie1Read; double voie2Read; double voie3Read; double voie4Read; double voie5Read; float TOTAL = 0; /*************************************************************************/ void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.clear(); lcd.setCursor(0,0); lcd.print("Water Flow Meter"); lcd.setCursor(0,1); lcd.print("****************"); delay(2000); pinMode(voie1Pin, INPUT); //initializes digital pin 2 as an input pinMode(voie2Pin, INPUT); //initializes digital pin 3 as an input pinMode(voie3Pin, INPUT); //initializes digital pin 11 as an input pinMode(voie4Pin, INPUT); //initializes digital pin 12 as an input pinMode(voie5Pin, INPUT); //initializes digital pin 13 as an input attachInterrupt(digitalPinToInterrupt(2), voie1RPM, RISING); //attaching voie1 pulse counter interrupt to pin 2 attachInterrupt(digitalPinToInterrupt(3), voie2RPM, RISING); //attaching voie2 pulse counter interrupt to pin 3 attachInterrupt(digitalPinToInterrupt(11), voie3RPM, RISING); //attaching voie3 pulse counter interrupt to pin 11 attachInterrupt(digitalPinToInterrupt(12), voie4RPM, RISING); //attaching voie4 pulse counter interrupt to pin 12 attachInterrupt(digitalPinToInterrupt(13), voie5RPM, RISING); //attaching voie5 pulse counter interrupt to pin 13 } /************************************************************************/ void loop() { static unsigned long lastsecond; if (micros() - lastsecond >= 1000000) { lastsecond += 1000000; getCount(); voie1Read = (copyvoie1Pulsecount / 7.5); //(voie1 pulse frequency / 7.5Q), = flow rate in L/min voie2Read = (copyvoie2Pulsecount / 7.5); //(voie2 pulse frequency / 7.5Q), = flow rate in L/min voie3Read = (copyvoie3Pulsecount / 7.5); //(voie3 pulse frequency / 7.5Q), = flow rate in L/min voie4Read = (copyvoie4Pulsecount / 7.5); //(voie4 pulse frequency / 7.5Q), = flow rate in L/min voie5Read = (copyvoie5Pulsecount / 7.5); //(voie5 pulse frequency / 7.5Q), = flow rate in L/min TOTAL = TOTAL + voie1Read + voie2Read + voie3Read + voie4Read + voie5Read; Serial.print("TOTAL:"); Serial.println(TOTAL); Serial.print ("voie1 : "); Serial.print (voie1Read, 2); //Prints the number calculated above Serial.println (" L/min"); Serial.print ("voie2 : "); Serial.print (voie2Read, 2); //Prints the number calculated above Serial.println (" L/min"); Serial.print ("voie3 : "); Serial.print (voie3Read, 2); //Prints the number calculated above Serial.println (" L/min"); lcd.clear(); lcd.setCursor(0,0); lcd.print(voie1Read, 1); lcd.setCursor(4,0); lcd.print(voie2Read, 1); lcd.setCursor(8,0); lcd.print(voie3Read, 1); lcd.setCursor(12,0); lcd.print(voie4Read, 1); lcd.setCursor(0,1); lcd.print(voie5Read, 1); lcd.setCursor(6,1); lcd.print("Total "); lcd.print(TOTAL/60,0); }} // functions ----------------------------------------------------- void voie1RPM (){ //This is the function that the interupt calls voie1Pulsecount++;} //This function measures the rising and falling edge of the hall effect sensors signal void voie2RPM (){ //This is the function that the interupt calls voie2Pulsecount++;} //This function measures the rising and falling edge of the hall effect sensors signal void voie3RPM (){ //This is the function that the interupt calls voie3Pulsecount++;} //This function measures the rising and falling edge of the hall effect sensors signal void voie4RPM (){ //This is the function that the interupt calls voie4Pulsecount++;} //This function measures the rising and falling edge of the hall effect sensors signal void voie5RPM (){ //This is the function that the interupt calls voie5Pulsecount++;} //This function measures the rising and falling edge of the hall effect sensors signal void getCount(){ noInterrupts(); copyvoie1Pulsecount = voie1Pulsecount; voie1Pulsecount = 0; copyvoie2Pulsecount = voie2Pulsecount; voie2Pulsecount = 0; copyvoie3Pulsecount = voie3Pulsecount; voie3Pulsecount = 0; copyvoie4Pulsecount = voie4Pulsecount; voie4Pulsecount = 0; copyvoie5Pulsecount = voie5Pulsecount; voie5Pulsecount = 0; interrupts();}
Bonsoir nicopro33250.
Il me semble que les attach interrupt sur la uno sont limitees seulement aux pins 2 et 3.
Comme on a put le voir dans ce fil. Tu peut aussi rajouter le timer1 et peut etre que sur la uno tu a plus de timer. Donc tu peut voir de ce coté eventuellement.
Tu peut aussi envisager dans le soft de lire des rpm different sur le meme timer en jouant sur des temps de lectures differents. Mais il faudra piloter avec des sorties de ta carte par exemple des transistor pour etre sur de mettre le signal que tu veut au bon moment. (Je sais pas si je suis tres clair mais en gros. Tu met les 5 retour capteur hall sur D5 et tu pilote celui que tu veut relever. Peut etre des diodes scotchy seront bienvenues aussi.) Je fais sur timer1 en nano une super aquisition des rpm en 200ms donc en 1s tu pourrais avoir tes 5 valeurs.
Tu peut surement faire pareil avec d2 et d3 en jouant avec les attach/detach pilotage de retour hall.. Mais le timer na meme pas besoin de declaration de pin..si il est configurer il prend les pulses qui arrive sur la broche. Tu na plus qu'a relever tcnt1 le coller dans une variable et le remettre a 0.
En esperant t'avoir filer une piste.
Bonne soiree.
Pour tes débitmetres, quelle fréquence de pulse ? ... car si ton CPU ne fait que ça, tu peux envisager de pooler aussi ... sinon tu utilises des mini CPU (tiny85 ?) pour compter les pulses et remonter tout ça au CPU principal via SPI par exemple ...
Tu peux aussi passer sur un uCPU avec plus de Timer, genre le 328PB
-> Donnes nous tes contraintes et on pourra t'aider ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>