Mesurer la consommation de l'énergie d'une avec arduino

Bonjour, voici mon problème; je dois calculer la consommation d'une lampe de 12V à deux moments c'est-à-dire une fois à 25% et une à 100%. Je m'explique: la lampe sera allumée mais pas a 100% mais lorsqu'il y aura un piéton la lampe va s'allumer a 100%, je dois calculer la consommation à ces deux moments. J'ai essayé de simuler sur proteus (logiciel de simulation de circuit électrique) mais je n'ai pas réussi. J'ai vu sur l'internet que je devais faire un pont diviseur de tension, puisque la tension dans le circuit sera de 12V et les entrées analogiques d'arduino peuvent accepter que 5 V, mais comment je dois paramétrer cela dans mon programme arduino ? puisque je ne m'y connais pas du tout en programmation. Ensuite pour mesurer le courant j'ai commandé un capteur de courant ACS712. J'ai vu sur internet plusieurs programmes sur ces capteurs mais je ne comprends pas les calculs qui sont réalisés. Et pour finir l'énergie est le produit de la puissance et de l'heure comment intégrer cela dans le programme ? je dois afficher cela sur le moniteur série, je pense que je pourrai faire cela moi-même sinon en résumé voila ce que je veux faire mais avec une lampe : http://www.instructables.com/id/DIY-...eter-Arduino/? , j'ai besoin de pistes pour aboutir a mon programme (j'ai jamais programmé). Merci pour votre aide !

Je n'ai jamais fait ce genre de projets mais en toutes logiques il faudrait utiliser un voltmètre et/ou un ampèremètre. Puis après (je sais pas si tu veux calculer la conso a un moment précis) tu fait un "delay(temps);" jusqu'au moment ou tu calculera !

J'espère avoir pu t'aider ! ;)

Première étape, faire un pont diviseur pour avoir une valeur 0 < x < 5V et mesurer cette tension avec une entrée analogique.
Attention à ne pas dépasser 5V en entrée.
http://arduino.cc/en/Reference/analogRead
La valeur mesurée 0-1023 est à convertir en tension avec simple une règle de trois (selon le rapport du pont diviseur et la tension servant de référence).

2e étape, mesurer l’intensité, avec le capteur de courant, c’est le même principe de mesure analogique.

  1. Multiplier UxI pour avoir une puissance instantanée en continu (si c’est en alternatif sinusoïdal, carré… il faut corriger pour avoir une valeur efficace).

  2. Cumuler chaque seconde ces mesures pour avoir une énergie en W.s, et convertir si besoin l’affichage en kW.h

Bonsoir, tout d’abord merci de vos réponses !
je pense avoir compris le pont diviseur de tension :wink: comme j’ai du 12V dans mon circuit et pour avoir - 5V à l’entrée de la pin analogique 3 j’ai fais comme calcul : R1/R1+R2 * Ve ce qui donne :
9000/9000+13000 * 12 = 4,90 ! Mais en simulant sur proteus y’a quelque chose que je n’ai pas compris ! Pourquoi lorsque je branche un voltmètre à la sortie du pont diviseur de tension j’obtiens 6,75 V ? (je joindrai ci - dessous une capture d’écran). Ensuite est-ce que mon schéma sur proteus est correct ? Puis pour finir, pour le programme j’ai utilisé le programme du site : http://www.instructables.com/files/orig/FF3/O206/H2BMNS8L/FF3O206H2BMNS8L.ino en changeant certains termes par rapport a mon schéma et en supprimant quelques lignes. Étant donné que je n’ai jamais programmé je ne comprends pas certaines lignes…
Le programme modifié à ma façon est le suivant :

int batMonPin = A4; // input pin for the voltage divider
int batVal = 0; // variable for the A/D value
float pinVoltage = 0; // variable to hold the calculated voltage
float batteryVoltage = 0;

int analogInPin = A0; // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0; // value read from the carrier board
int outputValue = 0; // output in milliamps
unsigned long msec = 0;
float time = 0.0;
int sample = 0;
float totalCharge = 0.0;
float averageAmps = 0.0;
float ampSeconds = 0.0;
float ampHours = 0.0;
float wattHours = 0.0;
float amps = 0.0;

int R1 = 9000; // Resistance of R1 in ohms
int R2 = 13000; // Resistance of R2 in ohms

float ratio = 0.6; // Calculated from R1 / R2 (est ce correct? ou faut le laisser a 0?)

void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);

}

void loop() {

int sampleBVal = 0;
int avgBVal = 0;
int sampleAmpVal = 0;
int avgSAV = 0;

for (int x = 0; x < 10; x++){ // run through loop 10x (je ne comprend pas cette ligne)

// read the analog in value:
sensorValue = analogRead(analogInPin);
sampleAmpVal = sampleAmpVal + sensorValue; // add samples together ( celle-ci non plus…)

batVal = analogRead(batMonPin); // read the voltage on the divider
sampleBVal = sampleBVal + batVal; // add samples together (idem)

delay (10); // let ADC settle before next sample

}

avgSAV = sampleAmpVal / 10; // (pareil)

// convert to milli amps
outputValue = (((long)avgSAV * 5000 / 1024) - 500 ) * 1000 / 185; // (un peu pres mais pourquoi 5000 et - 500 ?)

/* sensor outputs about 100 at rest.
Analog read produces a value of 0-1023, equating to 0v to 5v.
“((long)sensorValue * 5000 / 1024)” is the voltage on the sensor’s output in millivolts.
There’s a 500mv offset to subtract.
The unit produces 133mv per amp of current, so
divide by 0.133 to convert mv to ma

*/

avgBVal = sampleBVal / 10; //divide by 10 (number of samples) to get a steady reading (pas compris qu’est ce que c’est la avgBVal et le sampleBVal)

pinVoltage = avgBVal * 0.00488; // Calculate the voltage on the A/D pin
/* A reading of 1 for the A/D = 0.0048mV
if we multiply the A/D reading by 0.00488 then
we get the voltage on the pin.

NOTE! .00488 is ideal. I had to adjust
to .00610 to match fluke meter.

Also, depending on wiring and
where voltage is being read, under
heavy loads voltage displayed can be
well under voltage at supply. monitor
at load or supply and decide.
*/

ratio = (float)R1 / (float)R2; // (dois-je changer les valeurs de R1 et R2?)
batteryVoltage = pinVoltage * ratio; // Use the ratio calculated for the voltage divider
// to calculate the battery voltage

amps = (float) outputValue / 1000;
float watts = amps * batteryVoltage;

Serial.print(“Volts = " );
Serial.print(batteryVoltage);
Serial.print(”\t Current (amps) = “);
Serial.print(amps);
Serial.print(”\t Power (Watts) = ");
Serial.print(watts);

sample = sample + 1; // (sample = exemple ?)

msec = millis();

time = (float) msec / 1000.0;

totalCharge = totalCharge + amps;

averageAmps = totalCharge / sample;

ampSeconds = averageAmps*time;

ampHours = ampSeconds/3600;

wattHours = batteryVoltage * ampHours;

Serial.print("\t Time (hours) = ");
Serial.print(time/3600);

Serial.print("\t Amp Hours (ah) = “);
Serial.print(ampHours);
Serial.print(”\t Watt Hours (wh) = ");
Serial.println(wattHours);

delay(10);
}

Pouvez-vous si possible m’expliquer les lignes que je n’ai pas compris ou les termes a changer ? svp (j’ai mis en commentaire les lignes que j’ai du mal à comprendre)
La simulation sur proteus est un échec puisque la tension affichée n’est pas du 12V et la valeur de l’intensité est fausse (j’ai branché un ampèremètre dans le circuit et la valeur n’est pas la même que dans le moniteur série) et ensuite l’heure je sais pas.
Je vous joins ci-dessous mes simulations. Merci de votre aide !
Ledebutant1

Bonsoir,
Les balises codes SVP

Bonjour, excusez-moi voici le code :

int batMonPin = A4;    // input pin for the voltage divider
int batVal = 0;       // variable for the A/D value
float pinVoltage = 0; // variable to hold the calculated voltage
float batteryVoltage = 0;

int analogInPin = A0;  // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0;        // value read from the carrier board
int outputValue = 0;        // output in milliamps
unsigned long msec = 0;
float time = 0.0;
int sample = 0;
float totalCharge = 0.0;
float averageAmps = 0.0;
float ampSeconds = 0.0;
float ampHours = 0.0;
float wattHours = 0.0;
float amps = 0.0;

int R1 = 9000; // Resistance of R1 in ohms
int R2 = 13000; // Resistance of R2 in ohms

float ratio = 0.6;  // Calculated from R1 / R2    (est ce correct? ou faut le laisser a 0?)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
  
}

void loop() {
  
int sampleBVal = 0;
int avgBVal = 0;  
int sampleAmpVal = 0;
int avgSAV = 0;
  
 for (int x = 0; x < 10; x++){ // run through loop 10x                     (je ne comprend pas cette ligne)
 
  // read the analog in value:
  sensorValue = analogRead(analogInPin);   
  sampleAmpVal = sampleAmpVal + sensorValue; // add samples together       ( celle-ci non plus...)

  batVal = analogRead(batMonPin);    // read the voltage on the divider 
  sampleBVal = sampleBVal + batVal; // add samples together                (idem)
  
  delay (10); // let ADC settle before next sample

 }
 
 avgSAV = sampleAmpVal / 10;                                             // (pareil)
 
  // convert to milli amps
  outputValue = (((long)avgSAV * 5000 / 1024) - 500 ) * 1000 / 185;     // (un peu pres mais pourquoi 5000 et - 500 ?)
  
/* sensor outputs about 100 at rest. 
Analog read produces a value of 0-1023, equating to 0v to 5v.
"((long)sensorValue * 5000 / 1024)" is the voltage on the sensor's output in millivolts.
There's a 500mv offset to subtract. 
The unit produces 133mv per amp of current, so
divide by 0.133 to convert mv to ma
          
*/

 
 avgBVal = sampleBVal / 10; //divide by 10 (number of samples) to get a steady reading    (pas compris qu'est ce que c'est la avgBVal et le sampleBVal)
 
  pinVoltage = avgBVal * 0.00488;       //  Calculate the voltage on the A/D pin
                                /*  A reading of 1 for the A/D = 0.0048mV
                                    if we multiply the A/D reading by 0.00488 then 
                                    we get the voltage on the pin.  
                                   
                                    NOTE! .00488 is ideal. I had to adjust 
                                    to .00610 to match fluke meter.
                                    
                                    Also, depending on wiring and 
                                    where voltage is being read, under 
                                    heavy loads voltage displayed can be 
                                    well under voltage at supply. monitor 
                                    at load or supply and decide.
*/

  ratio = (float)R1 / (float)R2;                                                               // (dois-je changer les valeurs de R1 et R2?)
  batteryVoltage = pinVoltage * ratio;    //  Use the ratio calculated for the voltage divider
                                          //  to calculate the battery voltage
                                          
                                            
  amps = (float) outputValue / 1000;
  float watts = amps * batteryVoltage;
    
  Serial.print("Volts = " );                       
  Serial.print(batteryVoltage);      
  Serial.print("\t Current (amps) = ");      
  Serial.print(amps);  
  Serial.print("\t Power (Watts) = ");   
  Serial.print(watts);   
  
    
  sample = sample + 1;                                                                             // (sample = exemple ?)
  
  msec = millis();
  
  
  
 time = (float) msec / 1000.0;
  
 totalCharge = totalCharge + amps;
  
 averageAmps = totalCharge / sample;
  
 ampSeconds = averageAmps*time;

 ampHours = ampSeconds/3600;
  
 wattHours = batteryVoltage * ampHours;
  
 



  Serial.print("\t Time (hours) = ");
  Serial.print(time/3600);
  
  Serial.print("\t Amp Hours (ah) = ");
  Serial.print(ampHours);
  Serial.print("\t Watt Hours (wh) = ");
  Serial.println(wattHours);
  
  delay(10);                     
}

Merci pour votre aide !

Vous measurer le voltage du mauvaise cote de la lampe, presentement vous measurer le voltage du ampmetre.

Pour la ratio de R1 et R2 c'est pas grave il est calculer plus tard dans le programme.

Run through loop 10 X = il prend 10 measures et fait la moyene pour avoir des lectures plus stables. Les autres questions qui suit devrait faire du sense.

5000 = 5000mV il veut measurer en mV max 5V 500 = 500mV probablement le voltage ´ fix' sur le ampmetre. Il triche les valeurs pour que ca marche mais le voltage varie...

Il aurait du brancher comme suit, Sortie du pot Ampmetre Voltmetre Lampe Mise a la terre

Bonsoir, Merci pour ces explications !
Tout d’abord j’ai réussi à prélever l’intensité (sur proteus) puis j’ai intégré la tension comme une constante car je n’ai pas réussi avec le pont diviseur de tension. Ensuite j’ai dit à mon programme de calculer la puissance; ce qui a marché :wink: . Mais maintenant comment avoir ce résultat en kwh ? et mon deuxième problème est le suivant: Je dois calculer l’énergie à deux moments, c’est-à-dire, une fois quand il est allumé (pas à son intensité lumineuse max), et une fois quand il sera au maximum (passage d’un piéton). j’ai pensé à une ligne comme if E? ou E>? mais je sais pas… E c’est l’énergie. Si ya des choses à ameliorer dans le programme je suis preneur ;D
Voici le programme:

  int temp=0;
  float sum =0;
  float AMPS_SCALE =0;
  float amps=0;
int volt=12;
int puissance =0;
  
  void setup() {
     Serial.begin(9600);
      Serial.begin(9600); 
  Serial.println("Volt");
  }
  
  void loop() {
    
    sum = 0;
    for(int i = 0; i < 100; i++)  // loop through reading raw adc values 100 number of times 
  {
    temp=analogRead(A1);     // read the input pin   
    sum += temp;             // store sum for averaging
    delayMicroseconds(50);           
  }
   sum=sum/100;              // divide sum by 100 to get average 
   
  // Calibration  for current
  
   AMPS_SCALE= 5/(1024* 0.185);      // Sensitivity = 185mV
   amps = AMPS_SCALE* sum - 13.51 - 0.02;   // 2.5/0.185 = 13.51 
   puissance = amps * volt;
 

  Serial.print(amps);
  Serial.println("A");
  delay(500);
  Serial.print(volt);
  Serial.println("V");
  Serial.print(puissance);
  Serial.println("W");
  delay(1000);
  
  }

un seul Serial.begin(9600); suffit.

Bonjour Merci de votre réponse !,
J’ai toujours du mal à comprendre quelques lignes:

void loop ()
   {
    sum = 0;
    for(int i = 0; i < 100; i++)  // loop through reading raw adc values 100 number of times 
  {
    temp=analogRead(A1);     // read the input pin   
    sum += temp;             // store sum for averaging
    delayMicroseconds(50);           
  }
   sum=sum/100;              // divide sum by 100 to get average

sum veut dire somme, mais je ne vois pas à quoi il correspond. Ensuite la deuxième ligne correspond t-elle au nombre de fois que le programme va exécuter les 3 lignes suivantes du programme c’est dire 100x pendant 50 secondes ? J’ai essayé de comprendre cette deuxième ligne, et d’après mes recherches il s’agit d’une incrémentation, donc ce qui veut dire qu’on ajoute 1 a quelque chose, mais a quoi ? puis encore une fois le sum me pose problème avec le temp pourquoi sum += temp ? puis pourquoi on le divise par 100 ? pour avoir une moyenne de quoi ? ( je tiens à rajouter que ce programme sert à mesurer l’intensité circulant dans un circuit a l’aide d’un capteur de courant)
Merci de votre aide !
Ledebutant1

sum est un compteur for est une boucle qui tourne 100 fois on ajoute la lecture à chaque boucle et on divise par cent pour faire une moyenne 1+1+1+1+1=5 moyenne 5/5 = 1 tout bête, un peu de lecture c++ ne ferait pas de mal ;)

Merci de votre réponse ! J'ai un autre problème: mon objectif est d'allumer une led a une intensité faible, est-ce-possible ? Ensuite a l'aide d'un capteur de mouvement, lorsqu'il détecte ma main, elle va s'allumer a 5V (intensité max) puis elle se remet en mode "veille" (intensité faible). J'ai réussi à allumer la led à 100% quand je passe ma main mais après elle s'éteint au lieu de passer en mode "veille". Pourrais-je avoir des pistes ? Merci de votre aide ! Ledebutant1