[conseil] faire varier la tension en sortie d'une carte arduino

Bonjour, je fait ce sujet à part pour que peut être il soit facile d’accès pour les personne se posant la même question que moi..

Ma question est la suivante :

Est-ce possible de faire varier la tension sur une sortie d'une carte arduino ?

Exemple :

mon projet est un detecteur d'obstacle, et j'aimerai (pourquoi pas hein :p) faire varier l'intensité de la LED que j'utilise en fonction de la valeur envoyé par mon sonar. sur la carte on a en sortie 5V donc voila j'aimerai faire des clignotement de LED avec un intensité qui fluctue

Merci

Cordialement

Benoit

Salut,

Pour cela tu as des sorties spéciales sur l'arduino, ce sont les sorties PWM (Pulse Width Modulation)
Ce sont des sorties numériques 0-5V. En faisant varier la fréquence d'impulsion (passage rapidement de 5 à 5V) elles simulent une tension variable entre 0 et 5V (analogique).

Elles peuvent donc être utilisées soit en sortie numérique état 0V ou 5V en utilisant la fonction digitalWrite().
Soit être utilisées en sortie analogique générant une tension variable de 0 à 5V en utilisant la fonction analogWrite().

Merci à vous deux, j'ai fait un test avec la fonction analogWrite() et ça fonctionne.

En fait j’étais tombé sur une explication de cette fonction mais il parlait en fonction des largeurs d'impulsion du signal donc ça modifier le temps où la LED est allumé et le temps où la LED est éteinte.

Encore merci :slight_smile:

Benoit

Petite et derniere question ^^

voici un programme simple qui fait varier l'intensité de la LED :

int ledPin = 11;      // LED connected to digital pin 9
int analogPin = 3;   // potentiometer connected to analog pin 3
int val = 0;         // variable to store the read value

void setup()
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}

void loop()
{
  val = analogRead(analogPin);   // read the input pin

  analogWrite(ledPin, val / 3 );  // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
  
}

Plus la valeur de val est grande, plus la LED elcair fort. Ce qui m'interresse c'est l'inverse. Or un truc me bloque :frowning:
"analogWrite(ledPin, val / 3 ); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255"
c'est assez clair, plus la valeur est elevée, plus la led eclair. je ne vois pas comment inverser cela. j'ai essayé quelques petite modif mais sans succes, avez vous une idée?

Merci :slight_smile:

"il parlait en fonction des largeurs d'impulsion du signal"

C'est justement cela : PWM = Pulse Width Modulation = Modulation de Largeur d'Impulsion
C'est cette astuc qui permet de simuler un signal analogique sur une sortie numériuque

Concernant ta dernière question je ne comprend pas bien : tu veux que plus ta val envoyée à la fonction analogWrite() est petite plus la LED éclaire ?

essaie la fonction map() qui te permet de modifier tes plages de valeurs

Benoit1121:
Plus la valeur de val est grande, plus la LED elcair fort. Ce qui m'interresse c'est l'inverse. Or un truc me bloque :frowning:
"analogWrite(ledPin, val / 3 ); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255"
c'est assez clair, plus la valeur est elevée, plus la led eclair. je ne vois pas comment inverser cela. j'ai essayé quelques petite modif mais sans succes, avez vous une idée?

Merci :slight_smile:

Essaie un truc du genre:

analogWrite(ledPin, 255 - (1023/val))

Attention ça va planter si val==0.
un truc satisfaisant pour toi serait:

analogWrite(ledPin, 255 - (1024/(val+1)))

Par contre je ne sais pas comment se comporte analogWrite() avec des arguments négatifs, ce qui peut se produire avec le code ci-dessus.
Si ça pose problème, tu peux stocker 255 - (1024/(val+1)) dans une variable et par un if() t'assurer que sa valeur mini ne descend pas au-dessous de 0.

cela devrait fonctionner et être plus simple avec map() :

Ta valeur reçue est comprise entre 0 et 1023 -> tu la convertis en valeur entre 255 et 0 :

val = analogRead(analogPin);
val = map(val, 0, 1023, 255, 0);
analogWrite(ledPin, val);

Merci à vous deux, je suis en train d'essayer vos astuces.

@smarty : Oui c'est ca que je désire ^^

analogWrite(ledPin, 255 - (1024/(val+1)))

Pourquoi pas tout simplement

analogWrite(ledPin,  255 - val/4)

fdufnews:

analogWrite(ledPin, 255 - (1024/(val+1)))

Pourquoi pas tout simplement

analogWrite(ledPin,  255 - val/4)

Très juste, et en ce qui me concerne très faux =(
(ça fait une belle hyperbole qui en plus n'est pas dans le bon sens, shame on me).

Bon et bien, ca ne résoud pas le soucis que j'ai ^^
je n'arrive pas à avoir l'intensité de la LED qui augmente quand ''val" diminue ^^

j'ai essayé toute vos astuces :frowning:

Benoit

je n'arrive pas à avoir l'intensité de la LED qui augmente quand ''val" diminue ^^

Comment ta LED est-elle câblée? vers la masse ou vers le plus 5V?

analogWrite(ledPin, 255 - val/4)
Si val diminue l'argument augmente et donc le rapport cyclique augmente
Si val augmente l'argument diminue et donc le rapport cyclique diminue
Cette ligne de code est bonne si la LED est câblée entre une sortie PWM et la masse
Si la LED est câblée entre une sortie PWM et le +5V il faut utiliser analogWrite(ledPin, val/4)

hello,

étrange...

dans la solution avec map() tu as bien :

  • quand tu lis une valeur de 0 sur ton capteur, val=255 donc ta led est plein feux
  • quand tu lis une valeur de 1023 sur ton capteur, val=0 donc ta led éteinte

donc à priori c'est valide.

vérifie effectivement ton montage.
on est bien d'accord que tu as connecté ton capteur sur une entrée analogique (pin A0 -> A5 sur une Uno) ?
ta sorte est bien sur une sorte PWM (marquée ~ sur la plaquette) ?

que dit le capteur ? est-ce que tu sais quelles valeurs il renvoie ? (utilise la liaison série pour afficher la valeur sur ton ordi)

Je possede une carte duemilanove.
La LED est branchée de cette facons : sortie 11 de ma carte sur le + de la LED et la masse à la masse.

et oui mon sonar est branché sur l'entree analogique 3 de ma carte.

mon capteur me donne comme valeurs : 100 pour 1m 200 pour 2m (a 003 pres..) Donc avec le programme basic que j'ai mis plus haut, plus la valeur est grande plus la LED eclair.

j'ai essayé vos exemple et soit la LED reste allumé non stop fortement ou alors pas du tout ..

(il est possible que ce soit une erreur de ma part)

Ce code devrait fonctionner

int ledPin = 11;      // LED connected to digital pin 9
int analogPin = 3;   // potentiometer connected to analog pin 3
int val = 0;         // variable to store the read value

void setup()
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}

void loop()
{
  val = analogRead(analogPin);   // read the input pin

  analogWrite(ledPin, 255-(val / 4) );  // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
  
}

Voilà je pense avoir trouvé , mais je trouve que ma LED eclaire trop, meme quand elle est censé etre a bas regime ^^^Donc je suis pas sûr de moi a 100% mais 90%.

int ledPin = 11;      // LED connected to digital pin 9
int analogPin = 3;   // potentiometer connected to analog pin 3
int val = 0;         // variable to store the read value


void setup()
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
  Serial.begin(9600) ;
}

void loop()
{
   Serial.println(val);
  val = analogRead(analogPin);   // read the input pin

 
 analogWrite(ledPin,  255 - val * 3) ;
 
  
}

je * 3 mais on pourrait par 2 aussi.

Benoit

Que donnent les valeurs de val à la capture ? et à l'envoi ?
Peut être un manque de sensibilté et précision sur les mesures, ou une intensité trop faible sur la LED (changer de résistance ?)

utilise le port série pour débugger :

insère le code dans ta fonction setup()

Serial.begin(9600);

puis dans ton loop()

val = analogRead(analogPin);   // read the input pin
Serial.println(val);
val = map(val, 0, 1023, 255, 0);
analogWrite(ledPin, val);

si la lecture du capteur est ok, faire la lecture de val une fois la valeur traitée :

val = analogRead(analogPin);
val = map(val, 0, 1023, 255, 0);
Serial.println(val);
analogWrite(ledPin, val);

Il faudrait être clair sur la gamme de valeurs que tu récupères par AnalogRead().
Manifestement tu ne reçois pas une valeur comprise entre 0 et 1023. Mais seulement une gamme plus faible.
Il faudrait faire afficher les valeurs reçues avec un Serial.print pour avoir une idée de la gamme couverte pour adapter correctement l'argument d'analogWrite()