Outils pour utilisateurs


Une lampe de poche ultime

Présentation :

Je voudrais une lampe sur accus dont je puise

  • varier la luminosité
  • savoir le niveau de l' accus

Pré-requis :

Matériel:

  • une led de puissance 12v ( parce que j'en est une et parce que l' on peut la remplace par une ampoule de voiture ou un allogène à encastré)
  • un accus 14.4v (type accus de visseuse, pour les mêmes raisons j' en ai et on peut remplace par une prise allume-cigare 13.8v)
  • un transistor de puissance ( pour faire le pont entre l' arduino et les ~12v de la lampe )j' ai un 2SD1985A
  • un bouton poussoir ( pour sélectionner le mode de fonctionnement )

Logiciel:

  • Aucun

Etat d'avancement du projet :

[1 %]

Luminosité

Premier jet

Pour gérer la luminosité, j' ai penser utiliser un signal carré a fréquence fixe doont la durée des temps haut varie en fonction de l' éclairage demandé . la durée : t devra être le plus court possible pour éviter des clignotements. (l' utilisation de la lib.servo ne marche pas, elle clignote) Pour le code j' ai démarré avec l' exemple BlinkWithoutDelay Au quel j' ai ajouter un variable time qui (de 5 états, de 0 à 4 )qui multiplié a inter(variable de temps) nous donne interval. Ensuite en faisant un lecture du bouton ( digitalRead(buttonPin) avec une petite gestion du temps pour faire un filtre passe-bas ) je fais varier time de 0 à 4 en boucle .

lampe1_1.pde
const int ledPin =  13;      
const int buttonPin = 2;
 
 
int ledState = LOW;             
long previousMillis = 0;        
int time=4;
 
long inter = 1;           
long interval = 1;
long interrupt = 1;
 
void setup() {
 
  pinMode(ledPin, OUTPUT);      
}
 
void loop()
{
 
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    if (ledState == LOW){
      if(time!=0){
        ledState = HIGH;
        interval= inter*(0+time);
      }
    }
    else{
      if (time!=4){
        ledState = LOW;
        interval= inter*(4-time);
      }
    }
 
    digitalWrite(ledPin, ledState);
  }
  if (digitalRead(buttonPin)==HIGH){
    if (interrupt<=millis()){
    time=time+1;
      if (time==5){
        time=0;
      } 
      interrupt=millis()+400;
    }
  }
}

L'extension Adobe Flash est nécessaire pour afficher ce contenu.

Evolution

Je me suis rendu compte qu'il y avais un léger clignotement alors j' ai remplacé millis() par micros() , adapté le temps, et je suis passé de 5 états de 1 en 1 à 100 états de 10 en 10 ce qui rend plus propre. Pour finir j' ai modifié le système de saisie du bouton poussoir pour y loger un mode 0 ou 1 par une longe pression ( pour l' instant 0=éclairage continu et 1=éclairage clignotant ) par la suite l' éclairage clignotant deviendra continu avec sonde extérieur de luminosité . si l' adaptation est facile un 3eme mode sera pour la lecture du niveau de l' accus

lampe1_3.pde
const int ledPin =  13;      
const int buttonPin = 2;
 
 
int ledState = LOW;             
long previousMillis = 0;        
int time=0;
int mode=0;
int mod=0;
long inter = 100;           
long interval = 100;
long interrupt = 100;
long interrupte = 100;
 
void setup() {
 
  pinMode(ledPin, OUTPUT);      
}
 
void loop()
{
 
  unsigned long currentMillis = micros();
 
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    if (ledState == LOW){
      if(time!=0){
        ledState = HIGH;
        interval= inter*(0+time);
      }
    }
    else{
      if (time!=100){
        ledState = LOW;
        interval= inter*(100-time);
      }
    }
 
    digitalWrite(ledPin, ledState);
  }
  if (digitalRead(buttonPin)==HIGH){
    if (mode == 0){
      mode = 1;
      interrupt=micros();
    }
    interrupte=micros();
  }
  if (digitalRead(buttonPin)==LOW){
    if(mode==1){
      mode=0;
      if ((interrupte-interrupt)>300000){
        if (mod==1){
          mod=0;
        }
        else {
          mod=1;
        }
      }
      else {
        if ((interrupte-interrupt)>20000){
          time=time+10;
          if (time==110){
            time=0;
          }
        }
      }
    }
  }
  if (mod==1){
    inter=10000;
  }
  else {
    inter=100;}
}

L'extension Adobe Flash est nécessaire pour afficher ce contenu.

Niveau de batterie

Pour savoir le niveau de batterie, ce qui nos intéresse c'est la tension de 9.5v niveau bas a 14.4v niveau haut. Pour ce faire j' utilise trois résistances identiques ,de grande valeur, en série ( pont diviseur ). La tension est repartie de façon égale, 1/3 de V.total a chaque résistance . Ce qui fait que la tension au borne de la résistance coté masse varie de 4.8v à 3.17v. Raccordé a une entrée analogique du arduino,
batValue = analogRead ( batPin ); ça nous donne 982 à 648 sur 1023.
batValue = map ( batValue, 648, 982, 0, 5); a vérifier
Mais batValue devrais ce trouver entre 0 et 5 il ne reste plus qu'a faire “batValue ” clignotement .

Nouveau point de vue

Je suis passé à la version 2.x car j' avais du mal à intégré la lecture du niveau de batterie .
La grande nouveauté, tout est basé sur un menu à un bouton (le précédent était sur le clignotement d' un led).
La seconde est l' utilisation du mode PWM du arduino.( analogWrite ) Entre-autre cette nouvelle façon de voir permet de garder et/ou de changer l' intensité dans les autre mode .

//menu

Une grande pression entre et sort du menu, les pressions dans les 4 premières secondes choisissent le mode et les suivantes le modifient. Dans cette évolution une pression courte reste disponible en dehors du menu pour une autre utilisation .

PWM

//led

il ni a pas grand choses a dire, tout est .
Au départ, je pensais que ce mode était pour l' utilisation de la lib.servo. Mais sur les sorties PWM a une fréquence de ~500Hz sur une échelle de 0 à 255 on fait varier le signal . Le premier mode sert a modifier cette valeur pour regler l' intensité de la lampe.

Photo-capteur

//led la partie (if(photoCompt==1))

Il reste encore a l'étalonner correctement, mais avec comme base l' intensité choisi dans le premier mode, ce mode baisse l' intensité en fonction de l' éclairage devant la lampe. Ce qui sauve de la batterie, empêche l' éblouissement , et l'on peut facilement imaginer qu'a l'intérieur, grâce a ce procédé l'intensité de l'éclairage va s' adapter pour être constant (a quelques centimètres d'un mur, il reflète, l' intensité baisse, on tourne la tête vers un grand salon, plus de réflexion, elle revient a son maximum).

Niveau de Batterie

//led la partie (if(batCompt==1))

Après lecture du niveau de la batterie. Celui-ci est transmis par des variations d' intensité (clignotements), Le nombre indique le niveau. Une fois indiqué le mode niveau de batterie est quitté .

Remarque :

Il est a noter que le menu a un bouton peut être adapté pour d' autre application de même que ce code peut être utilisé pour commander d' autre périphérique comme un moteur, ainsi (a la place de la photo-résistance) en mesurant la chute de tension quand il et en difficulté celui-ci pourrais accélérer tout seul.

Code final

lampe2_1.pde
//Zebulon55 -*- Lampe -*-
const int boutonPin = 2;
const int photoPin = A0;
const int ledPin = 9;
const int batPin = A1;
long timeMenu = 0;
long timeLed = 0;
unsigned long timeRef[]={0,0};
unsigned long timeSet[]={1000, 100};
unsigned int powerSet[]={5, 50, 100, 255};
int boutonCompt = 0;
int pressLong = 0;
int pressCourt = 0;
int menuCompt = 0;
int menuMode = 0;
int powerCompt = 0;
int photoCompt = 0;
int photoValue = 0;
int batCompt = 0;
int batValue = 0;
int batI = 0;
int ledValue = 5;
 
 
 
 
void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(boutonPin, INPUT);
// Serial.begin(9600);
 
}
 
void loop(){
 
  //saisie bouton
  if (digitalRead (boutonPin)==HIGH){ //si bouton est appuyer
    if (boutonCompt==0){ //si le compteur est a zero
      timeRef[boutonCompt]=millis(); //noter l' heure de depart de pression bouton
      pressCourt=0;
      boutonCompt=1; // mettre le compteur a 1
    }
    timeRef[boutonCompt]=millis(); // noter l' heure temps que bouton est appuyer
  }//fin de la saisie bouton
 
  //detection de longue et courte pression
  if(digitalRead (boutonPin)==LOW){ // si le bouton n' est pas appuyer
    if (boutonCompt==1){//si le compteur est a 1
      if (( timeRef[1]-timeRef[0])>timeSet[0]){ //si pression supperieur a timeset0
        if (pressLong==0){
          pressLong=1;
         // Serial.print("pressLong ");
       //   Serial.println(pressLong);  
          menuCompt=0;
          menuMode=0;
          pressCourt=0;
        }
        else {
          pressLong=0;
         // Serial.print("pressLong ");
          //Serial.println(pressLong); 
        }
      }//fin pression longue
      else {
        if (( timeRef[1]-timeRef[0])>timeSet[1]){ //si pression supperieur a timeset1
          pressCourt=1;//note pression courte
        //  Serial.print("pressCourt ");
      //    Serial.println(pressCourt);  
        }//fin pression courte
      }
      boutonCompt=0; // mettre le compteur a 0
    }//fin de compteur a 1
  }//fin de detection de longue et courte pression
 
  //menu
  if(pressLong==1){//si,entrer dans le menu
    //Serial.println('\n');
    if(menuCompt==0){//si c'est le debut 
      timeMenu=millis(); //noter l' heure de debut
      menuCompt=1;
    }//fin de debut
 
    if((millis()-timeMenu)<4000){//durant 4 sec.
      Serial.print("<4000 ");
      if(pressCourt==1){
        menuMode = menuMode+1;//menuMode +1 de 0à2
        pressCourt=0;
        if(menuMode==3){menuMode=0;}
      }
    }//fin des 4 sec.
    if((millis()-timeMenu)>4000){//apres 4 sec.
      //Serial.print("Mode");
      if(menuMode==0){ //menu puissance
        //Serial.print("Puissance");
        if (pressCourt==1){
          powerCompt = powerCompt+1;
          if (powerCompt==5){
            powerCompt=0;
          }
          pressCourt=0;
        }
        ledValue=powerSet[powerCompt];
      }//fin puissance
      if(menuMode==1){ //menu photoresistance on/off
        Serial.print("Photo");
        if (pressCourt==1){
          if (photoCompt==0){
            photoCompt=1;
          }
          else {
            photoCompt=0;
          }
          pressCourt=0;
          Serial.println(photoCompt); 
        }
      }//fin photoresistance
      if(menuMode==2){ //menu batterie
        Serial.print("Batterie");
        if( pressCourt==1){
          if (batCompt==0){
            batCompt=1;
          }
          else {
            batCompt=0;
          }
          pressCourt=0;
        }
      }//fin batterie
 
  }//fin apres 4 sec.  
  }//fin de menu
 
  //Led
  if (photoCompt==1){
    photoValue = map ( analogRead(photoPin),0 ,1023, powerSet[powerCompt], 0);
    //Serial.println(photoValue); 
    ledValue = photoValue;
    //Serial.println(ledValue);
  }
//  else{
//    ledValue = powerSet[powerCompt];
//  }
  if ( batCompt==1){
    batValue  = map(analogRead ( batPin ),0,1023,0,10);
    if (millis()-timeLed>500){
      if (ledValue==powerSet[powerCompt]){
        ledValue = 75 ;
      }
      else {
        ledValue=powerSet[powerCompt];
        ++batI;
        if ( batI>=batValue){
          batI = 0;
          batCompt = 0;
        }
      }
    timeLed = millis();
    }
  }
 
 
  analogWrite (ledPin,ledValue);
}// fin loop