Je poste concernant mon projet de 3ème année en école d'ingénieur.
Je découvre à peine l'univers d'Arduino et j'utilise une Arduino Uno.
Mon projet consiste en la variation de la luminosité d'une ampoule LED dimmable via une application Android (déjà codée).
Depuis hier je suis sur la partie synchronisation secteur + gradateur (par angle de phase) et j'ai un soucis avec l'impulsion envoyé sur mon gradateur.
J'ai constaté dans un premier temps que l'ampoule ne réagissait pas comme je l'aurais souhaité. J'ai d'abord pensé à un soucis dans la programmation de l'impulsion et puis je me suis penchée sur le comparateur et j'ai l'impression que le programme ne capte pas le passage par 0 de l'onde secteur (sur l'oscillo, on voit l'onde secteur mais au lieu d'avoir l'impulsion de commande qui est fixe par rapport à cette onde, elle bouge.. et puis j'ai tenté le Serial.println(interrupt_var) avec interrupt_var qui est ma variable qui se met à 1 lors du passage par 0 de l'onde secteur, et elle vaut toujours 0...).
Je vous poste ici mon code. Vous constaterez dans le code que dans la fonction void loop, il y a des morceaux de programme en commentaire car j'ai fait pas mal de test d'envoi d'impulsions, certains avec des delay, d'autre sans, mais pas de différence...
Ce projet me tient vraiment à coeur et il me reste un mois pour le finir, et ce problème est vraiment bloquant.
Merci de votre aide.
volatile int interrupt_var=0; // Variable d'interruption (cette variable se met à 1 lorsque le comparateur détecte le passage par 0 de l'onde secteur)
int LED=12; // Sortie numérique (impulsion envoyée au gradateur)
byte impulse= HIGH;
unsigned long dateDernierChangement = 0;
unsigned long dateDernierChangementloop = 0;
int T=10; // période du signal de commande.
void setup() {
Serial.begin(9600);
pinMode(LED,OUTPUT);
interrupt_var = 0;
ADCSRB &= ~(1<<ACME); // force le bit ACME à 0 sans modifier les autres: entrée AIN1(pin7, entrée -) sélectionnée
ACSR = (1<<ACIE) | (1<<ACIS1); // force les bits ACIE et ACIS1 à 1 et les autres à 0 (ACIE=1 / ACIS1=1 et ACIS0=0 : interruption activée déclenchée quand la sortie du comparateur passe à 0)
DIDR1 = (1<<AIN1D) | (1<<AIN0D); // force les bits AIN1D et AIN0D*/
}
ISR (ANALOG_COMP_vect){ //fonction d'interruption, Variable d'interruption (cette variable se met à 1 lorsque le comparateur détecte le passage par 0 de l'onde secteur)
interrupt_var=1;
}
void loop() {
int t=2; // variable comprise entre 0 et 10ms (2mc pour l'exemple) qui indique le retard de l'impulsion pa rapport à l'onde secteur
if (interrupt_var==1){
impulse=LOW;
digitalWrite(LED,impulse);
delay(t);
impulse=HIGH;
digitalWrite(LED,impulse);
delay(T-t);
}
//ICI L'AUTRE BOUT DE CODE QUE J'AI FAIT POUR GENERER L'IMPULSION DE COMMANDE
/*unsigned long dateCourante = millis();
unsigned long intervalle = dateCourante - dateDernierChangement;
if (interrupt_var==1){
if (impulse == HIGH && intervalle > t) {
impulse = LOW; // passage a l'état HAUT
digitalWrite(LED, impulse);
dateDernierChangement = dateCourante;
}
else if (impulse == HIGH && intervalle > 10-t) {
impulse = LOW; //allumage de la DEL car elle est éteinte (LOW) et 980ms se sont écoulées
digitalWrite(LED, impulse);
dateDernierChangement = dateCourante;
}
}*/
}
Alors pour détecter le passage par zéro, j'ai crée une carte électronique qui me permet de redresser la tension du secteur (j'utilise un pot de diode). J'utilise le comparateur analogique intégrée à la carte arduino et je fais rentrer cette tension redressée dans l'entrée 6 (AIN0). Sur la carte de synchronisation, je fais aussi un pont diviseur de tension que je fais rentrer dans l'entrée 7 (AIN1). Cette tension est de 0.1V. (Je vous joins une photo de la carte et de mon schéma)
Je précise qu'entre la carte et le secteur, j'ai un transfo 2x6V.
Comme vous voyez dans le code, je dis que si il y a detection du passage par 0 de l'onde secteur, je met interrupt_var à 1. Or j'ai l'impression que cette variable reste toujours à 0. J'ai testé hier un Serial.println de cette variable et elle est toujours à 0... Peut-être que cela explique tout?
Qu'entends-tu par "raccordement de l'entrée de l'arduino au secteur "?
Le signal que tu vois sur l'oscillo correspond au signal que je fais rentrer dans AIN0 (pin 6). Je l'ai abaissé à environ 5V grâce à un pont diviseur de tension.
La carte est la carte de synchronisation, avec les 2 pont diviseur et le pont de diode.
Merci de ta réponse.
De plus, j'aurais voulu voir le signal crée par le comparateur, je sais qu'il est en rapport avec le bit ACO (j'ai vu cela dans la doc de l'arduino) mais je ne sais pas comment le visualiser.
Bonjour,
normalement 2 diodes suffisent
cela dit le montage est correct, c'est un très bon départ
en rapport avec le bit ACO
on sort un peu des domaines habituels d'utilisation de l'arduino, donc on ne va pas trouver tout ce dont tu as besoin dans sa doc
en se référant au datasheet du microchip atmega328p, on peut voir que ce signal n'est pas directement accessible par une broche
il y a amha 3 méthodes pour le visualiser :
le scruter dans la boucle principale et le recopier sur une sortie, why not ...
déclencher une interruption à sa sortie (voir le module de l'AC), qui se charge de recopier ACO sur une broche
utiliser une partie du module timer1, (voir le module capture du timer1), déclencher une interruption qui se charge de recopier ACO sur une broche. Cette solution a l'air complexe, mais elle permet d'utiliser le Noise Canceler du timer1, donc d'éliminer quelques parasites mal venus dans ton application
Qu'entends-tu par domaine habituel?
J'avais posté il y a quelques mois une question en rapport avec la synchronisation du signal de commande sur le signal de secteur, on m'avait dit d'utiliser le comparateur, ce qui m'a semblé être une bonne idée.
Peux-tu m'expliquer plus en détails tes 2 premières méthodes s'il te plait? Car je ne vois pas comment procéder.
En tout cas je ne comprend pas pourquoi mon signal de commande bouge par rapport à mon signal de secteur
Pensez-vous que si j'utilise le pin2 de ma carte arduino pour déclencher une interruption à chaque detection par 0 cela réglera le soucis?
Puis-je faire entrer le signal en photo sur le pin 2 de la carte arduino?
Je pensais qu'elle se remettait à 0 automatiquement en fait
J'imaginais qu'elle était toujours à 0 et que lorsque la tension du secteur passait par 0 elle se mettait à 1 et se remettait à 0 ensuite.
on prépare ACSR à la fin du setup
// mettre en commentaire le rôle de chaque bit
ACSR = 0b10001000
et dans la routine d'interruption
ISR(ANALOG_COMP_vect ) {
// mettre comme en 1)
// noter que " ACI is cleared by hardware when executing the corresponding interrupt handling vector"
}
ACO est défini dans les fichiers de configuration écrit par ATMEL.
Ces fichiers sont cohérents avec les "termes" de la datasheet.
Ces fichiers sont obligatoires pour programmer les micro-contrôleur en C ou C++
Ils sont bien évidement inclus dans l'IDE comme bien d'autres fichiers et programmes provenant de la société ATMEL qui conçoit le microcontrôleur..
Pour un micro 328p le fichier s'appelle "iom328p.h"
On peut lire : #define ACO 5
A ce sujet malgré que tu a 40 posts au compteur tu n'indique toujours pas le matériel que tu utilises.
Méfie toi nos boules de cristal ne sont pas fiables.
(1<<AC0) ou comme ACO vaut 5 (1<<5)
C'est ce qu'on appelle de la manipulation de bit. Certains qui parlent anglais disent du bitwase.
Tout bon tuto de C te donnera une explication claire sur la manipulation de bit et les décalages à droite ou à gauche.
Je ne suis pas un bon tuto de C, je vais faire de mon mieux :
Il faut raisonner en notation binaire.
Cela revient à décaler un bit 1 de 5 fois vers la gauche.
J'ai enfin réussi ce que je souhaitais.
J'ai les bons signaux Le seul soucis maintenant c'est que quand je branche mon ampoule au système, sa luminosité ne varie pas peu importe la commande mais j'ai ma petite idée dessus (soucis d'électronique).
En tout cas je tenais à vous remercier car depuis le début de mon projet je poste sur ce forum et j'obtiens toujours des réponses claires.
Cela me donne envie de continuer à me plonger dans l'univers d'Arduino.
Je partage mon code ici, cela pourrait servir
int imp=12;
void setup() {
Serial.begin(9600);
pinMode(12, OUTPUT);
ACSR |= (1<<ACI); // clear Analog Comparator interrupt
ACSR |=
(0<<ACD) | // Comparator ON
(0<<ACBG) | // Disconnect 1.23V reference from AIN0 (use AIN0 and AIN1 pins)
(1<<ACIE) | // Comparator Interrupt enabled
(0<<ACIC) | // input capture disabled
(1<<ACIS1) | // set interrupt bit on rising edge
(1<<ACIS0); // (ACIS1 and ACIS0 == 11)
}
ISR (ANALOG_COMP_vect){ //fonction d'interruption, Variable d'interruption (cette variable se met à 1 lorsque le comparateur détecte le passage par 0 de l'onde secteur)
}
void loop() {
if ( (ACSR & (1 << ACO))== 0 ){ //if (ain1 > ain0)
digitalWrite(imp, LOW);
delay(5);
}
else {
digitalWrite(imp, HIGH);
}
}
//http://www.realtechsupport.org/UB/CM/code/arduino/AnalogInterrupt/AnalogInterrupt.ino
Bonjour,
malheureusement je crains que les "ampoules led" en 230V AC ne soit pas graduables...
Impossible de les graduer avec un gradateur professionnel, de théâtre.
Les leds se graduent en basse tension, en PWM ou en courant.