Bonjour
Je suis novice en programmation de l'Arduino et j'ai besoin d'un générateur d'impulsion en signal carré de 5volts dans une gamme de 15 Hz à 250 Hz
Je dispose d'une carte UNO et d'un shield avec les touches et le LCD
J'aurais voulu trouver un projet similaire avec ce shield mais mes recherches tombent sur des générateurs BF qui utilisent des circuits complémentaires comme l'AD9850.
En fait j'ai besoin de quelque chose de simple qui affiche la fréquence et que l'on ajuste par le clavier
Je sais que pour certains d'entre vous c'est super facile à programmer, mais j'aurai préférer adapter un programme existant.
Bonjour,
Ici un projet qui ressemble à ce que tu souhaites faire.
Urbann:
Bonjour
Je suis novice en programmation de l'Arduino et j'ai besoin d'un générateur d'impulsion en signal carré de 5volts dans une gamme de 15 Hz à 250 Hz
Je dispose d'une carte UNO et d'un shield avec les touches et le LCD
J'aurais voulu trouver un projet similaire avec ce shield mais mes recherches tombent sur des générateurs BF qui utilisent des circuits complémentaires comme l'AD9850.
En fait j'ai besoin de quelque chose de simple qui affiche la fréquence et que l'on ajuste par le clavier
Je sais que pour certains d'entre vous c'est super facile à programmer, mais j'aurai préférer adapter un programme existant.
bonjour
quelle resolution de pas souhaite tu entre 15 et 250 Hz ?
si tu n'a besoin que d'un signal carré à une resolution de 1Hz (pas de progression)
c'est tres simple à coder
Bonjour
Merci Kamill
Effectivement je dois pouvoir adapter
Par contre ce programme utilise des fonctions avancées pour moi
Vu que j'avais besoin d'une fréquence très basse, je pensais que cela pouvait se faire avec des tempos plus simple à gérer.
Artouste:
bonjour
quelle resolution de pas souhaite tu entre 15 et 250 Hz ?
si tu n'a besoin que d'un signal carré à une resolution de 1Hz (pas de progression)
c'est tres simple à coder
Idéalement j'ai besoin de 8 valeurs de fréquence qui s’établissent en appuyant sur 2 boutons montée et descente et de l'affichage de cette fréquence sur le LCD.
Urbann:
Idéalement j'ai besoin de 8 valeurs de fréquence qui s’établissent en appuyant sur 2 boutons montée et descente et de l'affichage de cette fréquence sur le LCD.
expose ce que tu a déjà tenté de programmer
avec ce que tu a sous la main .
C'est pour un projet "scolaire" ? 8)
J'ai besoin de tester plusieurs bobines pour un allumage CDI (compétition moto).
La partie électronique de ces allumages est scellée et l'optimisation des perfs se fait par la sélection des pièces (règlement)
Donc l'idée est de générer un signal carré à la place du capteur à effet de hall avec un Arduino et de mesurer la courbe de retard à l’allumage avec un oscillo.
Les moteurs tournent de 1000 à 15000 RPM soit une fréquence de 15 hz à 250 kz
J'ai dans mes cartons une carte UNO avec le shield LCD + pad.
Je n'ai rien codé pour l'instant, j'envisage plutôt d'adapter un programme existant
Voili Voilou...
Urbann:
J'ai besoin de tester plusieurs bobines pour un allumage CDI (compétition moto).
La partie électronique de ces allumages est scellée et l'optimisation des perfs se fait par la sélection des pièces (règlement)
Donc l'idée est de générer un signal carré à la place du capteur à effet de hall avec un Arduino et de mesurer la courbe de retard à l’allumage avec un oscillo.
Les moteurs tournent de 1000 à 15000 RPM soit une fréquence de 15 hz à 250 kz
J'ai dans mes cartons une carte UNO avec le shield LCD + pad.
Je n'ai rien codé pour l'instant, j'envisage plutôt d'adapter un programme existant
Voili Voilou...
bon , je vais considérer que tu n'est pas un collégien qui vient chercher du tout cuit ici 8)
ci-dessous un petit prog qui sort du signal carré sous 8 valeurs (étagées à la louche)
avec palier de 2 secondes
a ce stade pas de lcd , ni de BP
c'est simplement pour voir si la reaction moteur est "conforme"
int rpm[] = {15, 30, 50, 80, 125,150,200,250}; // 8 valeurs à choisir
void setup() {
}
void loop() {
for (int i=0; i <= 7; i++){
tone(13, rpm[i]); // signal carré sortie sur pin 13 (led embarquée uno)
delay(2000); // durée d'un palier en ms
}
}
Merci Artouste
A +de 50ans si j'étais encore à l'école, j'aurais redoublé quelques fois...
La fonction tone est très appropriée effectivement
J'ai un signal carré sur la borne 13 dont la fréquence change sur la tempo de 2sec
Le signal sur oscilloscope est un peu déformé à 15hz mais c'est largement bon pour déclencher la bobine
Jusqu'à là j'ai compris
C'est fort de faire déjà tout ça en 4 lignes.
Pour les boutons et le LCD, j'ai trouvé ça
Pour choisir le fréquence:
Je dois interrompre la boucle par une condition d'appui sur une touche + mais dans ce cas comment décrémenter avec une autre touche -
Urbann:
Merci Artouste
A +de 50ans si j'étais encore à l'école, j'aurais redoublé quelques fois...La fonction tone est très appropriée effectivement
J'ai un signal carré sur la borne 13 dont la fréquence change sur la tempo de 2sec
Le signal sur oscilloscope est un peu déformé à 15hz mais c'est largement bon pour déclencher la bobine
Jusqu'à là j'ai compris
C'est fort de faire déjà tout ça en 4 lignes.
Pour les boutons et le LCD, j'ai trouvé çaPour choisir le fréquence:
Je dois interrompre la boucle par une condition d'appui sur une touche + mais dans ce cas comment décrémenter avec une autre touche -
je n'ai jamais utilisé ce module LCD+kjeypad mais normalement le programme dessous (compile ok )
si tes cablages sont ok , ça devrais faire une augmentation de vitesse lors d'un appui sur up jusqu'au max et d'une diminution (j'ai ajouté un poste à vitesse 0) lors d'un appui sur down jusqu'à vitesse 0.
NB attention a penser à utiliser un autre pin que le pin13 en situation reelle (clignotements au reset)
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>
/*******************************************************
This program will test the LCD panel and the buttons
Mark Bramwell, July 2010
********************************************************/
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int rpm[] = {0,15, 30, 50, 80, 125,150,200,250}; // 8 valeurs à choisir en plus du zero
byte im=0; // indice vitesse moteur
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
// For V1.1 us this threshold
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
// For V1.0 comment the other threshold and use the one below:
/*
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
*/
return btnNONE; // when all others fail, return this...
}
void setup()
{
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
lcd.print("Push the buttons"); // print a simple message
}
void loop()
{
lcd.setCursor(9,1); // move cursor to second line "1" and 9 spaces over
lcd.print(millis()/1000); // display seconds elapsed since power-up
lcd.setCursor(0,1); // move to the begining of the second line
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnRIGHT:
{
lcd.print("RIGHT ");
break;
}
case btnLEFT:
{
lcd.print("LEFT ");
break;
}
case btnUP:
{
im=im+1;
if (im > 8) im=8;
lcd.print("UP ");
lcd.print(rpm[im]);
tone(13, rpm[im]); // signal carré sortie sur pin 13 (led embarquée uno)
break;
}
case btnDOWN:
{
im=im-1;
if (im < 0) im=0;
lcd.print("DOWN ");
lcd.print(rpm[im]);
tone(13, rpm[im]); // signal carré sortie sur pin 13 (led embarquée uno)
break;
}
case btnSELECT:
{
lcd.print("SELECT");
break;
}
case btnNONE:
{
lcd.print("NONE ");
break;
}
}
}
avec affichage sur lcd
Je vais chercher à comprendre et adapter
J'espère que tu n'as pas passé trop de temps, parce que cette fois il y a plus de 4 lignes ...
Pour mon shield, le mode de traitement des touches est un peu particulier puisqu'il utilise une seule entrée analogique et reconnait les touches en fonction de la valeur de tension appliquée (c'est ce que j'ai compris).
Merci pour cette aide précieuse je te tiens au courant...
Urbann:
...
Pour mon shield, le mode de traitement des touches est un peu particulier puisqu'il utilise une seule entrée
...
J'espère que tu n'as pas passé trop de temps, parce que cette fois il y a plus de 4 lignes ...
Oui , j'avais compris que la gestion des touches est discriminée en fonction des valeurs du pont diviseur sur l'entrée A0.
en fait c'est juste l'exemple du shield avec qq controles et ajout de tone bien placé
J'ai avancé
Quelques modifications pour faire fonctionner les boutons
La fréquence (tone) de la UNO est au mini de 31hz. En dessous on a des signaux aléatoires avec des fréquences de l'ordre de 2,2 khz.
Moi qui devais démarrer à 15htz....
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>
/*******************************************************
This program will test the LCD panel and the buttons
Mark Bramwell, July 2010
********************************************************/
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int freq[7] = {31,50,80,125,150,200,250}; // 7 valeurs de fréquence Mini 31 pour la UNO
byte im=0; // indice vitesse moteur
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
// For V1.1 us this threshold
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
// For V1.0 comment the other threshold and use the one below:
/*
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
*/
return btnNONE; // when all others fail, return this...
}
void setup()
{
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
//lcd.print("Push the buttons"); // print a simple message
Serial.begin(9600);
Serial.print("Prêt !");
}
void loop()
{
lcd.setCursor(9,1); // move cursor to second line "1" and 9 spaces over
//lcd.print(millis()/1000); // display seconds elapsed since power-up
lcd.setCursor(0,1); // move to the begining of the second line
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnUP:
{
im=im+1;
if (im > 6) im=6;
Serial.println(im);
Serial.println(freq[im]);
Serial.println(" UP ");
lcd.clear();
lcd.print("UP ");
lcd.print(60*freq[im]);
tone(12, freq[im]); // signal carré sortie sur pin 12
delay(200);
break;
}
case btnDOWN:
{
if (im < 1) im=1;
im=im-1;
Serial.println(im);
Serial.print(freq[im]);
Serial.println(" Down ");
lcd.clear();
lcd.print("DOWN ");
lcd.print(60*freq[im]);
tone(12, freq[im]); // signal carré sortie sur pin 12
delay(200);
break;
}
}
}
D'autre part je me disais que plutôt que d'utiliser un oscillo pour mesurer le déphasage (avance) entre le signal de déclenchement de l'allumage et l'étincelle produite par la bougie, on pouvait peut être rentrer ce signal après mise en forme dans l'arduino et afficher la valeur de l'avance en degrés.
Pour faire simple on mesure le temps de décalage entre le front montant du signal de sortie (broche 12) et le front montant du signal d'entrée (broche à définir reliée à la bougie) et on l'affiche en degré sur le LCD.
Je ne sais pas si l'arduino sera assez rapide pour faire ce calcul.
Urbann:
J'ai avancé
Quelques modifications pour faire fonctionner les boutons
La fréquence (tone) de la UNO est au mini de 31hz. En dessous on a des signaux aléatoires avec des fréquences de l'ordre de 2,2 khz.
Moi qui devais démarrer à 15htz....D'autre part je me disais que plutôt que d'utiliser un oscillo pour mesurer le déphasage (avance) entre le signal de déclenchement de l'allumage et l'étincelle produite par la bougie, on pouvait peut être rentrer ce signal après mise en forme dans l'arduino et afficher la valeur de l'avance en degrés.
Pour faire simple on mesure le temps de décalage entre le front montant du signal de sortie (broche 12) et le front montant du signal d'entrée (broche à définir reliée à la bougie) et on l'affiche en degré sur le LCD.
Je ne sais pas si l'arduino sera assez rapide pour faire ce calcul.
Bonjour
alors tone() n'est pas la solution adaptée
fais un test avec le bout de code ci-dessous (compile ok , à l'oscillo çà a l'air OK)
c'est du codage simple , ça doit pouvoir s'optimiser en tapant directement dans les registres.
edit : dans la mesure où tu souhaite evoluer entre 15 et 250 ms , l'utilisation de la lib MsTimer2 semble parfaitement adequate.
mais déjà ça te permettra de verifier que ça descend suffisamment pour toi.
pour calculer le dephasage avec l'arduino , à chaud je dirais que ça ne posera pas de problemes , les contraintes temporelle sont faibles.
mais step by step ! 8)
int rpm[] = {14, 30, 50, 80, 125, 150, 200, 250}; // 8 valeurs à choisir
int dc = 0;
byte pinwave = 13;
unsigned long actuel; // millis actuel
int palier=2000; // duree palier en ms
void setup() {
pinMode(pinwave, OUTPUT);
}
void loop() {
for (int i = 0; i <= 7; i++) {
actuel = millis();
dc = rpm[i] / 2;
while ((millis()-actuel) < palier) {
digitalWrite(pinwave, HIGH);
delay(dc); // durée F°/2
digitalWrite(pinwave, LOW);
delay(dc); // durée F°/2
}
}
}
Bonjour
Le signal est moins propre qu'avec la fonction "Tone" mais c'est amplement suffisant. La fréquence basse à 850 hz fonctionne.
Pour un profane comme moi, le code apparait toujours comme "astucieux"
L'avantage de cette solution c'est que l'on peut gérer indifféremment le temps du signal haut et bas.
Urbann:
Bonjour
Le signal est moins propre qu'avec la fonction "Tone" mais c'est amplement suffisant. La fréquence basse à 850 hz fonctionne.
Pour un profane comme moi, le code apparait toujours comme "astucieux"
L'avantage de cette solution c'est que l'on peut gérer indifféremment le temps du signal haut et bas.
integre la lib mstimer2
et amuse toi avec les 2 codes ci-dessous 'compiles OK et test à l'oscillo verifié pour le 1er)
1er (random 8 postes d'acceleration)
2eme lib intégrée à ton code d'hier , qq modifs commentées
#include <MsTimer2.h>
byte pinwave = 13; // pin sortie
byte delt2 = 0;
byte var = 0;
int freq[] = {14, 30, 50, 80, 125, 150, 200, 250}; // 8 valeurs de fréquence
byte im = 0; // indice vitesse moteur
long val = 0; //random pour test
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println();
var = random(255) % 2 ; // modulo 2 pour simulation up/down
delay(150); // pour test oscillo toutes les x ms
Serial.print(" MODULO 2= ");
Serial.print(var);
switch (var) {
case 0:
{
im = im + 1;
if (im > 7) im = 7;
Serial.print(" SIM BOUTON UP ");
Serial.print(freq[im]);
delt2 = freq[im] / 2;
MsTimer2::set(delt2, flash); // period
break;
}
case 1:
{
im = im - 1;
if (im < 0) im = 0;
Serial.print(" SIM BOUTON DOWN ");
Serial.print(freq[im]);
delt2 = freq[im] / 2;
MsTimer2::set(delt2, flash); // period
break;
}
}
MsTimer2::start(); // start timer2
}
void flash() {
static boolean output = LOW;
digitalWrite(pinwave, output);
output = !output;
}
2eme
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>
#include <MsTimer2.h>
byte pinwave = 12; // pin sortie
byte delt2 = 0;
/*******************************************************
This program will test the LCD panel and the buttons
Mark Bramwell, July 2010
********************************************************/
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int freq[] = {14, 30, 50, 80, 125, 150, 200, 250}; // 8 valeurs de fréquence
byte im = 0; // indice vitesse moteur
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
// For V1.1 us this threshold
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
// For V1.0 comment the other threshold and use the one below:
/*
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
*/
return btnNONE; // when all others fail, return this...
}
void setup()
{
lcd.begin(16, 2); // start the library
lcd.setCursor(0, 0);
//lcd.print("Push the buttons"); // print a simple message
Serial.begin(9600);
Serial.print("Prêt !");
}
void loop()
{
lcd.setCursor(9, 1); // move cursor to second line "1" and 9 spaces over
//lcd.print(millis()/1000); // display seconds elapsed since power-up
lcd.setCursor(0, 1); // move to the begining of the second line
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnUP:
{
im = im + 1;
if (im > 7) im = 7;
Serial.println(im);
Serial.println(freq[im]);
Serial.println(" UP ");
lcd.clear();
lcd.print("UP ");
lcd.print(60 * freq[im]);
delt2 = freq[im] / 2;
MsTimer2::set(delt2, flash); // period
MsTimer2::start();
delay(200);
break;
}
case btnDOWN:
{
im = im - 1;
if (im < 0) im = 0;
Serial.println(im);
Serial.print(freq[im]);
Serial.println(" Down ");
lcd.clear();
lcd.print("DOWN ");
lcd.print(60 * freq[im]);
delt2 = freq[im] / 2;
MsTimer2::set(delt2, flash); // period
MsTimer2::start();
delay(200);
break;
}
}
}
void flash() {
static boolean output = LOW;
digitalWrite(pinwave, output);
output = !output;
}
Bonjour,
Je reprends le projet la semaine ayant été chargée.
La librairie mstimer2 génère des signaux très propres mais a un inconvénient c'est que la plus petite division est la milliseconde.
Or j'ai besoin de générer des couples de fréquences assez rapprochées du genre
900 RPM => 15hz => 66 ms
1100 RPM => 18,33hz => 54ms
Jusque là tout va bien
12500 RPM => 208hz => 4,8 ms
12700 rpm => 211hz => 4,7 ms
Et là ça coince car la valeur de la période ne peut être qu'un entier.
Urbann:
Bonjour,
Je reprends le projet la semaine ayant été chargée.La librairie mstimer2 génère des signaux très propres mais a un inconvénient c'est que la plus petite division est la milliseconde.
Or j'ai besoin de générer des couples de fréquences assez rapprochées du genre
900 RPM => 15hz => 66 ms
1100 RPM => 18,33hz => 54ms
Jusque là tout va bien12500 RPM => 208hz => 4,8 ms
12700 rpm => 211hz => 4,7 ms
Et là ça coince car la valeur de la période ne peut être qu'un entier.
Alors oriente toi vers une lib qui gere la µs (resolution max esperable confortablement sur uno= 4 µs )
pour test , avec les prog basiques plus bas , tu remplace delay() par delayMicroseconds();
Tu devrai regarder le mode CTC des timers.
Le mode CTC délivre un signal de type "horloge", c'est à dire que le temps du "1" est égal à celui du "0".
Je te préviens de suite tu ne trouvera rien sur Arduino il faudra lire la datasheet du micro que tu utilise et la télécharger sur le site du fabricant. Comme tu as une UNO il faudra télécharger la datasheet de l'Atmega328p sur le site d'Atmel.
Pour résumer sur un 328p les timers sont au nombre de 3 et ils peuvent prendre chacun le contrôle de 2 E/S.
Tout le monde pense qu'il n'y a que la PWM parce qu'arduino ne gère que ça mais ils peuvent faire plus.
Le timer 0 est utilisé par les fonctions arduino qui gèrent le temps (delay(), millis(), etc ) il est préférable de ne pas y toucher si tu veux conserver la possibilité d'utiliser ces fonctions dans ton programme.
Il reste le timer 1 et le timer 2.
Le timer 2 est 8 bits comme le timer 0, le timer 1 est un 16 bits et il te permettra de descendre en dessous du Hz.
Le time 2 peut recevoir une horloge externe qui peut par exemple être délivrée par le timer 1 en mode CTC ce qui permettrait de faire de la PWM a très très basse fréquence, je ne sais pas si cela t'intéresse ( je ne l'ai pas pratiqué, c'est juste déduit de ce que j'ai lu).
La tâche n'est pas insurmontable si tu lit l'anglais mais ce sera clairement moins facile qu'avec les fonctions arduino.
Il est des fois où il faut choisir : la performance ou la facilité qui est forcément réductrice.
Pour utiliser au maximum le micro il faut accepter de se faire un peu bobo à la tête.
Bonjour
J'ai utiliser le premier principe que m'avais donné Artouste et j'ai mis à jour le code
#include <LiquidCrystal.h>
/*******************************************************
Test avance allumage
********************************************************/
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
int del[] = {63158, 60000, 7059, 7018, 4839, 4819, 4800, 4781, 4762, 4743}; // 10 valeurs à choisir
int ind = 0; // indice delai
int dp=0; // demie période
float rpm; //Vitesse moteur Tours/Minutes
byte pinwave = 12;
//unsigned long actuel; // millis actuel
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // Valeur des résistances des boutons
// 0, 144, 329, 504, 741
// on ajoute 50 et on vérifie si l'on est proche
if (adc_key_in > 1000) return btnNONE; // valeur la plus probable en premier
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
return btnNONE; // Si pas de touche activée
}
void setup()
{
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
Serial.begin(9600);
Serial.print("Prêt !");
}
void loop()
{
lcd.setCursor(9,1); // Place le curceur en ligne 1 à la position 9
lcd.setCursor(0,1);
lcd_key = read_LCD_buttons(); // lesture du bouton
switch (lcd_key)
{
case btnUP:
{
ind=ind+1;
if (ind > 9) ind=9;
Serial.println(" UP ");
Serial.print(" Delai ");
Serial.println(del[ind]);
//rpm=(60000000*((float)1 / del[ind]));
Serial.print(" RPM ");
Serial.println(rpm);
lcd.clear();
lcd.print("UP ");
lcd.print(rpm);
delay (200);
break;
}
case btnDOWN:
{
if (ind < 1) ind=1;
ind=ind-1;
Serial.print(del[ind]);
Serial.println(" Down ");
Serial.print(" Delai ");
Serial.println(del[ind]);
//rpm=(60000000*((float)1 / del[ind]));
Serial.print(" RPM ");
Serial.println(rpm);
lcd.clear();
lcd.print("DOWN ");
lcd.print(rpm);
delay(200);
break;
}
default:
{
dp = del[ind] / 2; //demie période
digitalWrite(pinwave, HIGH);
delayMicroseconds(dp);
digitalWrite(pinwave, LOW);
delayMicroseconds(dp);
break;
}
}
}
Sur le principe ça fonctionne mais en faisant les mesures on se rend compte que le controleur ne suit pas la cadence. Plus on monte en fréquence + ça dérive
Pour simuler 12650 T/min le délai théorique est de 4,743 msec
A la sortie j'obtiens que 10700 T/min soit un délai de 5,607 msec
Presque 1msec de perdue dans l'exécution du code.
Le contrôleur ne suit pas la cadence avec ce type de programmation.
J'ai essayé de comprendre les recommandations de 68tjs, mais ça dépasse largement mes compétences.