Eclairage à led de vélo 3W+tracker (atmega, ESP32) maker

Encore pour tester le filtre, on aurait pu utiliser le traceur série pour tester le filtre du deuxième ordre numérique, mais on peut aussi utiliser une sortie PWM.

En effet, si l’on désire lire le signal carré ou un signal alternatif est connaitre les résultats du filtre numérique, il est possible d’utiliser une sortie PWM filtré analogiquement par un RC.
Avec une fréquence PWM de 32kHz, et un RC de (10kohms et une capacité de 33nF) donc une fréquence de coupure de 482Hz atténuera l’ondulation de la PWM de
On peut observer l’ondulation pour un rapport cyclique de 50% sur la figure suivante :

Cette ondulation est de 0.075V autour de la valeur moyenne.

Avec un signal sinusoïdal ou carré de 10Hz et la fréquence de coupure de 1Hz, on retrouve bien que la valeur moyenne du signal carré qui est donc bien filtré en réel et dans ISIS.

Mais si l’on met un signal sinusoïdale de fréquence de 1hz, l’atténuation est de 0.35 à la place de 0.7 par contre le déphasage est bien de -90°.

Evidemment pour une fréquence sinusoïdale de 0.1Hz, il n’y a plus d’atténuation et le déphasage est presque à 0°.

Le code avec la pwm et la conversion analogique est le suivant :

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TimerOne.h>
#include <avr/wdt.h>   //chien de garde


#define PWM3   3      //   timer2    
#define LED13    13       
LiquidCrystal lcd(9, 8, 4, 5, 6, 7);   // LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Configuration des variables


unsigned    int    temps=0; 

            float  entree=0;
            float  entree1=0;
            float  entree2=0;
         
            float  sortie=0;
            float  sortie1=0;
            float  sortie2=0;
            
            float  out=0;
 const float b1 =2;
 const float b2 =1;

             
            const float a1 =-1.911;
            const float a2 =0.915;
            
            const float gain =1000;   
                    

void setup() {
  pinMode(LED13, OUTPUT);
  pinMode(PWM3,OUTPUT);

  Timer1.initialize(10000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
  Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt
  lcd.begin(16, 2);                   //modifier pour un afficheur 20x4
  Serial.begin(9600); 

  TCCR2B = (TCCR2B & 0b11111000) | 0x01;         //pin 10  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet

  
}



// Interruptions  tous les 0.01s fait par le timer1***********************************
void callback()  {

/*
temps++;  
if (temps>4)         //1=singnal carré de 0.1s  5*routine d'interruption*2
{
temps=0;  //reset : attention cette boucle doit etre infereir à son temps d'execution
if (entree==1023) {entree=0;}  else {entree=1023;}  
 
}//temps>1
*/

      /* ----filtre passe pas Butterwoth 3émé ordre  pour fc=10hz,  fechantillon=1000Hz------   */
entree=analogRead(A0);         
//digitalWrite(LED13,HIGH);  //permet de mesurer à l'oscillo, le temps du calcul du filtre et le temps de la routine d'interruption
entree2=entree1;      //entree(n-2)
entree1=entree;       //entree(n-1)

sortie2=sortie1;      //sortie(n-2)
sortie1=sortie;        //sortie(n-1)

//sortie=entree+entree1*b1+entree2*b2+entree3*b3-sortie1*a1-sortie2*a2-sortie3*a3 ;   //filtre passe pas recursif ordre 3
sortie=(entree+entree1*b1+entree2*b2-sortie1*a1-sortie2*a2) ;   //filtre passe pas recursif ordre 2
out=sortie/gain;       //plus facile de diviser  que de multiplier


out = map(out, 0, 1023, 0, 255);   //mise à l'echelle

analogWrite(PWM3,out); 


//digitalWrite(LED13,LOW);
if (entree>=850) {digitalWrite(LED13,HIGH);}  else {digitalWrite(LED13,LOW);}  //test de la lecture du signal

/*  Serial.print(temps);
  Serial.print(";");    //creation du fichier CSV
  Serial.print("\t");
*/    
  Serial.print(entree);
  Serial.print(";");
  Serial.print("\t");
  
  Serial.print(out);
  Serial.print("\t");
  Serial.println(";");  //mise à la ligne dans le terminal

}//fin routine



///////////////////////////////////////////// Boucle correspondant à la fonction main 
void loop() {  
  lcd.setCursor(0,0); 
  lcd.print(entree,0);
   lcd.print("   ");

   
} // fin loop