Hi everyone,
I've an issue with my sketch and I want you please to show me the way to solve it. In my below sketch, want to have the average of Time01, Time02 and Time03 in T01 , then reset them to get new values and have the sum in T02 , but when printing T01 and T02 I always have 0. Any way to solve this issue ? Thank you in advance for the help
#include "esp_system.h"
#define Signal 34
volatile int Counter;
volatile uint64_t Time, TickTime, OldTime;
volatile uint8_t Merker;
uint64_t Time01, Time02, Time03;
float T01=0, T02=0, t01, t02;
float Rate, BE;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR What2Do()
{
portENTER_CRITICAL_ISR(&mux);
Time = esp_timer_get_time();
TickTime = Time - OldTime;
OldTime = Time;
Counter++;
Merker = 1;
portEXIT_CRITICAL_ISR(&mux);
}
void setup() {
Serial.begin(115200);
pinMode(Signal, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(Signal), What2Do, RISING);
}
void loop() {
if (Merker == 1){
if (Counter >= 11){
switch(Counter){
case 11:
Time01 = TickTime;
break;
case 12:
Time02 = TickTime;
break;
case 13:
Time03 = TickTime;
break;
}
}
}
if ( T01==0 && T02==0){
T01 = (Time01+Time02+Time03)/3.0;
Counter=0; Time01=0; Time02=0; Time03=0; Merker=0;
}
if ( T01 != 0 && T02 == 0){
T02 = (Time01+Time02+Time03);
Counter=0; Time01=0; Time02=0; Time03=0; Merker=0;
}
Serial.print("T01: ");
Serial.print(T01);
Serial.print(" ms | T02: ");
Serial.print(T02);
Serial.println(" s/24h");
}
Shouldn't you be resetting Merker after you detect Merker == 1 ?
if (Merker == 1){
if (Counter >= 11){
switch(Counter){
case 11:
Time01 = TickTime;
break;
case 12:
Time02 = TickTime;
break;
case 13:
Time03 = TickTime;
break;
}
}
}
If you are doing it here you may be missing an interrupt.
if ( T01==0 && T02==0){
T01 = (Time01+Time02+Time03)/3.0;
Counter=0; Time01=0; Time02=0; Time03=0; Merker=0;
}
if ( T01 != 0 && T02 == 0){
T02 = (Time01+Time02+Time03);
Counter=0; Time01=0; Time02=0; Time03=0; Merker=0;
}
The code is very confusing. How often does the Signal pin toggle?
b707
August 8, 2022, 10:52pm
3
Do not use strict equality for float, the condition (T01 == 0) will almost always be false, even if you assigned T01 =0 before it.
Are you sure that you need T01 and T02 float? as I seen the code, it can easily be integers
I like to learn little things, so can someone say this is true?
We can't even assign 0 to a float and expect it to be equal to 0?
# include <stdio.h>
int main()
{
printf("Hello, World!\n");
float f = 0;
if (f == 0.00) printf("never?");
return 0;
}
Prints "never?", at least the one place I've tried. When would that not happen? On what would it depend?
a7
@alto777 , you are correct.
If you assign a value to a float and next compare it with that value, the result will always be true.
As you more than likely know, it fails if one of the values of a comparison is a calculated value as below code demonstrates.
void setup() {
Serial.begin(57600);
while (!Serial) {}
Serial.println("starting");
float f = 1.497;
f -= 0.499;
f -= 0.499;
f -= 0.499;
if (f == 0.0)
{
Serial.println("OK");
}
else
{
Serial.println("Fail");
}
}
void loop()
{
}
b707
August 9, 2022, 6:58am
6
You are right, after assigning zero the expression will be true. But I think you agree that in general using a strict equality conditions with a float is bad practice.
THX.
TBH my questions were not rhetorical in nature. Nothing you could tell me about floating point woukd surprise me at this point.
a7
Why don't you try printing Time01, Time02, and Time03 to be sure they're doing what you think they're doing.
Also, if this is true (subject to the previous discussion)...
barbess:
if ( T01==0 && T02==0)
...and if Time01, 02, or 03 are nonzero, then T01 will become nonzero.
Then, immediately this will be true...
but because the first if statement reset Time01, 02, and 03, T02 will equal zero...
So something is screwy in your logic.
Also, if T01 ever does become nonzero, the first if statement will never be executed again, because you don't reset T01 to zero.
And why do you have upper and unused lowercase...
Also, with the ESPs does your main code need to protect reading multi-byte variables that could be modified by the ISR, like you do with AVRs?
Hi, this is what I've done now but still have 0 when printing.
#include "esp_system.h"
#define Signal 34
volatile int Counter;
volatile uint64_t Time, TickTime, OldTime;
volatile uint8_t Merker;
uint64_t Time01, Time02, Time03;
int t01=0, t02=0;
float T01, T02;
float Rate, BE;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR What2Do()
{
portENTER_CRITICAL_ISR(&mux);
Time = esp_timer_get_time();
TickTime = Time - OldTime;
OldTime = Time;
Counter++;
Merker = 1;
portEXIT_CRITICAL_ISR(&mux);
}
void setup() {
Serial.begin(115200);
pinMode(Signal, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(Signal), What2Do, RISING);
}
void loop() {
if (Merker == 1){
if (Counter >= 11){
switch(Counter){
case 11:
Time01 = TickTime;
break;
case 12:
Time02 = TickTime;
break;
case 13:
Time03 = TickTime;
break;
}
}
}
if ( t01==0 && t02==0){
t01 = (Time01+Time02+Time03);
Counter=0; Time01=0; Time02=0; Time03=0; Merker=0;
}
if ( t01 != 0 && t02 == 0){
t02 = (Time01+Time02+Time03);
Counter=0; Time01=0; Time02=0; Time03=0; Merker=0;
}
T01 = float(t01)/3.0;
T02 = float(t02)/5.0;
Serial.print("T01: ");
Serial.print(T01);
Serial.print(" ms | T02: ");
Serial.print(T02);
Serial.println(" s/24h");
}