ESP8266 function Void and Float problem

Hello Guys While I am programming my Esp8266 for calculating the voltage using LM258.

previously I have used this code

#include <Filters.h>

#define ZMPT101B A0

float testFrequency = 60; 
float windowLength = 100 / testFrequency; 

int RawValue = 0;
float Volts_TRMS; 
float intercept = 0; 
float slope = 1.8;

RunningStatistics inputStats;

void setup() {
  Serial.begin(115200); 
  Serial.println("Serial started");
  inputStats.setWindowSecs(windowLength);
}

void loop() {
  ReadVoltage();
}

void ReadVoltage() {
  RawValue = analogRead(ZMPT101B);
  inputStats.input(RawValue); 

    Volts_TRMS = inputStats.sigma() * slope + intercept;
    Volts_TRMS = Volts_TRMS*1.25; 
    
    if (Volts_TRMS > 30 && Volts_TRMS < 300) {
      Serial.println(Volts_TRMS);
    } else {
      Serial.println("0");
    }
 }

When i use this code with void it works well but as soon as I change my code from void to float it is not giving me proper values here is the float code that i have created.

#include <Filters.h>

#define ZMPT101B A0

float testFrequency = 60; 
float windowLength = 100 / testFrequency; 

int RawValue = 0;
float Volts_TRMS; 
float intercept = 0; 
float slope = 1.8;

RunningStatistics inputStats;

void setup() {
  Serial.begin(115200); 
  Serial.println("Serial started");
  inputStats.setWindowSecs(windowLength);
}

void loop() {
  float voltage = ReadVoltage();
  Serial.print("Voltage: ");
  Serial.println(voltage); 
  delay(1000); 
}

float ReadVoltage() {
  RawValue = analogRead(ZMPT101B);
  inputStats.input(RawValue); 

    Volts_TRMS = inputStats.sigma() * slope + intercept;
    Volts_TRMS = Volts_TRMS*1.25; 
    
  if (Volts_TRMS > 30 && Volts_TRMS < 300) {
    return Volts_TRMS;
  } else {
    return 0;
  }
 }

What is the issue might be here can anybody tell me?

Welcome to the forum

As your topic does not relate to the operation of IDE 1.x it has been moved to the Programming category of the forum

What do you see if you print the value of Volts_TRMS in the "float" version of your function ?

some random values... like when i am printing for void it is showing me voltage around 220-230 which i have calibrated but as soon as i use float it is showing me some random values between 0 to 70.

See I have done some changes in the code

#include <Filters.h>

#define ZMPT101B A0

float testFrequency = 60; 
float windowLength = 100 / testFrequency; 

int RawValue = 0;
float Volts_TRMS; 
float intercept = 0; 
float slope = 1.8;

RunningStatistics inputStats;

void setup() {
  Serial.begin(115200); 
  Serial.println("Serial started");
  inputStats.setWindowSecs(windowLength);
}

void loop() {
  float voltage;
  ReadVoltage(voltage);
  Serial.println(voltage);
}

void ReadVoltage(float& voltage) {
  RawValue = analogRead(ZMPT101B); // read the analog in value:
  inputStats.input(RawValue); // log to Stats function

  Volts_TRMS = inputStats.sigma() * slope + intercept;
  Volts_TRMS = Volts_TRMS * 1.25; // Further calibration if needed

  if (Volts_TRMS > 30 && Volts_TRMS < 300) {
    voltage = Volts_TRMS; // Assign the voltage value to the reference variable
  } else {
    voltage = 0; // Assign 0 to the reference variable
  }
}

This code working fine for me right now but i want to intigrate this code into my main code which is this one



#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <Filters.h>
#include "pcloud.h"

const char* ssid = "Password";
const char* password = "Password";
const char* authCode = "pcloud-oU8MKDfAINeIVAkqaHDLB8i";

#define ZMPT101B A0

float testFrequency = 60; 
float windowLength = 100 / testFrequency; 

int RawValue = 0;
float Volts_TRMS; 
float intercept = 0; 
float slope = 1.8;

RunningStatistics inputStats;

pCloud pCloud(ssid, password, authCode);

void setup() {
  Serial.begin(115200);
  inputStats.setWindowSecs(windowLength);
  pCloud.setup();
  pCloud.setPinMode(D0, OUTPUT);
  pCloud.setPinMode(D1, OUTPUT);
  pCloud.setPinMode(D2, OUTPUT);
  pCloud.setPinMode(D3, OUTPUT);
  pCloud.setPinMode(D4, OUTPUT);
  pCloud.setPinMode(D5, OUTPUT);
  pCloud.setPinMode(D6, OUTPUT);
  pCloud.setPinMode(D7, OUTPUT);
  pCloud.setPinMode(D8, OUTPUT);

}

void loop() {
  float voltage;
  ReadVoltage(voltage);
  Serial.println(voltage);
  pCloud.loop();
  pCloud.VirtualWrite(V0, voltage);
}

void ReadVoltage(float& voltage) {
  RawValue = analogRead(ZMPT101B); // read the analog in value:
  inputStats.input(RawValue); // log to Stats function

  Volts_TRMS = inputStats.sigma() * slope + intercept;
  Volts_TRMS = Volts_TRMS * 1.25; // Further calibration if needed

  if (Volts_TRMS > 30 && Volts_TRMS < 300) {
    voltage = Volts_TRMS; // Assign the voltage value to the reference variable
  } else {
    voltage = 0; // Assign 0 to the reference variable
  }
}

but in this code it is still not working

The problem is not the type of function (void vs float), but the fact that in the second code you add Wi-Fi and cloud (and, most likely, a lot of other code).
The library for the ZMPT sensor is very sensitive to delays. To get the correct values, you must measure the data hundreds of times per second. Obviously, when working with a network, the code may have delays tens of times longer.

Yes, so do I have to change this window size right?
float windowLength = (100 / testFrequency);

I am not sure.
I highly doubt that working with this sensor is compatible with working in the cloud

ah man is there any library available rather than ZMPT for this?

If you comment the last two lines in the loop - is it make the sensor output correct?

heyyyy.... bruhh i am geeting the values correctly now but i got the values after soo much time see this Serial monitor output

16:33:08.862 -> ...........
16:33:14.404 ->
16:33:14.404 -> ____ ____ _ ___ _ _ ____
16:33:14.404 -> | _ \ / | | | / _ \ | | | | | _ \
16:33:14.450 -> | |
) | _____ | | | | | | | | | | | | | | | |
16:33:14.450 -> | / |
| | |__ | |___ | || | | || | | || |
16:33:14.450 -> |
| _| || _/ ___/ |____/
16:33:14.450 ->
16:33:14.450 ->
16:33:14.450 -> SERVER: pcloud.codeestro.com
16:33:14.450 -> WIFI SSID: Password
16:33:14.450 -> IP ADDRESS: 00.00.00.00
16:33:14.450 -> 266.46
16:33:18.252 -> 0.00
16:33:21.372 -> 0.00
16:33:24.722 -> 0.00
16:33:27.996 -> 0.00
16:33:31.275 -> 0.00
16:33:34.705 -> 0.00
16:33:38.293 -> 0.00
16:33:41.679 -> 0.00
16:33:45.637 -> 0.00
16:33:48.861 -> 0.00
16:33:52.310 -> 0.00
16:33:55.619 -> 0.00
16:33:58.976 -> 0.00
16:34:02.453 -> 0.00
16:34:05.944 -> 0.00
16:34:09.614 -> 0.00
16:34:13.339 -> 0.00
16:34:17.027 -> 0.00
16:34:20.671 -> 0.00
16:34:24.018 -> 0.00
16:34:27.306 -> 0.00
16:34:30.522 -> 0.00
16:34:33.851 -> 0.00
16:34:37.071 -> 0.00
16:34:40.217 -> 0.00
16:34:43.356 -> 0.00
16:34:47.209 -> 0.00
16:34:50.604 -> 0.00
16:34:53.769 -> 0.00
16:34:56.936 -> 0.00
16:35:00.237 -> 0.00
16:35:03.389 -> 0.00
16:35:06.694 -> 0.00
16:35:10.204 -> 294.12
16:35:13.486 -> 284.60
16:35:16.950 -> 275.48
16:35:20.181 -> 266.75
16:35:23.643 -> 257.39
16:35:26.974 -> 249.52
16:35:30.215 -> 242.47
16:35:33.427 -> 236.34
16:35:36.531 -> 231.01
16:35:39.636 -> 227.52
16:35:42.786 -> 223.47
16:35:46.105 -> 218.35
16:35:49.300 -> 213.17
16:35:52.746 -> 210.20

yess!!! you are right..

Sorry, I am not experienced with the Cloud... Perhaps you could to pause the Cloud.loop() some way during the sensor reading...
But the best way is to use sensors that do the calculations itself and outputs the processed data.

Ohh okay, let me see what I can do. :melting_face: Thanks though..

Got the solution to this problem by using their library I have resolved my problem.

library link: https://github.com/Abdurraziq/ZMPT101B-arduino/tree/master

Here is the updated code

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <ZMPT101B.h>
#include "pcloud.h"

const char* ssid = "SSID";
const char* password = "PASSWORD";
const char* authCode = "Token";

#define SENSITIVITY 500.0f

float Frequency = 60.0; 
ZMPT101B voltageSensor(A0, Frequency);

pCloud pCloud(ssid, password, authCode);

void setup() {
  Serial.begin(115200);
  voltageSensor.setSensitivity(SENSITIVITY);
  pCloud.setup();
  pCloud.setPinMode(D0, OUTPUT);
  pCloud.setPinMode(D1, OUTPUT);
  pCloud.setPinMode(D2, OUTPUT);
  pCloud.setPinMode(D3, OUTPUT);
  pCloud.setPinMode(D4, OUTPUT);
  pCloud.setPinMode(D5, OUTPUT);
  pCloud.setPinMode(D6, OUTPUT);
  pCloud.setPinMode(D7, OUTPUT);
  pCloud.setPinMode(D8, OUTPUT);

}

void loop() {
  float voltage;
  ReadVoltage(voltage);
  Serial.println(voltage);
  pCloud.loop();
  pCloud.VirtualWrite(V0, voltage);
}

void ReadVoltage(float& voltage) {
  float new_voltage = (voltageSensor.getRmsVoltage()*1.35);

  if (new_voltage > 30 && new_voltage < 300) {
    voltage = new_voltage;
  } else {
    voltage = 0;
  }
}
1 Like

I just sped read the thread, thinking you might have made a simple error commonly seen, that is not returning a value with a proper return statement.

You have solved your problem, but in an odd way. Please read this change and see how a function that returns a value is used:

void loop() {
  float voltage;
  voltage = ReadVoltage();
  Serial.println(voltage);
  pCloud.loop();
  pCloud.VirtualWrite(V0, voltage);
}

float ReadVoltage() {
  float the_voltage = voltageSensor.getRmsVoltage() * 1.35;

  if (the_voltage > 30 && the_voltage < 300) {
    // the voltage is OK
  }
  else {
    // out of range, return 0
    the_voltage = 0;
  }

  return the_voltage;
}

It's your code with a few style tweaks (spaces, extra parents removed &c.) my elbows did before my brain would not let them and

changing getting the value back to where you use it from modifying an argument passed by reference (handy sometimes, but not needed and possibly bad elsewhere) to letting the function return a value.

HTH

a7

Thank you so much for spending so much time. Surely i will check this code if it might work then its really good for me.. :raised_hands:t2:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.