This is not even about accuracy. It is about wanting to compute the function pow() with exponents greater than 2 but only getting 0 as a result.
I am using Arduino UNO R4 WiFi to estimate the flow in a channel by calculating the distance w an ultrasonic sensor.
My sketch:
The following variables are automatically generated and updated when changes are made to the Thing
CloudFlowRate gasto;
CloudTemperatureSensor temperatura_atm;
CloudLength distancia;
CloudLength tirante;
CloudPercentage porcentajeQ;
CloudRelativeHumidity humedad_atm;
CloudTime date;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
#include <Adafruit_Sensor.h> //para el sensor DHT
#include <DHT.h> //para el sensor DHT
#include <SD.h> //para el SD
#include <SPI.h> //para el SD
#include <Wire.h> //para el reloj
#include <RTClib.h> //para el reloj
#include <Arduino.h>
#define trigPin 6
#define echoPin 5
#define DHTPIN 2
#define DHTTYPE DHT11
const int chipSelect = 10;
DHT dht(DHTPIN, DHTTYPE);
String ano;
String dia;
String mes;
String horas;
String minutos;
String segundos;
String Fecha;
String Hora;
String Nombrearchivo;
String Imprimir;
float H_canal = 146.30; //height between the base of the channel and the ultrasonic sensor
float tirante2 = -9999.00;
float Q2 = -9999.00;
float Qmax = 9.6601;
//creating variables to later save the values obtained with pow function:
float y_3 = -9999.00;
float y_4 = -9999.00;
float y_5 = -9999.00;
void setup() {
Serial.begin(9600);
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.println("Inicializando reloj RTC...");
if(! rtc.begin())
{ Serial.println("No se encontró RTC");
Serial.flush();
while (1) delay(10);
//abort();
}
if (rtc.lostPower())
{ Serial.println("RTC no está activado, colocar la hora");
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
else
{ Serial.println("RTC inicializado");
}
Serial.println("Inicializando tarjeta SD...");
if (!SD.begin(chipSelect))
{ Serial.println("No se pudo inicializar la SD, o no está conectada");
}
else
{ Serial.println("SD inicializada");
}
dht.begin();
}
void loop() {
ArduinoCloud.update();
// Your code here
//if (millis()-lastSensorRead > 30000) {
date = ArduinoCloud.getLocalTime();
delay (2000);
float h2 = dht.readHumidity();
float t2 = dht.readTemperature();
if (isnan(t2) || isnan(h2))
{ Serial.println(F("Failed to read from DHT sensor!"));
return;
}
float d = 133.88; //since calculating the distance with the ultrasonic sensor is not the problem, just change this value between 0 and H_canal stated at the beginning of the sketch
if (d<0)
{
tirante2 = -9999.00;
Q2 = -9999.00;
}
else
{ tirante2 = (H_canal - d)/100.00;
tirante = tirante2;
Serial.println(tirante2);
y_3 = pow(tirante2, 3.0);
y_4 = pow(tirante2, 4.0);
y_5 = pow(tirante2, 5.0);
Serial.println(y_3);
Serial.println(y_4);
Serial.println(y_5);
}
if (tirante2<0)
{
tirante2 = -9999.00;
Q2 = -9999.00;
}
else if (tirante2=0)
{
Q2 = 0.00;
}
else if ((tirante2>0) && (tirante2<=0.11))
{
float x1 = 4047.1*y_5;
float x2 = - 960.19*y_4;
float x3 = 80.27*y_3;
float x4 = 2.0888*pow(tirante2, 2.00);
float x5 = 0.0306*tirante2;
float a1 = - 0.00003;
Q2 = x1 + x2 + x3 + x4 + x5 + a1;
}
else if ((tirante2>0.11) && (tirante2<0.2))
{
float x1 = 28.294*pow(tirante2, 2.0);
float x2 = - 4.7767*(tirante2);
float a1 = 0.1907;
Q2 = x1 + x2 + a1;
}
else
{
float x1 = -4.5949*y_3;
float x2 = 13.727*pow(tirante2, 2.0);
float x3 = 2.2187*tirante2;
float a1 = - 0.6172;
Q2 = x1 + x2 + x3 + a1;
}
porcentajeQ = Q2*100.00/Qmax;
DateTime now = rtc.now();
ano = String(now.year());
mes = String(now.month());
dia = String(now.day());
horas = String(now.hour());
minutos = String(now.minute());
segundos = String(now.second());
Fecha = ano + "/" + mes + "/" + dia;
Hora = horas + ":" + minutos + ":" + segundos;
Nombrearchivo = ano + mes + dia + ".csv"; //nombre máximo de 8 caracteres
Imprimir = "EHA_3 ";
Imprimir += Fecha;
Imprimir += " ";
Imprimir += Hora;
Imprimir += " Tirante: ";
Imprimir += tirante2;
Imprimir += " m Gasto: ";
Imprimir += Q2;
Imprimir += " l/s Temperatura: ";
Imprimir += t2;
Imprimir += " °C Humedad: ";
Imprimir += h2;
Imprimir += " % dist_sensor: ";
Imprimir += d;
Imprimir += " cm Q%:";
Imprimir += porcentajeQ;
Imprimir += " %";
File dataFile = SD.open(Nombrearchivo, FILE_WRITE);
if (dataFile)
{ dataFile.println(Imprimir);
dataFile.close();
Serial.println(Imprimir);
}
else
{ Serial.println("Error al intentar escribir en el archivo!");
}
tirante = tirante2;
gasto = Q2;
humedad_atm = h2;
temperatura_atm = t2;
distancia = d;
ArduinoCloud.update();
delay(20000);
ArduinoCloud.update();
delay(20000);
}
This is what I get as a result in the Serial Monitor when using my program in the channel:
13:13:39.402 -> SD inicializada
13:13:41.484 -> 0.12
13:13:41.484 -> 0.00
13:13:41.484 -> 0.00
13:13:41.484 -> 0.00
13:13:41.603 -> EHA_3 2025/5/27 13:13:30 Tirante: 0.00 m Gasto: -0.63 l/s Temperatura: 34.30 °C Humedad: 43.00 % dist_sensor: 133.88 cm Q%:-6.48 %
For some reason my value in "tirante2" (and therefore, "tirante") gets automatically erased and it is equalled to zero although it did get a different value at the beggining. And I have changed the Pow() function to multiplying directly as:
y_3 = tirante2*tirante2*tirante2;
y_4 = tirante2*tirante2*tirante2*tirante2;
y_5 = tirante2*tirante2*tirante2*tirante2*tirante2;
But the problem remains the same, I get zero as a value.