I'm having difficulty getting DigitalWrite to behave as expected on an ESP32 board (behaviour confirmed on several different ESP32 boards).
Arduino IDE : version 2.0.3 (On OS X)
Date : 2022-12-05T09....
CLI Version : 0.29.0
The issue is as follows : I set digitalWrite to HIGH in my code, and the test case which involves querying the output register AND using an LED on said both appear to confirm the output is LOW.
The output I get is as follow:
19:02:15.292 -> Moving Forward
19:02:20.303 -> 1
19:02:20.303 -> Motor stopped
19:02:20.303 -> Pin state is 0
Code :
#include "esp_system.h"
#include "Arduino.h"
#include <wiring_private.h>
int period = 5000;
unsigned long time_trig = 0;
unsigned long currentTime = 0;
int state_machine = 0;
int pin_state;
// Motor A
#define motorAPin1 16
#define motorAPin2 19
// Motor B
#define motorBPin1 25
#define motorBPin2 26
void setup() {
// sets the pins as outputs:
pinMode(motorAPin1, OUTPUT);
pinMode(motorAPin2, OUTPUT);
pinMode(motorBPin1, OUTPUT);
pinMode(motorBPin2, OUTPUT);
Serial.begin(115200);
Serial.print("Testing DC Motor...");
}
void loop() {
while(millis() > (time_trig + period)){
Serial.println(state_machine);
state_machine++;
switch (state_machine) {
case 1:
Serial.println("Moving Forward");
digitalWrite(motorAPin1, 1);
digitalWrite(motorAPin2, 0);
digitalWrite(motorBPin1, 1);
digitalWrite(motorBPin2, 0);
break;
case 2:
Serial.println("Motor stopped");
digitalWrite(motorAPin1, 1);
digitalWrite(motorAPin2, 1);
digitalWrite(motorBPin1, 1);
digitalWrite(motorBPin2, 1);
pin_state = digitalReadOutputPin(motorAPin1);
Serial.print("Pin state is ");
Serial.print(pin_state);
Serial.println();
break;
case 3:
Serial.println("Motor backwards");
digitalWrite(motorAPin1, 0);
digitalWrite(motorAPin2, 1);
digitalWrite(motorBPin1, 0);
digitalWrite(motorBPin2, 1);
break;
case 4:
Serial.println("Motor FULL STOP");
digitalWrite(motorAPin1, 0);
digitalWrite(motorAPin2, 0);
digitalWrite(motorBPin1, 0);
digitalWrite(motorBPin2, 0);
break;
} //end of state_machine SWITCH
if(state_machine>=5){
state_machine = 0;
}
time_trig = millis();
} //end of while_millis
} //end of main_loop
int digitalReadOutputPin(uint8_t pin)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN)
return LOW;
return (*portOutputRegister(port) & bit) ? HIGH : LOW;
}
I looked for anyone having similar issues to no avail.
Expected behavior: setting a digital output to high results in the output in question remaining high for 5 seconds, with LED to confirm.
Result : output is low, testcase shows as low, led confirms output low.
It's for a L298n motor driver, but the behavior was not as expected with digitalWrite so I reverted to checking with LEDs connected in lieu of the motor driver board.
That'd be fine if this were an AVR, but you said ESP32, and it's GPIO structure is quite different, with digitalWrite() calling gpio_set_level(), which calls gpio_hal_set_level(), and then gpio_ll_set_level() (some of those are macros or inline functions, but it's ... not pretty.)
uint8_t bit = digitalPinToBitMask(pin);
I don't know whether the various digitalPinToXxx macros do reasonable things on an ESP32 or not, but you'd need to at least take into account that the ESP32 IO ports (and thus bitmasks) are 32bits, rather than 8.
#include "esp_system.h"
#include "Arduino.h"
int period = 10000;
unsigned long time_trig = 0;
unsigned long currentTime = 0;
int state_machine = 0;
int pin_state;
// Motor A
#define motorAPin1 13
#define motorAPin2 12
// Motor B
#define motorBPin1 25
#define motorBPin2 26
void setup() {
// sets the pins as outputs:
pinMode(motorAPin1, OUTPUT);
pinMode(motorAPin2, OUTPUT);
pinMode(motorBPin1, OUTPUT);
pinMode(motorBPin2, OUTPUT);
Serial.begin(115200);
Serial.print("Testing DC Motor...");
}
void loop() {
while(millis() > (time_trig + period)){
state_machine++;
if(state_machine>=5){
state_machine = 1;
}
Serial.print("State machine is :");
Serial.print(state_machine);
switch (state_machine) {
case 1:
Serial.print(" -- Moving Forward\n");
digitalWrite(motorAPin1, 1);
digitalWrite(motorAPin2, 0);
digitalWrite(motorBPin1, 1);
digitalWrite(motorBPin2, 0);
pin_state = digitalRead(motorAPin1);
Serial.print("PinA1 state is ");
Serial.print(pin_state);
Serial.print(" versus 1 expected.\n");
break;
case 2:
Serial.print(" -- Motor stopped\n");
digitalWrite(motorAPin1, 1);
digitalWrite(motorAPin2, 1);
digitalWrite(motorBPin1, 1);
digitalWrite(motorBPin2, 1);
pin_state = digitalRead(motorAPin1);
Serial.print("PinA1 state is ");
Serial.print(pin_state);
Serial.print(" versus 1 expected.\n");
break;
case 3:
Serial.print(" -- Motor backwards\n");
digitalWrite(motorAPin1, 0);
digitalWrite(motorAPin2, 1);
digitalWrite(motorBPin1, 0);
digitalWrite(motorBPin2, 1);
pin_state = digitalRead(motorAPin1);
Serial.print("PinA1 state is ");
Serial.print(pin_state);
Serial.print(" versus 0 expected.\n");
break;
case 4:
Serial.print(" -- Motor FULL STOP\n");
digitalWrite(motorAPin1, 0);
digitalWrite(motorAPin2, 0);
digitalWrite(motorBPin1, 0);
digitalWrite(motorBPin2, 0);
pin_state = digitalRead(motorAPin1);
Serial.print("PinA1 state is ");
Serial.print(pin_state);
Serial.print(" versus 0 expected.\n");
break;
} //end of state_machine SWITCH
time_trig = millis();
} //end of while_millis
} //end of main_loop
Output of the code is :
Testing DC Motor...State machine is :1 -- Moving Forward PinA1 state is 1 versus 1 expected. State machine is :2 -- Motor stopped PinA1 state is 1 versus 1 expected. State machine is :3 -- Motor backwards PinA1 state is 0 versus 0 expected. State machine is :4 -- Motor FULL STOP PinA1 state is 0 versus 0 expected.
==> LED now tracks as predicted on all outputs. Now to connect to L298N and the real fun begins