Problème photoresistance et condition

Re-bonjour, le boulet est de retour :grin:

Après avoir un peu galéré, j’ai réussi à comprendre le système des LDR et à les utiliser.
Mais là j’ai un petit problème : Je souhaite allumer des leds selon la lumière :

Led verte quand il y a beaucoup de lumière
Led orange niveau moyen de lumière
led rouge : absence de lumière

Mon montage semble bon :

et voici mon code :

int ledv = 0; //led Verte pin 0
int ledr = 13; //led rouge pin 13
int ledo = 6; //led orange pin 6
float capteur = 0; //photoresistance sur pin A0
float tension = 0;
float ten = 0;

void setup()
{
  pinMode(ledv, OUTPUT);
  pinMode(ledo, OUTPUT);
  pinMode(ledr, OUTPUT);
 
 Serial.begin(9600);
}

void loop()
{
  ten = analogRead(capteur);
  tension = ten * 5 / 1024; //conversion en volts
  
 if(tension >= 0.45)
 {
   digitalWrite(ledv, LOW); //allume led verte
   digitalWrite(ledr, HIGH);
   digitalWrite(ledo, HIGH);
   Serial.println(tension); //affiche la tension
   delay(500);  
 }
  
  else if (tension < 0.50 && tension >= 0.20)
  
 {
   digitalWrite(ledo, LOW); //allume led orange
   digitalWrite(ledr, HIGH);
   digitalWrite(ledv, HIGH);
   Serial.println(tension);//affiche la tension
   delay(500);  
 }
 
 else
 {
   digitalWrite(ledr, LOW); //allume led rouge
   digitalWrite(ledo, HIGH);
   digitalWrite(ledv, HIGH);
   Serial.println(tension);//affiche la tension
   delay(500);  
 }
 delay(500);                                                                                                                                                                                                                                                         
}

Malheureusement, seule la led rouge s’allume quand il y a pas de lumière.
Les deux autres leds ne réagissent pas (je les ait testées, elles fonctionnent)
Par contre, le programme me renvoie bien la tension correspondante…

Quelqu’un voit-il le problème ?

Merci :slight_smile:

tu aurais pu continuer sur le même topic du début.
déjà pin 0 réservée, donc tu change ca.
pourquoi passer par une tension?
la PR renvoie de 0 à 1024
donc remplaces tes seuils :wink:
y a pas comme un blem?

 if(tension >= 0.45)
  else if (tension < 0.50 && tension >= 0.20)

dans l’exemple donné sur l’autre post, il se casse pas le fion :slight_smile:
http://www.codingcolor.com/microcontrollers/arduino-night-light-using-a-photocell/

int photocellPin = 0;// Photocell connected to analog pin 0
int photocellVal = 0; // define photocell variable


void setup() {
  Serial.begin(9600);
  pinMode(photocellPin, INPUT);
}
void loop() {
  photocellVal = analogRead(photocellPin);// read the analog from photocell
  Serial.println( photocellVal); // output to screen

  if (photocellVal < 100){
    Serial.println("lights on");// output to screen
   }                      
    else if (photocellVal > 100){
    Serial.println("light out");// output to screen
   }
  delay(30);

 }

donc tu peux faire
si valeur <100 => led X on
si valeur >1000=> led y on
sinon led z on

je t’avais pas dit aussi de mettre A0 pour la pin au lieu de 0 :wink:

Bonjour,

Il y a plusieurs choses bizarres dans le programme. Utiliser un float pour un numéro de broche par exemple.

Je ne ferais pas le câblage comme ça. La sortie 3,3V de l'Arduino ne sort que 50 mA il me semble. Connecter dessus des LED sans résistance fait un appel de courant qui, peut-être, effondre la tension au dessous du seuil des LED orange et verte (qui est plus élevé que celui de la LED rouge). Comme tu allumes la nouvelle LED avant d'éteindre les autres, c'est la double peine.

J'alimenterais les LED avec le 5V et une résistance > 330? en série.

Je pense qu'on ne va pas tarder à sentir le cramé. Là tu donnes l'impression de tester au pif jusqu'à que cela tombe en marche.

L'informatique quand c'est faux et bien c'est faux, pas grave on recommence. L'électronique quand c'est faux on a parfois de la chance de n'avoir rien cramé mais c'est rare, le plus souvent il faut ouvrir le porte-monnaie. Ce serait quand même bête d'être obligé de racheter une carte UNO a cause d'une simple Led à moins d'un € parce que que tu as confondu vitesse et précipitation !

Alors de la patience, de la réflexion, un peu d'initiation a l'électronique -> site OpenClassRoom rubrique Arduino ou le très bon tuto d'Eskimon. Ce ne sera pas du temps perdu loin de là.

infobarquee: je t'avais pas dit aussi de mettre A0 pour la pin au lieu de 0 ;)

Ah, je crois que j'ai mal compris, je doit faire ca ? :roll_eyes:

float capteur = A1;

Je passe sur les résistances absentes c'est déjà évoqué plus haut.

Là il y a comme un problème:

  ten = analogRead(capteur);
  tension = ten * 5 / 1024; //conversion en volts

ten et tension sont déclaré comme étant des float

analogRead retourne un entier Dans le calcul les constantes sont déclarées comme des entiers.

  ten = (float)analogRead(capteur);
  tension = ten * 5.0 / 1024.0; //conversion en volts

ou alors

int ten;
 ten = analogRead(capteur);
  tension = (float)ten * 5.0 / 1024.0; //conversion en volts

Maintenant convertir en tension c'est un peu se prendre la tête pour pas grand chose. Parce que manipuler des volts ou une l'information sans dimension comme celle retournée par analogRead c'est du pareil au même. Dans tous les cas il faut tâtonner pour trouver les seuils à utiliser

Je pense aussi que la valeur de la résistance est mal adaptée. Tu ne travailles qu'avec une toute petite portion de la dynamique du codeur. Seuleent un dixième de la dynamique. Il faudrait utiliser une résistance de valeur plus élevée.

Il y a recouvrement des 2 premiers seuils

jlbechennec:
Il y a plusieurs choses bizarres dans le programme. Utiliser un float pour un numéro de broche par exemple.

Ah, je crois que j’ai mal compris, je doit faire ca ? smiley-roll-blue
Code:float capteur = A1;

? ? ? ?
Un numero de pin est un ENTIER. Le compilateur de l’avr-gcc code les “integer” sur deux octets.
Il est absurde de coder un entier avec un float qui sert pour les nombres avec des chiffres après la virgule.
L’adage populaire “Qui peut le plus , peut le moins” n’est pas toujours vrai dans le domaine de la programmation.

Tout cela est expliqué là :
http://arduino.cc/en/Reference/HomePage
et aussi ici :
http://eskimon.fr/196-arduino-bienvenue-sur-le-tuto
ou là

Salut

Je me suis toujours posé une question au sujet des numéros de pin, dans tous les exemples, elles sont déclarées en int.

Comme un numéro de pin ne peut être négatif, on devrai la déclarer en unsigned int ? Je me suis dis que c'est pour éviter de taper du code car comme on n'a aucun numéro supérieur à la capacité d'un int, ça roule :)

Maintenant, un int est codé sur deux octets, donc pourquoi ne pas déclarer les numéros de pin en byte sur un octet ?

J'ai fais un test avec Arduino ERW qui me donne une estimation de la SRAM utilisée après la compilation. En compilant un programme vide avec juste une variable de déclarée j'obtiens ces résultats :

byte test = 5; donne SRAM 9 bytes int test = 5; donne SRAM 9 bytes

Arrivé là je me suis dis que le compilateur code un int sur deux octets uniquement si sa valeur est supérieur à 255 donc j'ai testé avec :

int test = 2000; ce qui donne SRAM 9 bytes ??

Soit je me plante et la SRAM n'est pas la mémoire utilisée par mes variables, soit un byte est codé aussi sur deux octets soit l'estimation est fausse soit je capte rien...

Le compilateur fait des optimisations, même dès fois sans te demander ton avis, d'autres t'expliqueront mieux que moi. Les "constantes" sont fortement optimisées par le compilateur et sont préférables à un "int". On peut utiliser aussi

define del 25

au lieu de : int del = 25;

Maintenant il existe des types de variable fortement typés (désolé pour la répétition) : int8_t -> 1 seul octet, entier signés uint8_t-> 1 seul octet, entier non signé et bien sûr on peut étendre : uint16_t, int32_t. De cette façon on est sur d'économiser au maximum la mémoire qui n'est pas à disponible à volonté sur un micro-controleur.

Question au pros de la compilation : Avec un micro 8 bits un type "int8_t" ou un type "const" ou un #define devrait occuper le même nombre d'octets, soit 1 octet qui est le minimum pour un micro 8bits ? Mais je pense qu'il ne sont pas placé au même endroit ("define" -> flash ?, "constante" -> flash ?, "int " -> sram ? Je l'ai lu mais je ne m'en rappelle plus.

Merci pour la piqûre de rappel :grin:

Bonsoir,

koala: J'ai fais un test avec Arduino ERW qui me donne une estimation de la SRAM utilisée après la compilation. En compilant un programme vide avec juste une variable de déclarée j'obtiens ces résultats :

byte test = 5; donne SRAM 9 bytes int test = 5; donne SRAM 9 bytes

Arrivé là je me suis dis que le compilateur code un int sur deux octets uniquement si sa valeur est supérieur à 255 donc j'ai testé avec :

int test = 2000; ce qui donne SRAM 9 bytes ??

Si la variable n'est pas utilisée, le compilateur l'élimine.

Ajoute dans setup un

++test;

Les tailles mémoires seront cohérentes

Pour répondre à 68tjs :

Une #define est traité par le préprocesseur. La macro définie n'a pas de présence en mémoire.

Étonnant car je viens de regarder le fichier arduino.h et j'ai trouvé ces deux lignes:

typedef uint8_t boolean;
typedef uint8_t byte;

Est-ce que tu as fait la même manip avec un "char" ou un "int8_t " ?

C’est à dire ? (mais ce n’est peut-être pas à moi que tu réponds…)

En fait je me suis mélangé les pinceaux c'est aux points d'intérogations de Kaola que je réagissais:

byte test = 5; donne SRAM 9 bytes int test = 5; donne SRAM 9 bytes Arrivé là je me suis dis que le compilateur code un int sur deux octets uniquement si sa valeur est supérieur à 255 donc j'ai testé avec : int test = 2000; ce qui donne SRAM 9 bytes ??

Pour dire que le byte (comme le boolean) est défini comme un uint8_t

Mon test est faux, comme l'explique jlbechennec car j'ai pas utilisé la variable donc elle est traitée comme un commentaire :)

J'essaye ce soir après le boulot

koala: Salut

Je me suis toujours posé une question au sujet des numéros de pin, dans tous les exemples, elles sont déclarées en int.

Comme un numéro de pin ne peut être négatif, on devrai la déclarer en unsigned int ? Je me suis dis que c'est pour éviter de taper du code car comme on n'a aucun numéro supérieur à la capacité d'un int, ça roule :)

Maintenant, un int est codé sur deux octets, donc pourquoi ne pas déclarer les numéros de pin en byte sur un octet ?

J'ai fais un test avec Arduino ERW qui me donne une estimation de la SRAM utilisée après la compilation. En compilant un programme vide avec juste une variable de déclarée j'obtiens ces résultats :

byte test = 5; donne SRAM 9 bytes int test = 5; donne SRAM 9 bytes

Arrivé là je me suis dis que le compilateur code un int sur deux octets uniquement si sa valeur est supérieur à 255 donc j'ai testé avec :

int test = 2000; ce qui donne SRAM 9 bytes ??

Soit je me plante et la SRAM n'est pas la mémoire utilisée par mes variables, soit un byte est codé aussi sur deux octets soit l'estimation est fausse soit je capte rien...

Si une variable n'est pas utilisée, elle est ignorée donc elle n'occupe pas de place en mémoire. Si une variable est utilisée mais définie en const elle n'est pas créé. La valeur est mise directement dans les instructions lors de la compilation donc elle n'occupe pas de place en mémoire.

Concernant les numéros de pin, les fonctions sont définies ainsi

void pinMode(uint8_t pin, uint8_t mode)
void digitalWrite(uint8_t pin, uint8_t val)
int digitalRead(uint8_t pin)

Donc ces fonctions attendent des uint8_t ce qui correspond à des unsigned char.

on s'éloignerait pas un peu du sujet? :)

Sans doute, mais nous n'avons plus de nouvelles de SuperGlue donc nous ne devons pas le gêner. Si jamais c'était le cas qu'il n'hésite pas à se manifester.

Puis c'était pas inutile car pour ma part j'ai appris quelque chose (^_^)

koala: Puis c'était pas inutile car pour ma part j'ai appris quelque chose (^_^)

j'ai pas dit inutile, mais dans ce cas, autant créer un topic dédié que tout le monde pourra lire au lieu de se noyer dans un autre ;)

Oups :blush:
j’ai répondu en croyant que c’était une question de SuperGlue