Arduino using ESP32

Arduino Version: 2.1.1
CLI Version: 0.32.3
Custom Board with:ESP32 WROOM-32 Wifi Board

First tests using the ESP32.
Simple test code below.
If I place a digitalRead(GPIO17); -- or a digitalWrite
before the if (x >= 2000L) the code works
If I don't do the digital read or write,
then the (x >= 2000L) always evaluates as true
and toggles GPIO4 very quickly
Any idea what is happening?
Thanks

#define GPIO4 4
#define GPIO2 2
#define GPIO17 17

#define NOP __asm__ __volatile__("nop\n\t")
void setup() {
  Serial.begin(9600);
  pinMode(GPIO4, OUTPUT);
  pinMode(GPIO2, OUTPUT);
  pinMode(GPIO17, INPUT);
}

void loop() {
  long x = 0L;
  char VAL = 0;
  Serial.println("\n\rReady>\n\r");
 
  while (1) {
    x++;
    // digitalWrite(GPIO2,VAL);
    digitalRead(GPIO17); // if add this line process if (x >=...) properly
    if (x >= 2000L)  // for some reason acts as always true-if no digitalRead or digitalWrite before it
    {
      x = 0L;
      VAL = !VAL;
      digitalWrite(GPIO4, VAL);
    }  // end of if (x)
  }    // end of while
}  // end of loop()

digitalWrite wants HIGH or LOW

Make VAL type bool

More correctly,

VAL = !VAL;
if( VAL == true)
digitalWrite(GPIO4, HIGH);
else
digitalWrite(GPIO4, LOW);

2000L
Since there are no delays, counting to 2000 will happen very fast.

1 Like

Hi,
I found if I put volatile in front of the:

long x=0L;

to be:

volatile long x=0L;

it works properly

Also the digitalWite works fine with the VAL in lieu LOW and HIGH

Thanks for your time, much appreciated.

It does but it’s a freak of the compiler, suggest you avoid short cuts and use HIGH/LOW as the digitalWrite function is written for.

.

1 Like

What is connected to this pin so that you can conclude that it is working (or not) ?
Adding a digitalRead() or digitalWrite() or making a variable volatile will add a short pause in your while() loop. 2000 loop iterations will happen very quickly so you'll need a scope or logic analyser to see anything.

I had a scope on the GPIO output pin so I could see the toggling of the output.

The difference between 2000 and 4000 is very easy to see (it halves the image on the scope). I had tried numbers like 4000000L and had the same problem.

I've found, without the volatile, the optimization allows very quick processing (using the value from the accumulator -a compiler optimization, not a regular memory fetch)

If you do something which is undefined, the compiler can simply and silently generate rubbish. Here is a recent example: Odd code behaviour, just FYA

As has already been pointed out, this is odd looking in that it is a logical NOT operation on a signed number. I could guess this may cause odd behaviour.

char VAL = 0;
. . .
VAL = !VAL;

I will be very surprised to learn that there is anything wrong with these lines of code:

char VAL = 0;
// . . .
VAL = !VAL;

0 (zero) is false, not 0 is true, I would expect VAL to take on the value of 1 or true after the assignment.

I have seen cleansing code like

    VAL = !!VAL;

that's two not operators and will leave VAL as 0 or 1, true or false same as it was logically but "corrected" for non-zero means true.

With the GDB online compiler, tests compile without warning and produce the expected results.

a7

Indeed, you will not be surprised. It seems this is a relic from C and is OK according to this: Can I use the not operator in C++ on int values? - Stack Overflow

THX. I am a relic from C myself. :expressionless:

a7

1 Like

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