digitalPinToGPIONumber is not a type error on Nano ESP32

LiquidCrystal_I2C.h (8.5 KB)
mpv6050_rollPitch_kickme_nano.ino (7.8 KB)

I am trying to build and flash the attached code to the Arduino Nano ESP32 (genuine). But I get following errors:

In file included from C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/Arduino.h:252,
                 from C:\Users\user\AppData\Local\Temp\arduino\sketches\58D546ED292D9575345F60D9573A36F7\sketch\mpv6050_rollPitch_kickme_nano.ino.cpp:1:
C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/io_pin_remap.h:47:57: error: 'digitalPinToGPIONumber' is not a type
   47 | #define pinMode(pin, mode)                      pinMode(digitalPinToGPIONumber(pin), mode)
      |                                                         ^~~~~~~~~~~~~~~~~~~~~~
C:\Users\user\OneDrive\Documents\Arduino\libraries\NewLiquidCrystal_lib/I2CIO.h:88:9: note: in expansion of macro 'pinMode'
   88 |    void pinMode ( uint8_t pin, uint8_t dir );
      |         ^~~~~~~
C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/io_pin_remap.h:42:61: error: 'digitalPinToGPIONumber' is not a type
   42 | #define digitalRead(pin)                        digitalRead(digitalPinToGPIONumber(pin))
      |                                                             ^~~~~~~~~~~~~~~~~~~~~~
C:\Users\user\OneDrive\Documents\Arduino\libraries\NewLiquidCrystal_lib/I2CIO.h:123:12: note: in expansion of macro 'digitalRead'
  123 |    uint8_t digitalRead ( uint8_t pin );
      |            ^~~~~~~~~~~
C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/io_pin_remap.h:46:62: error: 'digitalPinToGPIONumber' is not a type
   46 | #define digitalWrite(pin, val)                  digitalWrite(digitalPinToGPIONumber(pin), val)
      |                                                              ^~~~~~~~~~~~~~~~~~~~~~
C:\Users\user\OneDrive\Documents\Arduino\libraries\NewLiquidCrystal_lib/I2CIO.h:151:8: note: in expansion of macro 'digitalWrite'
  151 |    int digitalWrite ( uint8_t pin, uint8_t level );
      |        ^~~~~~~~~~~~

exit status 1

Compilation error: exit status 1

Here is the code:

// This code starts a 5 sec timer as soon as Arduino starts
// After 5 sec, randomly within next 5 sec the light illuminates
// if the Accelerometer detects jerk greater than threshold
// Time difference between light on time and jerk exceed time 
// is recorded and displayed on the LCD screen

// Include Wire Library for I2C
#include <Wire.h>
// Include NewLiquidCrystal Library for I2C
#include <LiquidCrystal_I2C.h>
#define HAVELEDS
// Define LCD pinout
const int  en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;
 
// Define I2C Address - change if reqiuired
const int i2c_addr = 0x27;
 
LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

// Level LEDs
#ifdef HAVELEDS
int ledPin = 11;
#endif

//Variables for Gyroscope
int gyro_x, gyro_y, gyro_z;
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
boolean set_gyro_angles;

long acc_x, acc_y, acc_z, acc_v;
float angle_roll_acc, angle_pitch_acc;

float angle_pitch, angle_roll;
int angle_pitch_buffer, angle_roll_buffer;
float angle_pitch_output, angle_roll_output;

// Setup timers and temp variables
long loop_timer;
int temp;

// Display counter
int displaycount = 0;
unsigned long startTime;
bool ledOn = false;
bool jerkDetected = false;
float prevAx, prevAy, prevAz, prevAv;
const float jerkThreshold = 1.0; // Tunable variable for jerk threshold
bool loopcompleted = false;

void setup() {

  //Start I2C
  Wire.begin();
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // Set display type as 16 char, 2 rows
  lcd.begin(16,2); 

  //Setup the registers of the MPU-6050                                                       
  setup_mpu_6050_registers(); 
  
  // Start Serial Monitor                                                 
  Serial.begin(115200);
  
  // Init Timer 
  loop_timer = micros();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Readyyyyy!!!");          
  delay(3000); // Wait 5 seconds before turning on the LED
  digitalWrite(ledPin, LOW);
  ledOn = true;
  read_mpu_6050_data();
  prevAx = acc_x;
  prevAy = acc_y;
  prevAz = acc_z;
  acc_v = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z)); 
  prevAv = acc_v;
  randomSeed(analogRead(0));
  startTime = millis();

}

void loop(){

  while (!loopcompleted) {
    for(int i=0;i<1000;i++) {
        startTime = millis();
        read_mpu_6050_data();
        float jerkX = (acc_x - prevAx) / ((millis() - startTime) * 1000);
        float jerkY = (acc_y - prevAy) / ((millis() - startTime) * 1000);
        float jerkZ = (acc_z - prevAz) / ((millis() - startTime) * 1000);
        acc_v = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));
        float jerkV = (acc_v - prevAv) / (millis() - startTime) * 1000;
        
        //Serial.print(abs(jerkX)); Serial.print("\t");
        //Serial.print(abs(jerkY)); Serial.print("\t");
        //Serial.print(abs(jerkZ)); Serial.print("\t");
        //Serial.print(abs(jerkV)); Serial.print("\t");
        //Serial.print("\n");

        prevAv = acc_v;
        prevAx = acc_x;
        prevAy = acc_y;
        prevAz = acc_z;
    }
    Serial.print("I am here");
    startTime = millis();
    float jerkV_avg=0;
    int jerkv_avg_track = 0;
    

    long randomDelay = random(2000, 10001);
    Serial.print("random wait:"); Serial.print("\t");
    Serial.print(randomDelay); Serial.print("\n");
    unsigned long startTime = millis();
    while (millis() - startTime < randomDelay) {
      // Do nothing, just wait
    }
    float startTimefight = millis();
    digitalWrite(ledPin, HIGH);

    while (ledOn && !jerkDetected) {
        startTime = millis();
        read_mpu_6050_data();
        float jerkX = (acc_x - prevAx) / ((millis() - startTime) * 1000);
        float jerkY = (acc_y - prevAy) / ((millis() - startTime) * 1000);
        float jerkZ = (acc_z - prevAz) / ((millis() - startTime) * 1000);
        acc_v = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));
        float jerkV = (acc_v - prevAv) / ((millis() - startTime) * 1000);
        
        //Serial.print(abs(jerkX)); Serial.print("\t");
        //Serial.print(abs(jerkY)); Serial.print("\t");
        //Serial.print(abs(jerkZ)); Serial.print("\t");
  
        prevAv = acc_v;
        prevAx = acc_x;
        prevAy = acc_y;
        prevAz = acc_z;
      
        jerkV_avg = (jerkV + jerkV_avg) / 2;
        jerkv_avg_track = jerkv_avg_track + 1;
        //if(jerkv_avg_track > 100) {
        //  jerkv_avg_track=0;
        //}
        //Serial.print(abs(jerkV_avg)); Serial.print("\t"); Serial.print("\n");
      //if (abs(jerkX) > jerkThreshold || abs(jerkY) > jerkThreshold || abs(jerkZ) > jerkThreshold) {
      if(abs(jerkV_avg) > jerkThreshold) {
        Serial.print("Jerk exceeded:"); Serial.print("\t"); 
        Serial.print(abs(jerkZ)); Serial.print("\t");
        unsigned long elapsedTime = millis() - startTimefight;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Reaction Time:");
        lcd.setCursor(0, 1);
        lcd.print(elapsedTime / 1000.0, 5); // Display in seconds
        Serial.print("Reaction time:"); Serial.print("\t"); Serial.print(elapsedTime / 1000.0);
        Serial.print("\n");

        jerkDetected = true;
        ledOn = false;
        loopcompleted=true;
      }
    }
  }
  digitalWrite(ledPin, LOW);
}
void setup_mpu_6050_registers(){

  //Activate the MPU-6050
  
  //Start communicating with the MPU-6050
  Wire.beginTransmission(0x68); 
  //Send the requested starting register                                       
  Wire.write(0x6B);  
  //Set the requested starting register                                                  
  Wire.write(0x00);
  //End the transmission                                                    
  Wire.endTransmission(); 
                                              
  //Configure the accelerometer (+/-8g)
  
  //Start communicating with the MPU-6050
  Wire.beginTransmission(0x68); 
  //Send the requested starting register                                       
  Wire.write(0x1C);   
  //Set the requested starting register                                                 
  Wire.write(0x10); 
  //End the transmission                                                   
  Wire.endTransmission(); 
                                              
  //Configure the gyro (500dps full scale)
  
  //Start communicating with the MPU-6050
  Wire.beginTransmission(0x68);
  //Send the requested starting register                                        
  Wire.write(0x1B);
  //Set the requested starting register                                                    
  Wire.write(0x08); 
  //End the transmission                                                  
  Wire.endTransmission(); 
                                              
}


void read_mpu_6050_data(){ 

  //Read the raw gyro and accelerometer data

  //Start communicating with the MPU-6050                                          
  Wire.beginTransmission(0x68);  
  //Send the requested starting register                                      
  Wire.write(0x3B);
  //End the transmission                                                    
  Wire.endTransmission(); 
  //Request 14 bytes from the MPU-6050                                  
  Wire.requestFrom(0x68,14);    
  //Wait until all the bytes are received                                       
  while(Wire.available() < 14);
  
  //Following statements left shift 8 bits, then bitwise OR.  
  //Turns two 8-bit values into one 16-bit value                                       
  acc_x = Wire.read()<<8|Wire.read();                                  
  acc_y = Wire.read()<<8|Wire.read();                                  
  acc_z = Wire.read()<<8|Wire.read();                                  
  temp = Wire.read()<<8|Wire.read();                                   
  gyro_x = Wire.read()<<8|Wire.read();                                 
  gyro_y = Wire.read()<<8|Wire.read();                                 
  gyro_z = Wire.read()<<8|Wire.read();                                 
}

I dont get this error when I am trying to build for Mega 2560. Any ideas?

did you pick the right board in the IDE ?

it's in the core

Which board have you got selected in the IDE ?

Please post your code here, using code tags when you do, to avoid the need to download it

Yes, I just checked that by flashing the Blink code.

Edited original post to include code.

Thank you

It looks like you have selected the esp32 instead of the Arduino

This is what you should see, pick the first one.

The Nano ESP32 had to make some compromises to make two competing pin numbering views happy. You can read this article and this post for more information, but TLDR is, please also use the following tips in your sketch and IDE:

  • ALWAYS use pin labels, such as D12, in your sketch. You can't be wrong!

This means that you have to change in your sketch the lines:

const int  en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;
int ledPin = 11;

to

const int en = D2, rw = D1, rs = D0, d4 = D4, d5 = D5, d6 = D6, d7 = D7, bl = D3;
int ledPin = D11;

(and anywhere else, if I missed any pin reference).

  • Since you use libraries, select "by GPIO Number" in the "Tools" > "Pin Numbering" menu of the IDE to avoid issues. This is most likely what is causing your error, but it needs the above patch for the sketch to work properly.

Hope this helps!

“You can’t be wrong”?!

I’ve wasted a considerable amount of time trying to get my Xiao ESP32C3 to output properly using the PIN numbers (eg D2). It only worked when I used the GPIO number.

There is no pin numbering option in the IDE.

So while my numbering may have “been wrong” by the books, it was the only way I could get my Xiao to work.

That is not a Nano ESP32, hence

1 Like

So the bolded instructions ONLY apply to using the Nano ESP32, and none of the other ESP32-type boards. Gotcha.

This solution worked. I was able to compile the code. Though to flash the Nano ESP32. I have to follow a roundabout way as per my other forum entry here

1 Like

It's only there if the board supports the option, so far I am only aware of the one.

1 Like

So I could build and most of the code works as intended. I can see (using I2C scanner) that there are two devices on the I2C (0x68 for the IMU and 0x27) for the LCD. But the LCD screen doesnt show any output. The fact that the I2C scanner is detecting the LCD, the 0x27 for the ic2_addr variable is correct. For Nano ESP32 to work with LCDs do I have to do something special? (BTW Same code with Arduino Mega 2560 works fine).