geen resultaat bij delen door 1000 [solved]

Hallo beste mensen,

Mijn naam is John en ik ben nieuw op dit forum. Ik heb mij net pas aangemeld dus mijn profiel is nog niet up to date, maar dat komt nog wel.
Ik heb het volgende probleem. Ik ben bezig met een KWh logger dmv een aparte KWh meter die ik in mijn meterkast wil inbouwen.
Ben nu bezig met de code hiervoor te schrijven maar moet erbij vermelden dat ik nog niet zoveel ervaring hiermee heb. Vooral lang bezig geweest met inlezen. Heb hier en daar wat stukjes code geleend om de pulsen die mijn KWh meter geeft te tellen en om te zetten in verbruikt vermogen en totaal Kwh verbruik. Ik laat alles even naar de seriele monitor gaan om alles te controleren.
Het aantal pulsen dat mijn KWh meter geeft( 1000 pulsen = 1KWh) wil ik delen door duizend zodat de uitkomst in KWh gegeven wordt.
Alleen krijg ik geen resultaat als ik door duizend deel. Als ik bijvoorbeeld 100 invul, krijg ik wel resultaat. Volgens mij zit ik mij nu blind te staren op iets wat misschien betrekkelijk eenvoudig is maar ik zie het niet(meer) 8).
Kan iemand hier een (deskundige) blik op werpen en mij een stukje op gang helpen. Een complete oplossing is niet nodig, ik moet zelf ook nog iets te doen hebben. :grin:
Hieronder de code tot zover:

#include <LiquidCrystal.h>

  LiquidCrystal lcd (12,11,10,6,5,4,3);
  
//instellen vaste variabelen voor tellen pulsjes

  const int KwhPulse = 2; // puls aangesloten op digitale ingang 2
  
// instellen variabelen voor bijhouden aantal pulsjes

  int pulseState = 1; // huidige staat van kwh puls, deze is äctief laag" dus hier inverteren
  long KwhpulseCounter = 0; // teller voor aantal pulsen
  int lastPulseState = 1; // vorige staat van Kwh puls
 
// instellen variabelen berekenen pulstijd
  
  float pulseAan = 0;
  float pulseUit = 1;
  float verstrekenTijd =0;
  
  //instellen variabelen berekenen Kwh en huidig vermogen
  int currentWatts = 0;
  float totalKwh = 0.00;
  int tijd=0;
  
 //setup 
  void setup() {
    
    pinMode(KwhPulse, INPUT); // maak van (digitale)pin 2 een input
    
    Serial.begin(9600); // seriele communicatie op 9600 baud
    
    lcd.begin(16,2); // lcd met 2 regels en 16 karakters per regel
    
    //lcd.print("Kwh"); // boodschap op lcd schrijven
  }
  
  
  void loop() {
   pulseState = digitalRead(KwhPulse);  // lees waarde digitale ingang en bewaar de waarde in "pulseState"
   
   if (pulseState != lastPulseState){  //vergelijk de staat van de Kwhpulse met zij vorige staat
     if (pulseState == LOW){           //als de huidige staat laag is ging de puls van uit naar aan
     KwhpulseCounter++;                // als de staat is veranderd, verhoog de teller
     Serial.print ("aantal pulsen: ");  //controle
     Serial.println (KwhpulseCounter);  //controle
     
     pulseAan = millis();                          //tijd in milliseconden vanaf start arduino
     verstrekenTijd = (pulseAan - pulseUit)/1000;  //gemeten tijd tussen twee pulsen
     pulseUit = pulseAan;       //bewaren voor volgende ronde
     
     Serial.print("tijd tussen pulsen: ");  //controle
     Serial.print (verstrekenTijd);  //controle
     Serial.println(" sec");  //controle
     
     currentWatts = 3600000 / (1000 * verstrekenTijd);
     
     Serial.print ("huidig verbruik: ");  //controle
     Serial.print (currentWatts);  //controle
     Serial.println(" Watt");  //controle
     
     
     totalKwh = KwhpulseCounter / 1000;
     Serial.print ("Totaal Kwh verbruik: ");
     Serial.println(totalKwh);
     
     }
   }
  //bewaar de huidige staat als de laatste staat voor de volgende keer in de loop
  lastPulseState = pulseState;   


  
  
  }

Dag comteccie Welkom op het nederlandstalige gedeelte van het arduino forum. Ik ben blij te zien dat je je code toevoegde. Dat maakt de zaak direct wat handiger. Ik heb voor jou code tags toegevoegd ant dat leest makkelijker. Best doe je dat natuurlijk zelf.

Ik ben niet helemaal zeker van wat ik ga voorstellen maar vervang eens volgende lijn

totalKwh = KwhpulseCounter / 1000;

door

totalKwh = ((float)KwhpulseCounter) / 1000.0;

Met vriendelijke groet Jantje

You better do the calculations with either all floats or all unsigned long. I prefer unsigned long in this case. You have a mix of integer, float and long, that is bound to go wrong someday. Add comment to every calculation, about what is calculated, and how the conversion is and if it will fit in the resulting variable.

Bedankt Jan voor de snelle reactie. Dat van die code tags wist ik niet maar zal er voortaan rekening mee houden. Helaas werkt jouw oplossing ook niet. Het resultaat blijft 0. Verander ik die 1000 in 100 dan krijg ik wel resultaten.

Hi Peter,

I changed some calculations and added some comments. But it still doesn’t work.
Suggestions are welcome

Greetings,
John

// invoegen bibliotheek
#include <LiquidCrystal.h>

  LiquidCrystal lcd (12,11,10,6,5,4,3);
  
//instellen vaste variabelen voor tellen pulsjes

  const int KwhPulse = 2; // puls aangesloten op digitale ingang 2
  
// instellen variabelen voor bijhouden aantal pulsjes

  int pulseState = 1; // huidige staat van kwh puls, deze is äctief laag" dus hier inverteren
  float KwhpulseCounter = 0; // teller voor aantal pulsen
  int lastPulseState = 1; // vorige staat van Kwh puls
 
// instellen variabelen berekenen pulstijd
  
  float pulseAan = 0;
  float pulseUit = 1;
  float verstrekenTijd =0;
  
  //instellen variabelen berekenen Kwh en huidig vermogen
  float currentWatts = 0;
  float totalKwh = 0;
  
  
 //setup 
  void setup() {
    
    pinMode(KwhPulse, INPUT); // maak van (digitale)pin 2 een input
    
    Serial.begin(9600); // seriele communicatie op 9600 baud
    
    lcd.begin(16,2); // lcd met 2 regels en 16 karakters per regel
    
    //lcd.print("Kwh"); // boodschap op lcd schrijven
  }
  
  
  void loop() {
   pulseState = digitalRead(KwhPulse);  // lees waarde digitale ingang en bewaar de waarde in "pulseState"
   
   if (pulseState != lastPulseState){  //vergelijk de staat van de Kwhpulse met zij vorige staat
     if (pulseState == LOW){           //als de huidige staat laag is ging de puls van uit naar aan
     KwhpulseCounter++;                // als de staat is veranderd, verhoog de teller
     Serial.print ("aantal pulsen: ");  //controle
     Serial.println (KwhpulseCounter);  //controle
     
     pulseAan = millis();                          //tijd in milliseconden vanaf start arduino
     verstrekenTijd = (pulseAan - pulseUit)/1000;  //gemeten tijd tussen twee pulsen
     pulseUit = pulseAan;                         //bewaren voor volgende ronde
     
     Serial.print("tijd tussen pulsen: ");  //controle
     Serial.print (verstrekenTijd);        //controle
     Serial.println(" sec");              //controle
     
     currentWatts = 3600000 / (1000 * verstrekenTijd); // het huidige afgenomen vermogen berekenen
     
     Serial.print ("huidig verbruik: ");  //controle
     Serial.print (currentWatts);  //controle
     Serial.println(" Watt");  //controle
     
     
     totalKwh = KwhpulseCounter / 1000.0;    // het totale KWh verbruik berekenen
     Serial.print ("Totaal Kwh verbruik: "); // controle
     Serial.println(totalKwh);              //controle
     
     }
   }
   
  //bewaar de huidige staat als de laatste staat voor de volgende keer in de loop
  lastPulseState = pulseState;   


  
  
  }

Ik heb de code wat aangepast naar de juiste type variabelen. Alleen is het me nog niet duidelijk waar de puls voor staat. KW? KWH?

@edit: Laat die vraag maar ff zitten het is 1000 pulsen per KWH. kijk nog wel ff verder

Dat je een float nog als 0 ziet komt vermoedelijk omdat bij print je maar 2 decimalen ziet van een in totaal 7 cijferig getal. Meer precisie kent float niet. Ik heb nu in jouw code een splitsing gemaakt van het getal voor en na de punt een een format gemaakt met voorloop nullen voor de decimalen,

Nu met de juiste code.

// invoegen bibliotheek
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 6, 5, 4, 3);

//instellen vaste variabelen voor tellen pulsjes

const int KwhPulse = 2; // puls aangesloten op digitale ingang 2

// instellen variabelen voor bijhouden aantal pulsjes

int pulseState 								= 1; // huidige staat van kwh puls, deze is äctief laag" dus hier inverteren
unsigned long KwhpulseCounter = 0; // teller voor aantal pulsen
int lastPulseState 						= 1; // vorige staat van Kwh puls

// instellen variabelen berekenen pulstijd

unsigned long pulseAan = 0;					// pulse aan en uit makengebruik van millis dus long gebruiken
unsigned long pulseUit = 1;
unsigned long verstrekenTijd = 0;		// en het verschil ook
unsigned int KWH_cijfer;						// cijfers voor de komma
unsigned int KWH_decimaal;					// cijfers achter de komma

//instellen variabelen berekenen Kwh en huidig vermogen

unsigned int currentWatts = 0;			// we kunnen max 65536 Watts verwerken. Anders unsigned long gebruiken
unsigned long totalKwh = 0;

//setup
void setup() {
	pinMode(KwhPulse, INPUT); 	// maak van (digitale)pin 2 een input
	Serial.begin(9600); 				// seriele communicatie op 9600 baud
	lcd.begin(16, 2); 					// lcd met 2 regels en 16 karakters per regel
	//lcd.print("Kwh"); 				// boodschap op lcd schrijven
}

void loop() {
	char kwhStr[9];
	pulseState = digitalRead(KwhPulse); 			// lees waarde digitale ingang en bewaar de waarde in "pulseState"

	if (pulseState != lastPulseState) { 			//vergelijk de staat van de Kwhpulse met zij vorige staat
		if (pulseState == LOW) { 								//als de huidige staat laag is ging de puls van uit naar aan
			KwhpulseCounter++;         						// als de staat is veranderd, verhoog de teller
			Serial.print("aantal pulsen: ");  		//controle
			Serial.println(KwhpulseCounter);  		//controle

			pulseAan = millis();           					//tijd in milliseconden vanaf start arduino
			verstrekenTijd = (pulseAan - pulseUit) / 1000; //gemeten tijd tussen twee pulsen
			pulseUit = pulseAan;                   	//bewaren voor volgende ronde

			Serial.print("tijd tussen pulsen: ");		//controle
			Serial.print(verstrekenTijd);        		//controle
			Serial.println(" sec");              		//controle

			currentWatts = 3600000 / (1000 * verstrekenTijd); // het huidige afgenomen vermogen berekenen

			Serial.print("huidig verbruik: ");  		//controle
			Serial.print(currentWatts);  						//controle
			Serial.println(" Watt");  							//controle
			//
			// eerst de cijfers voor en na de decimale punt bepalen
			//
			KWH_cijfer 		= KwhpulseCounter / 1000;		// eerst de cijfers voor de komma
			KWH_decimaal 	= KwhpulseCounter - (KWH_cijfer * 1000); // dan de decimalen
			//
			// dan een mooie strin opmaken
			//
			sprintf(kwhStr, "%4d.%03d", KWH_cijfer, KWH_decimaal);
 			totalKwh 	= KwhpulseCounter / 1000;  		// het totale KWh verbruik berekenen
			Serial.print("Totaal Kwh verbruik: "); 	// controle
			Serial.println(kwhStr);
		}
	}

	//bewaar de huidige staat als de laatste staat voor de volgende keer in de loop
	lastPulseState = pulseState;

}

Nico,

Bedankt voor de moeite. Ik heb je aangepaste code geprobeerd en hij werkt! Helemaal begrijpen doe ik het nog niet, maar ik ga mij beetje voor beetje verdiepen in de aanpassingen die je hebt gemaakt. Weer even een leermomentje zal ik maar zeggen. :)

Groeten, Johnny

In grote lijnen samengevat: millis() geeft een 32 bits getal terug (dus unsigned long) Omdat je er mee rekent wordt het verschil ook unsigned long

de KWH splits je in cijfers en decimalen. Dus KWH / 1000 voor de cijfers voor de punt. Daar het een long is heeft deze geen decimalen en ben je die automatisch kwijt in de cijfers. Het decimalen gedeelte bepaal je door de cijfers voor de komma met 1000 te vermenigvuldigen en van het totaal KWH af te trekken.

Het printen doe ik door eerst de cijders in een string (char []) te zetten gebruikmakend van sprintf.

format string; "%4d.03d" = 4 cijfers (%4d) voor de punt zonder voorloopnullen. dan de Punt dan 3 cijfers met voorloop nullen. (%03d). En als laatste de variabelen die ik erin wil zetten in volgorde van de format string

Mijn mening: Laat float vallen en werk met WH. Dus alleen integer rekenen das veeeeeeeeeeeeel makkelijker en veeeeeeeeeeeel sneller en eigenlijk nog preciezer ook.

Met vriendelijke groet Jantje

En een stuk compactere code....

nicoverduin: En een stuk compactere code....

Ik had zelfs nog niet gezien dat je float had verwijderd :-)

Heren,

Bedankt voor het meedenken. Ik zal alle gegeven informatie opslaan en meenemen voor later gebruik (het bekende leermomentje :grin:)

Groetjes,
Johnny