Créer un site internet

3 - LED Fade

Ce projet permet de faire varier la luminosité d’une LED. Dans les fonctions Arduino, il y a la fonction AnalogWrite qui permet de faire varier la luminosité d’une LED. Cependant, cette appellation « AnalogWrite » ne convient pas vraiment car on ne peut pas écrire de valeur sur les broches analogiques. La fonction repose sur le PWM (Pulse With Modulation) des timers 0 (chapitre 15), 1 (chapitre 16) et 2 (chapitre 18). Il y a donc six ports qui peuvent supporter ce genre de fonctionnalité :
- D5 et D6 sur le timer 0 (8 bits) ;
- D9 et D10 sur le timer 1 (16 bits) ;
- D3 et D11 sur le timer 2 (8 bits).

Nous allons donc voir un programme qui permet d’écrire une valeur sur les ports correspondants. Pour avoir plus d’information sur le PWM, vous pouvez consulter cette page . Voici le programme pour écrire sur les ports D5 et D6.

------------------------------------------------------------------------------
--                                                                          --
--                                                                          --
--                                F A D E                                   --
--                                                                          --
--                                M a i n                                   --
--                                                                          --
--    Copyright (C) 2017 Bardot Sébastien                                   --
--    More information on http://lvcetada.e-monsite.com/ or by mail on      --
--    lvcetada@gmail.com                                                    --
--                                                                          --
--    This program is free software: you can redistribute it and/or modify  --
--    it under the terms of the GNU General Public License as published by  --
--    the Free Software Foundation, either version 3 of the License, or     --
--    (at your option) any later version.                                   --
--                                                                          --
--    This program is distributed in the hope that it will be useful,       --
--    but WITHOUT ANY WARRANTY; without even the implied warranty of        --
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         --
--    GNU General Public License for more details.                          --
--                                                                          --
--    You should have received a copy of the GNU General Public License     --
--    along with this program.  If not, see <http://www.gnu.org/licenses/>. --
--                                                                          --
--                                                                          --
--    This package and its children are based on AVR-Ada Library.           --
--                                                                          --
--                                                                          --
------------------------------------------------------------------------------

with AVR;
with AVR.MCU;
with Interfaces;
with AVR.Real_Time.Delays;

use AVR;
use AVR.MCU;
use Interfaces;

procedure Fade is
   Sens : Boolean;
   pwmValue : Interfaces.Unsigned_16;
begin

   MCU.DDRB_Bits (1) := DD_Output;
   MCU.DDRB_Bits (2) := DD_Output;

   TCCR1A_Bits := (COM1A1_Bit => True,
                   COM1A0_Bit => False,
                   COM1B1_Bit => True,
                   COM1B0_Bit => False,
                   WGM10_Bit  => True,
                   WGM11_Bit  => False,
                   others => False);
   TCCR1B_Bits := (WGM12_Bit => True,
                   WGM13_Bit => False,
                   CS10_Bit => False,
                   CS11_Bit => False,
                   CS12_Bit => True,
                   others => False);
   pwmValue := 16#00#;
   MCU.OCR1A := pwmValue;
   MCU.OCR1B := pwmValue;

   loop
      if(pwmValue = 16#FF#)then
         Sens := False;
      elsif(pwmValue = 16#00#) then
         Sens := True;
         -- end if;
      end if;
      if (Sens) then
         pwmValue := pwmValue + 16#01#;
      else
         pwmValue := pwmValue - 16#01#;
      end if;
      MCU.OCR1A := pwmValue;
      MCU.OCR1B := pwmValue;
      delay 0.01;
   end loop;
end Fade;

Les fichiers de ce programme peuvent être téléchargés ici.

Un programme analogue peut être fait avec les ports D3, D9, D10 et D11 en remplaçant les registres du timer 0 par ceux du timer 1 ou du timer 2 suivant les ports que nous souhaitons contrôler. La gestion de l’ensemble de ces ports peut se faire avec la fonction « AnalogWrite » de la librairie GPIO. Voici le programme avec la librairie GPIO mise à jour.

------------------------------------------------------------------------------
--                                                                          --
--                                                                          --
--                                F A D E                                   --
--                                                                          --
--                                M a i n                                   --
--                                                                          --
--    Copyright (C) 2017 Bardot Sébastien                                   --
--    More information on http://lvcetada.e-monsite.com/ or by mail on      --
--    lvcetada@gmail.com                                                    --
--                                                                          --
--    This program is free software: you can redistribute it and/or modify  --
--    it under the terms of the GNU General Public License as published by  --
--    the Free Software Foundation, either version 3 of the License, or     --
--    (at your option) any later version.                                   --
--                                                                          --
--    This program is distributed in the hope that it will be useful,       --
--    but WITHOUT ANY WARRANTY; without even the implied warranty of        --
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         --
--    GNU General Public License for more details.                          --
--                                                                          --
--    You should have received a copy of the GNU General Public License     --
--    along with this program.  If not, see <http://www.gnu.org/licenses/>. --
--                                                                          --
--                                                                          --
--    This package and its children are based on AVR-Ada Library.           --
--                                                                          --
--                                                                          --
------------------------------------------------------------------------------

with AVR;
with Interfaces;
with GPIO;
with AVR.Real_Time.Delays;

use AVR;
use Interfaces;
use GPIO;


procedure Fade is
   Sens : Boolean;
   pwmValue : Interfaces.Unsigned_16 := 16#00#;
begin
   PinMode(D9, AnalogOutput);
   PinMode(D10, AnalogOutput);
   pwmValue := 16#00#;
   AnalogWrite(D9, pwmValue);
   AnalogWrite(D10, pwmValue);
   loop
      if(pwmValue = 16#FF#)then
         Sens := False;
      elsif(pwmValue = 16#00#) then
         Sens := True;
         -- end if;
      end if;
      if (Sens) then
         pwmValue := pwmValue + 16#01#;
      else
         pwmValue := pwmValue - 16#01#;
      end if;
      AnalogWrite(D9, pwmValue);
      AnalogWrite(D10, pwmValue);
      delay 0.01;
   end loop;
end Fade;

Les fichiers de ce programme peuvent être téléchargés ici.

La fonction « AnalogWrite » prend comme paramètres le port de sortie et un nombre entre 0 et 255. Elle fonctionne différemment selon les broches, ainsi :
- pour les ports D3, D5, D6, D9, D10 et D11 : elle écrit sur le port une valeur entre 0 et 255, 0 correspond à 0 Volt et 255 correspond à 5Volts.
- pour les autres ports, si la valeur est strictement inférieure à 128, un niveau bas est écrit sur le port, si elle est supérieure, ça écrit un niveau haut.

Attention, le programme aura un fonctionnement bizarre avec les ports D5 et D6. En effet, le Timer 0 est celui utilisé par la fonction delay. Si vous voulez voir le phénomène, vous avez deux solutions:
- mettre un delay de 1.0 et vous pouvez voir le changement d'état de la LED.
- utiliser le watchdog et les interruptions, je traiterai cela un peu plus tard.

 

Un peu plus

Le timer1 permet de générer des pwm de 8 bits (comme ceux utilisés dans la procédure AnalogWrite), mais aussi des pwm de 9 et 10 bits qui permettent donc de découper la tension 5V en respectivement 512 et 1024, ce qui donne une résolution qui est respectivement 2 et 4 fois plus fine que la fonction AnalogWrite. Voici un exemple d'utilisation :

------------------------------------------------------------------------------
--                                                                          --
--                                                                          --
--                                F A D E                                   --
--                                                                          --
--                                M a i n                                   --
--                                                                          --
--    Copyright (C) 2017 Bardot Sébastien                                   --
--    More information on http://lvcetada.e-monsite.com/ or by mail on      --
--    lvcetada@gmail.com                                                    --
--                                                                          --
--    This program is free software: you can redistribute it and/or modify  --
--    it under the terms of the GNU General Public License as published by  --
--    the Free Software Foundation, either version 3 of the License, or     --
--    (at your option) any later version.                                   --
--                                                                          --
--    This program is distributed in the hope that it will be useful,       --
--    but WITHOUT ANY WARRANTY; without even the implied warranty of        --
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         --
--    GNU General Public License for more details.                          --
--                                                                          --
--    You should have received a copy of the GNU General Public License     --
--    along with this program.  If not, see <http://www.gnu.org/licenses/>. --
--                                                                          --
--                                                                          --
--    This package and its children are based on AVR-Ada Library.           --
--                                                                          --
--                                                                          --
------------------------------------------------------------------------------

with AVR;
with Interfaces;
with GPIO;
with AVR.Real_Time.Delays;
with AVR.MCU;

use AVR;
use Interfaces;
use GPIO;


procedure Fade is
   Sens : Boolean;
   pwmValue : Interfaces.Unsigned_16 := 16#00#;
begin
   PinMode(D9, AnalogOutput);
   PinMode(D10, AnalogOutput);
   MCU.TCCR1A_Bits(MCU.WGM10_Bit) := False;
   MCU.TCCR1A_Bits(MCU.WGM11_Bit) := True;
   pwmValue := 16#00#;
   AnalogWrite(D9, pwmValue);
   AnalogWrite(D10, pwmValue);
   loop
      if(pwmValue = 16#1FF#)then
         Sens := False;
      elsif(pwmValue = 16#00#) then
         Sens := True;
         -- end if;
      end if;
      if (Sens) then
         pwmValue := pwmValue + 16#01#;
      else
         pwmValue := pwmValue - 16#01#;
      end if;
      AnalogWrite(D9, pwmValue);
      AnalogWrite(D10, pwmValue);
      delay 0.01;
   end loop;
end Fade;

 

Les fichiers de ce programme peuvent être téléchargés ici. Pour passer en 1024, il suffit de remplacer

   MCU.TCCR1A_Bits(MCU.WGM10_Bit) := False;
   

par

   MCU.TCCR1A_Bits(MCU.WGM10_Bit) := True;
   

et

if(pwmValue = 16#1FF#)then

par

if(pwmValue = 16#3FF#)then

Le lien github du projet est ici.

Ajouter un commentaire

Anti-spam