<RESOLU> Allumage/extinction progressif lumière sur lévitation.

Bonjour tout le monde, je viens vers vous pour un truc super simple mais que j'arrive pas à faire...

je vous explique en deux mot. J'aimerai allumer une led de façon progressive, qu'elle reste allumer et quand je l'éteint elle s'éteint de façon progressive. J'utilise des leds haute puissance que je commande à l'aide d'un transistor sur une sortie PWM.

J'ai joué avec "fade" mais celles-ci tourne en boucle, j'imagine donc qu'il faut utiliser l'incrémentation. J'ai pas mal fouillé et je n'ai pas trouvé de bout de code satisfaisant.

Si vous aviez une piste ou la solution je vous serais très reconnaissant.

merci à vous!

Bonjour,
Tu as la solution, fait varier la valeur de ton PWM.
De 0 à 255 pour un allumage progressif
De 255 à 0 pour une extinction progressive
Ne pas oublier la petite tempo entre chaque valeur de ton PWM
@+

bonjour icare, merci pour ta réponse.

C'est bien ce que je pensai utiliser mais je ne sais pas la faire varier dans le temps sans que ça ne fasse pas de boucle (comme le fade).
J'ai au début utilisé un delay, du coup la boucle recommence sans cesse, ce qui est logique. Je me doute que c'est donc une histoire d'incrémentation mais c'est quelque chose que je n'ai pas encore utilsé.

Je veux juste que quand j'appuie sur mon inter la lumière s'allume progressivement et reste allumer jusqu'à que l'info bouton devienne fausse, entrainant l'extinction de ma led de façon progressive.

Re,
Où est ton problème.
Une piste :
Dans ta boucle principale

Si
Appuie sur un BP
alors Va vers une fonction allumage/extinction

Dans ta fonction allumage/extinction

Si allumer 
alors 
tu décrémentes ton PWM
si non 
tu incrémentes ton PWM
mise à jour flag allumer/éteind

Si tu utilises un inter tu devras gérer le changement d'état de l'entrée et n'oublie pas les phénomènes de rebonds des BP ou inter

@+

bonjour
ça ça tourne avec un inter (etat 0 ou 1 maintenu)

const int buttonPin = 2;     
const int ledPin =  5;      
int buttonState = 0;         
byte epwm=0;
byte i=0;
void setup() {
  pinMode(ledPin, OUTPUT);      
  pinMode(buttonPin, INPUT);     
}
void loop(){
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {     
    if (epwm< 255) epwm++; 
  } 
  else {
    if (epwm>0) epwm--; 
  }
  analogWrite(ledPin, epwm);
  delay(15); 
}

merci icare et Artouste.

J'ai testé et ça marche pas mal.

Mais un nouveau soucis apparait... En fait il y a une autre partie dans mon code.

Mon interrupteur est en fait un capteur à effet hall qui gère un aimant en lévitation, j'ai en gros deux boucle.

Quand j'approche mon aimant, la bobine se déclenche et gère la lévitation. J'ai voulu rajouter une lumière, donc j'ai aussi intégrer la gestion dans ma boucle. j'ai donc une boucle if et else pour chaque fonction.

quand je demande juste d'allumer ou éteindre ma lumière il n'y a pas de soucis. Mais dès qu'un delay est rajouté celui-ci viens mettre son grain de sel et perturbe ma boucle, l'aimant ne tiens plus.

J'ai besoin d'une grande vitesse d'exécution pour gérer l'aimant. L'électroaimant s'allume quand l'aimant est trop loin et s'éteint quand celui-ci est trop prêt, ce qui le fait tenir...

Je me dis que je vais peut être juste mettre un condensateur dans mon montage pour gérer l'extinction progressive et laisser arduino gérer que la lévitation.

je vais nettoyer et vous poster mon code.

merci à vous

elastickman:
quand je demande juste d'allumer ou éteindre ma lumière il n'y a pas de soucis. Mais dès qu'un delay est rajouté celui-ci viens mettre son grain de sel et perturbe ma boucle, l'aimant ne tiens plus.

remplace le delay par un calcul de difference sur millis()

voici mon code.

Artouste, je vais regarder cette histoire de mills(), le temps est ma plus grosse lacune sur arduino, je vais tenter de rattraper ça.

// these constants won't change:
const int bobine = 13;      // commande de la bobine
const int ledPin = 9; 

const int knockSensor = A0; // capteur à effet hall
const int threshold =802;  // threshold correspond à une valeur choisi dans la lecture du capteur à effet hall, ça correspond à la position choisit.
const int threshold2 = 1020;// permet une plage de distance pour mon aimant, entre 802 et 1020, je gagne en stabilité.

const int threshold3 = 600; // seuil de déclenchement de la lumière.









// these variables will change:
int sensorReading = 0;      // Pin analogique 0 pour l'entrée du capteur


void setup() {
 pinMode(bobine, OUTPUT); // declare la bobine comme sortie
  pinMode(ledPin, OUTPUT); 
 
}

void loop() {
  
  // read the sensor and store it in the variable sensorReading:

   
  sensorReading = analogRead(knockSensor); // lit la valeur du capteur à effet hall 
  
  
    
  if (sensorReading > threshold && sensorReading < threshold2 ) // si la valeur lue se situe entre les deux threshold 
 
  {
   
  digitalWrite (bobine, HIGH); //allumage de la bobine pour attirer l'aimant


  }
    
    else  //Sinon éteindre la bobine pour faire redescendre l'aimant
	{
		digitalWrite (bobine, LOW); //éteint la bobine
             
	}


  
  if (sensorReading > threshold3 ) //si la valeur lu est plus grande que threshold3
  
  {
    

   digitalWrite (ledPin,HIGH); // allumage de la lumière
    }

  
  
    
 
    

  
else 
 {
    digitalWrite (ledPin,LOW); // si l'aimant disparait, extinction de la lumière
    }

  
 
	  }

Re,
La lévitation magnétique n'est possible qu'avec un régulateur PID.
Sans ce type de régulation (avec les bons paramètres pour le proportionnel, l'intégral et le différentiel) impossible de le faire
@+

elastickman:
voici mon code.

Artouste, je vais regarder cette histoire de mills(), le temps est ma plus grosse lacune sur arduino, je vais tenter de rattraper ça.

le meme que le precedent avec utilisation de millis
à toi de voir ce que ça donne et comment l'integrer dans ton code

const int buttonPin = 2;     
const int ledPin =  5;      
int buttonState = 0;         
byte epwm=0;

unsigned long smil; // save pour calcul millis
byte de=20; // variable pour delay non bloquant
void setup() {
  pinMode(ledPin, OUTPUT);      
  pinMode(buttonPin, INPUT);     
}
void loop(){
  if (millis()-smil >de) {
  buttonState = digitalRead(buttonPin);
  
  if (buttonState == HIGH) {     
    if (epwm< 255) epwm++; 
  } 
  else {
    if (epwm>0) epwm--; 
  }
  analogWrite(ledPin, epwm);
  smil=millis();
  }
  
}

Re,
Ne vous acharnez pas sans régulateur PID vous allez dans le mur contre l'aimant ou au sol :grin: :fearful:
C'est un cas typique ou le tout ou rien ne marche pas et je vous fait cadeau des nombreux paramètres à gérer.
Continue cette expérience tu vas apprendre énormément de choses
@+

Re,

elastickman:
Bonjour tout le monde, je viens vers vous pour un truc super simple mais que j'arrive pas à faire...

Mon œil XD
Il faut exposer le problème en entier cela permet aux colistiers de mieux cerner la réponse
@+

merci artouste, j'étais en train de me faire toute la documentation millis, une nouvelle porte s'ouvre à moi. (je vais tester ton code immédiatement).

qu'entend tu icare par PID? j'ai juste mis un transistor avec ma bobine, mon code marche très bien et j'ai déjà tenu plus de 24h en lévitation, mais c'est vrai qu'une régulation ferai moins "bourrin" Mais si tu as de quoi affiner le truc je suis preneur, au moins pour découvrir de nouvelle choses.

et voilà que ça marche enfin!

merci à vous deux

voici le code final, je vais changer le titre en résolu et en y mettant plus d'info.

const int ledPin =  9; // broche lumière
int sensorReading = 0; 

const int knockSensor = A0; // capteur à effet hall
const int threshold3 =702;  // threshold correspond à une valeur choisi dans la lecture du capteur à effet hall, ça correspond à la position choisit.       


const int bobine = 13;      // commande de la bobine
const int threshold =802;  // threshold correspond à une valeur choisi dans la lecture du capteur à effet hall, ça correspond à la position choisit.
const int threshold2 = 1020;// permet une plage de distance pour mon aimant, entre 802 et 1020, je gagne en stabilité.

unsigned long smil; // save pour calcul millis
byte de=15; // variable pour delay non bloquant
byte epwm=0; 

void setup() {
  pinMode(ledPin, OUTPUT);  
  pinMode(bobine, OUTPUT);
      
}
void loop(){
  
   sensorReading = analogRead(knockSensor); 
 
 
 if (sensorReading > threshold && sensorReading < threshold2 ) // si la valeur lue se situe entre les deux threshold 
 
  {
   
  digitalWrite (bobine, HIGH); //allumage de la bobine pour attirer l'aimant


  }
    
    else  //Sinon éteindre la bobine pour faire redescendre l'aimant
	{
		digitalWrite (bobine, LOW); //éteint la bobine
             
	}

  
     if (millis()-smil >de){        
       
    
     if (sensorReading > threshold3 )   // // allumage/extinction progressive de la lumière en fonction de la présence ou nom de l'aimant
 {     
    if (epwm< 255) epwm++; 
  } 
  else {
    if (epwm>0) epwm--; 
  }
  analogWrite(ledPin, epwm);
    smil=millis();
}

}

icare si tu peux argumenter sur le PID je suis preneur.

elastickman:
et voilà que ça marche enfin!

merci à vous deux

Tant mieux
ce qui serait sympa ce serait de mettre une petite video du dispositif
Comme evoqué par Icare, ça doit plutot pas mal vibrer autour du point d'equilibre

Re,
Tu peux consulter les liens suivants :
http://forum.arduino.cc/index.php?topic=89241.0
ou

ou

mais il en existe d'autres
Si tu veux en savoir plus sur les PID, regarde la documentation asservissement sur net
@+

je vous en mettrai une de vidéo, j'ai rien pour filmer pour l'instant.

Le point d'équilibre je l'ajuste à taton avec le threshold de mon code, là je suis vraiment pas mal, et le fait d'avoir une plage (exemple de 802 à 102 pour la valeur) stabilise aussi pas mal.

Ensuite j'augmente la stabilité en fonction de la forme de l'objet qui l'évite en dessous, ça joue aussi beaucoup. (centre de gravité, frottement avec l'air...)

elastickman:
Le point d'équilibre je l'ajuste à taton avec le threshold de mon code, là je suis vraiment pas mal, et le fait d'avoir une plage (exemple de 802 à 102 pour la valeur) stabilise aussi pas mal.

Ensuite j'augmente la stabilité en fonction de la forme de l'objet qui l'évite en dessous, ça joue aussi beaucoup. (centre de gravité, frottement avec l'air...)

OK
perso par curiosité et pour test, je mettrais un/des potentiometre sur un/des autre AD pour jouer entre bornes sur la/les valeurs de treshold :grin:

Mais bon j'arrete , sinon dans une heure ça va devenir une usine à gaz 8)

icare, c'est les liens qui m'ont permit de mettre tout ça "au point".

J'ai commencé à regarder PID, je vais creuser la question, ça semble assez intéressant.

pour le coup des potentiomètres c'est une bonne idée. Je voulais dans un premier temps faire varier le threshold dans le temps mais de façon programmer, le faire onduler. Mais j'ai maintenant une bonne piste grace au millis() ;).