Strange Abort Error

Hi all!

I built an e-scooter a while back (DIY Arduino (FireBeetle) E-Scooter - Hackster.io) and it worked great! But then my motor driver broke, and I had to get a new motor, etc; anyways, it hasn't been working for about a month, and I had ended up changing my code right after I uploaded last time.

My last version works perfectly (https://github.com/Kgray44/DIY_Arduino_E-Scooter/tree/main/diy_e-scooter_cloud_v5) but Im getting an abort error for my code rn! I have never seen an error like it, and can't figure out how to fix it.

My error is:

E (33) gpio: G
abort() was called at PC 0x4008561b on core 1
Backtrace: 0x40084119:0x3ffc5840 0x40088e39:0x3ffc5860 0x4008df75:0x3ffc5880 0x4008561b:0x3ffc5900 0x40085765:0x3ffc5930 0x400e14c8:0x3ffc5950 0x400d892e:0x3ffc5990 0x400d8830:0x3ffc59e0 0x400d3cb1:0x3ffc5a00 0x400dd3a7:0x3ffc5a30

ELF file SHA256: 0f9876c112080128
Rebooting...

Here is my code:

#include "DFRobot_GDL.h"
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
#include "DFRobot_GNSS.h"
#include "DFRobot_BMI160.h"
#include "DFRobot_AHT20.h"
#include "DFRobot_GR10_30.h"
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>
#include "settings.h"

//Testing
bool testing = false;

//Voltage Conversion for Speed
bool voltconversion = false;

// PWM properties for motor driver
const int freq = 5000;
const int speedChannel = 0;
const int resolution = 8;

//throttle
int throttleoffvalue = 0;
int throttleonvalue = 4095;
int throttleval = 0;
int lastthrottleval = 0;

//Touch coordinates for calibration
#define touchxmin 290
#define touchxmax 3750
#define touchymin 300
#define touchymax 3700
#define backcolor COLOR_RGB565_WHITE
#define erasecolor backcolor//COLOR_RGB565_LGRAY
#define backgroundcolor COLOR_RGB565_CYAN

//gnss / display
long readgnssinc = 1000;//time between GNSS readings
unsigned long lastreadgnss = 0;
long readdisplayinc = 1000;//time between display updates
unsigned long lastdisplay = 0;
sTim_t utc;
sTim_t date;
sLonLat_t latitude;
sLonLat_t longitude;
double altitude;
uint8_t satelites;
double knots;
double course;

//AHT20
float temperature = 0;
float humidity = 0;
float HI = 0;

//WS2812
#define NUMPIXELS 14
float lastcoursereading = 0;
float coursechangetime = 1000;
float lastcoursereadtime = 0;
float courseturnsignalinc = 10; //degrees of turning for turning signal to turn on
float coursechange = 0;
float lastspeedreading = 0;
float speedchangetime = 1000;
float lastspeedreadtime = 0;
float speedbrakeinc = -0.08;//decrease in speed before brake light turns on
int brake[] = {5,6,7,8,9};
int footlight[] = {10,11,12,13};
unsigned long startmillis = 0;
int animationcountleft = 1;
int animationcountright = 1;
bool leftturnsignal = false;
bool rightturnsignal = false;
float speeddiferrence = 0;
bool headlight = false;
int panimationcount = 0;
bool pup = true;
bool ledsoff = false;

//Password
bool locked = false;//true
uint16_t gestures;
int passwordlength = 3;
#define EEPROM_SIZE passwordlength
int passc = 0;//pass count

//battery
float batteryvolts = 0;
int batteryreadings = 10;//number of readings to average, more for a smoother more reliable response
long readbatteryint = 20;//time in milliseconds between battery readings
unsigned long lastbatreading = 0;
long R1 = 15000;//15k ohms
long R2 = 1000;//1.1k ohms
int curbatread = 0;
int batsum = 0;
#define batteryamps 5
#define batteryvoltage 36 //voltage and amp hours of battery, or uncomment "batterywattage" below instead
//#define batterywattage 180
#define motorwattage 350
#define maxcruisespeed 15 //mph //20

//gyro
float lastgyroreading = 0;
float readgyroint = 1;
float curgyroread = 0;
float gyroreadings = 5;
float gyrosum = 0;
float gyroy = 0;

//current sensor
int currentreadings = 10;//number of readings to average, more for a smoother more reliable response
long readcurrentint = 20;//time in milliseconds between battery readings
unsigned long lastcurreading = 0;
int curcurread = 0;
int cursum = 0;
float current = 0;                // the average
float watts = 0;

bool lastebrakeon = false;
unsigned long lastebrakechange = 0;
bool ebrakeon = false;
bool lockbtnon = false;
bool lastcruiseon = false;
unsigned long lastcruisechange = 0;
bool cruiseon = false;
float cruisesetspeed = 0;
int motorvalue = 0;

int previousotherx1 = 0;
int previousothery1 = 0;
int previousotherx2 = 0;
int previousothery2 = 0;

bool stole = false;
float speedlimit = 0.00;
bool lastturnstat = false;

XPT2046_Touchscreen ts(TOUCH_CS);
DFRobot_ILI9341_240x320_HW_SPI screen(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);
DFRobot_GNSS_I2C gnss(&Wire,GNSS_DEVICE_ADDR);
DFRobot_BMI160 bmi160;
const int8_t i2c_addr = 0x69;
DFRobot_AHT20 aht20;
DFRobot_GR10_30 gr10_30(/*addr = */GR10_30_DEVICE_ADDR, /*pWire = */&Wire);
Adafruit_NeoPixel pixels(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
//WiFiMulti wifiMulti;

//BMI160
struct dat{
  float x = 0;
  float y = 0;
  float z = 0;
};
dat accel;
struct data{
  float x = 0;
  float y = 0;
  float z = 0;
};
data gyro;
float baseyangle = 0;

void setup() {
  pinMode(speedpin, OUTPUT);
  pinMode(27, INPUT_PULLUP);
  pinMode(cruisepin, OUTPUT);
  digitalWrite(cruisepin, LOW);

  if (voltconversion){
    digitalWrite(speedpin, HIGH);
  }
  else {
    digitalWrite(speedpin, LOW);
  }
  
  Serial.begin(115200);

  pixels.begin();
  pixels.clear();
  pixels.show();

  for (int i=0;i<4;i++){
    pixels.setPixelColor(footlight[i], pixels.Color(255,255,0));
    pixels.show();
  }

  screen.begin();
  screen.setRotation(3);

  //pinMode(rpmpin, INPUT);

  EEPROM.begin(EEPROM_SIZE);
  for (int i=0;i<passwordlength;i++){//read password from EEPROM
    password[i] = EEPROM.read(i);    
  }
  
  pinMode(batterypin, INPUT);
  pinMode(throttlepin, INPUT);
  pinMode(brakepin, OUTPUT);
  //pinMode(rpmpin, INPUT);
  //attachInterrupt(rpmpin, interruptRoutine, FALLING);
  ledcSetup(speedChannel, freq, resolution);
  ledcAttachPin(speedpin, speedChannel);
  ledcWrite(speedChannel, 0);

  if(!gnss.begin()){
    Serial.println("NO GPS device !");
    delay(1000);
  }

  gnss.enablePower();
  gnss.setGnss(eGPS_BeiDou_GLONASS);
  gnss.setRgbOn();

  if (bmi160.softReset() != BMI160_OK){
    Serial.println("bmi160 reset false");
    //while(1);
  }
  if (bmi160.I2cInit(i2c_addr) != BMI160_OK){
    Serial.println("bmi160 init false");
    //while(1);
  }
  readAccelGyro();
  baseyangle = gyro.y;
  //baseyangle = 20;

  uint8_t status;
  if((status = aht20.begin()) != 0){
    Serial.print("AHT20 sensor initialization failed. error status : ");
    Serial.println(status);
    delay(1000);
  }
  
  startGestureSensor();
  ts.begin();
  ts.setRotation(3);
  
  startDisplay();

}

void loop() {
  if ((millis() - lastreadgnss) > readgnssinc){
    readGNSS();
    lastreadgnss = millis();
  }
  if (!ledsoff){
    handleLeds();
  }
  else {
    pixels.clear();
    pixels.show();  
  }
  if (locked){
    lockedloop();
    if (satelites > 8){
      if (knots > 2){
        //ifttt_counter++;
      }
    }
    return;
  }
  if (ts.touched()){
    TS_Point p = ts.getPoint();
    handleTouch(abs(map(p.x,touchxmax,touchxmin,0,320)),abs(map(p.y,touchymax,touchymin,0,240)));
  }
  readAccelGyro();
  readGyro();
  readTempHum();
  readCurrent();
  readBattery();
  readThrottle();
  if (!rightturnsignal && !leftturnsignal){
    if (lastturnstat){
      startDisplay();
      lastturnstat = false;
    }
    if (((millis() - lastdisplay) > readdisplayinc) && (satelites != 0)){
      handleSlowDisplay();
      lastdisplay = millis();
    }
    handleFastDisplay();
    handleDisplayButtons();
    float handleAngleLineValue = (baseyangle*100) - (gyroy*100);
    handleAngleLine(handleAngleLineValue);
  }
  else {
    if (rightturnsignal){
      screen.fillRoundRect(15,38,290,195,12,backgroundcolor);
      screen.setTextSize(14);
      screen.setCursor(100,75);
      screen.setTextColor(COLOR_RGB565_RED);
      screen.print(">");
    }
    else if (leftturnsignal){
      screen.fillRoundRect(15,38,290,195,12,backgroundcolor);
      screen.setTextSize(14);
      screen.setCursor(100,75);
      screen.setTextColor(COLOR_RGB565_RED);
      screen.print("<");
    }
  }
  handleGestures();
  handleMotordriver();
  //handleSpeedLimit();
}

/*void onLockChange()  {
  if (lock == true){
    screen.fillRoundRect(15,50,80,50,12,backgroundcolor);
    screen.setTextSize(2);
    screen.setCursor(20,70);
    screen.setTextColor(COLOR_RGB565_RED);
    screen.print("Locked");
    screen.fillRoundRect(225,50,80,50,12,backgroundcolor);
    screen.setTextSize(2);
    screen.setCursor(235,70);
    screen.setTextColor(COLOR_RGB565_GREEN);
    screen.print("E ON");
    ebrakeon = true;
    locked = true;
  }
  if (lock == false){
    ebrakeon = false;
    locked = false;
  }
}*/

/*void onMaxspeedChange()  {
  speedlimit = maxspeed;
}

void handleSpeedLimit(){
  if (knots > speedlimit){
    throttleval = throttleval/2;
  }
}*/

void handleTouch(int x,int y){
  Serial.print("Touch X = " + String(x));
  Serial.println(" | Touch Y = " + String(y));

  if (x >= 215 && x <= 320){
    if (y < 45){
      changepassword();
    }
    else if (y >= 45 && y <= 104){
      if ((millis() - lastebrakechange) > 400){//wait 1 second between reading button as pressed
        if (knots < 5){
          ebrakeon = !ebrakeon;
          lastebrakechange = millis();
        }
      }
    }  
    else if (y >= 105 && y <= 160){
      if ((millis() - lastcruisechange) > 400){//wait 1 second between reading button as pressed
        cruiseon = !cruiseon;
        cruisesetspeed = knots;
        lastcruisechange = millis();
      }
    }  
  }
  else if (x >= 5 && x <= 105){
    if (y < 45){
      changepassword();
    }
    else if (y >= 45 && y <= 105){
      if (!lockbtnon){
        lockbtnon = true;
      }
      else {
        screen.setTextSize(2);
        screen.setCursor(15,115);
        screen.setTextColor(COLOR_RGB565_RED);
        screen.print("Unlock with gestures!");//display unlock warning
        delay(3000);
        screen.fillRect(14, 114, 290, 20, erasecolor);//erase display unlock warning
      }
    }
  }
}

void handleSlowDisplay(){
  //satelites
  screen.setTextSize(2);
  screen.setCursor(287,15);
  screen.fillRect(286, 13, 26, 18, erasecolor);//backcolor
  if (satelites <= 5){
    screen.setTextColor(COLOR_RGB565_RED);
  }
  else if (satelites > 5 && satelites <= 8){
    screen.setTextColor(COLOR_RGB565_ORANGE);
  }
  else if (satelites > 8){
    screen.setTextColor(COLOR_RGB565_GREEN);
  }
  screen.print(String(satelites));
  //Serial.println(satelites);

  //speed (knots)
  screen.setTextSize(4);
  if (knots >= 10){
    screen.setCursor(100,62);//118,62
    screen.fillRect(92, 58, 132, 37, erasecolor);//117, 57, 90, 30,
  }
  else {
    screen.setCursor(110,62);//118,62
    screen.fillRect(100, 58, 105, 37, erasecolor);//117, 57, 90, 30,
  }
  if (knots <= 1.00){
    screen.setTextColor(COLOR_RGB565_BLUE);
  }
  else if (knots > 1.00 && knots <= 12.00){
    screen.setTextColor(COLOR_RGB565_GREEN);
  }
  else if (knots > 12.00 && knots <= 19.00){
    screen.setTextColor(COLOR_RGB565_ORANGE);
  }
  else {
    screen.setTextColor(COLOR_RGB565_RED);
  }
  screen.print(knots);
  //if (knots >= cruisesetspeed+4.00){//reset cruise if current speed goes above cruisesetspeed + 4
  //  cruiseon = false;
  //}
  
  //temperature
  screen.setTextSize(2);
  screen.setCursor(12,215);
  screen.fillRect(11,214,55,17,erasecolor);
  screen.setTextColor(COLOR_RGB565_GREEN);
  screen.print(temperature,1);//temperature with only one decimal
  screen.drawCircle(64,209,2,COLOR_RGB565_GREEN);//degrees symbol

  //humidity
  screen.setTextSize(2);
  screen.setCursor(270,215);
  screen.fillRect(269,214,40,17,erasecolor);
  screen.setTextColor(COLOR_RGB565_GREEN);
  screen.print(humidity,0);//humidity with no decimals
  screen.print("%");//percentage symbol
  
  //battery
  screen.setTextSize(2);
  screen.setCursor(140,215);
  screen.fillRect(139,214,65,17,erasecolor);
  float batpercent = map(batteryvolts*10,300,420,0,100); //map battery voltage to a percentage value of 0 - 100
  batpercent = constrain(batpercent,0,100);
  if (batpercent > 80.0){
    screen.setTextColor(COLOR_RGB565_GREEN);
  }
  else if (batpercent <= 80.0 && batpercent > 50.0){
    screen.setTextColor(COLOR_RGB565_DGREEN);
  }
  else if (batpercent <= 50.0 && batpercent > 25.0){
    screen.setTextColor(COLOR_RGB565_YELLOW);
  }
  else if (batpercent <= 25.0 && batpercent > 12.0){
    screen.setTextColor(COLOR_RGB565_ORANGE);
  }
  else if (batpercent <= 12.0 && batpercent > 5.0){
    screen.setTextColor(COLOR_RGB565_RED);
  }
  else {
    screen.setTextColor(COLOR_RGB565_RED);
    batterywarning();
  }
  screen.print(batpercent,0);//battery percentage with no decimals
  screen.print("%");//percentage symbol

  //dist to empty; for 36V 5AH (180W) that would be (at 20mph) 8 miles or 0.4 hours
  float batwatts = 0;
  #ifdef batterywattage
    batwatts = batterywattage;
  #else
    batwatts = batteryvoltage * batteryamps;
  #endif
  float bathours = batwatts / motorwattage;
  float batmiles = maxcruisespeed * bathours;
  float batmilesleft = map(batteryvolts*10,300,420,0,batmiles*100);//map function cant map floating values
  batmilesleft = batmilesleft / 100;
  float bathoursleft = map(batteryvolts*10,300,420,0,bathours*100);//map function cant map floating values
  bathoursleft = bathoursleft / 100;
  float batminutesleft = map(bathoursleft*100,0,100,0,600);//map function cant map floating values
  batminutesleft = batminutesleft / 10;
  screen.setTextSize(3);
  screen.setCursor(75,187);
  screen.fillRect(74,186,198,24,erasecolor);
  screen.setTextColor(COLOR_RGB565_BLUE);
  screen.print(abs(batmilesleft),1);//miles with no decimals
  screen.print("m|");//miles symbol
  screen.print(abs(batminutesleft),1);//hours with two decimals
  screen.print("m");
  Serial.print("Battery: ");
  Serial.println(batteryvolts);
  Serial.print("Current: ");
  Serial.println(current);
}

void handleFastDisplay(){
  //Angle
  screen.setTextSize(2);
  screen.setCursor(140,95);
  screen.fillRect(139,94,75,17,erasecolor);
  screen.setTextColor(COLOR_RGB565_GREEN);
  screen.print((baseyangle*100)-(gyroy*100),1);//angle with only one decimal
}

void handleDisplayButtons(){
  //e-brake button
  if (ebrakeon != lastebrakeon){
    if (!ebrakeon){
      screen.fillRoundRect(220,45,90,60,12,erasecolor);//erase
      screen.drawRoundRect(225,50,80,50,12,backgroundcolor);
      screen.setTextSize(2);
      screen.setCursor(235,70);
      screen.setTextColor(COLOR_RGB565_RED);
      screen.print("E OFF");
    }
    else {
      screen.fillRoundRect(225,50,80,50,12,backgroundcolor);
      screen.setTextSize(2);
      screen.setCursor(235,70);
      screen.setTextColor(COLOR_RGB565_GREEN);
      screen.print("E ON");
    }
    lastebrakeon = ebrakeon;
  }
  if (!lockbtnon){
    screen.fillRoundRect(12,45,90,60,12,erasecolor);//erase
    screen.drawRoundRect(15,50,80,50,12,backgroundcolor);
    screen.setTextSize(1);
    screen.setCursor(25,70);
    screen.setTextColor(COLOR_RGB565_GREEN);
    screen.print("Unlocked");
  }
  else if (lockbtnon || locked){
    screen.fillRoundRect(15,50,80,50,12,backgroundcolor);
    screen.setTextSize(2);
    screen.setCursor(20,70);
    screen.setTextColor(COLOR_RGB565_RED);
    screen.print("Locked");
    ebrakeon = true;
    locked = true;
  }
  if (cruiseon != lastcruiseon){
    if (!cruiseon){
      screen.fillRoundRect(220,105,90,60,12,erasecolor);//erase
      screen.drawRoundRect(225,110,80,50,12,backgroundcolor);
      screen.setTextSize(2);
      screen.setCursor(235,130);
      screen.setTextColor(COLOR_RGB565_GREEN);
      screen.print("C OFF");
    }
    else {
      screen.fillRoundRect(225,110,80,50,12,backgroundcolor);
      screen.setTextSize(2);
      screen.setCursor(235,130);
      screen.setTextColor(COLOR_RGB565_ORANGE);
      screen.print("C ON");
    }
    lastcruiseon = cruiseon;
  }
}

void handleAngleLine(float angle1){  
  int x=160,y=140; //center point of the two lines

  screen.drawLine(x, y, previousotherx1, previousothery1, erasecolor);//line going right
  screen.drawLine(x+1, y+1, previousotherx1+1, previousothery1+1, erasecolor);//double thick line
  screen.drawLine(x, y, previousotherx2, previousothery2, erasecolor);//line going left
  screen.drawLine(x+1, y+1, previousotherx2+1, previousothery2+1, erasecolor);//double thick line

  #define DEG2RAD 0.0174532925
  float screenangle1 = 135; //value for right line to make it level
  float screenangle2 = 315; //value for left line to make it level; appears to be one line instead of two separate ones
  float angle2 = angle1;  
  int w=100,h=100; //length of each line; one going right and one going left
 
  #define linecolor COLOR_RGB565_NAVY
  float cosa1 = cos((screenangle1+angle1) * DEG2RAD), sina1 = sin((screenangle1+angle1) * DEG2RAD);
  int otherx1 = x - ((w * cosa1 / 2) - (h * sina1 / 2));
  int othery1 = y - ((h * cosa1 / 2) + (w * sina1 / 2));
  screen.drawLine(x, y, otherx1, othery1, linecolor);//line going right
  screen.drawLine(x+1, y+1, otherx1+1, othery1+1, linecolor);//double thick line
  float cosa2 = cos((screenangle2+angle2) * DEG2RAD), sina2 = sin((screenangle2+angle2) * DEG2RAD);
  int otherx2 = x - ((w * cosa2 / 2) - (h * sina2 / 2));
  int othery2 = y - ((h * cosa2 / 2) + (w * sina2 / 2));
  screen.drawLine(x, y, otherx2, othery2, linecolor);//line going left
  screen.drawLine(x+1, y+1, otherx2+1, othery2+1, linecolor);//double thick line

  previousotherx1 = otherx1;
  previousothery1 = othery1;
  previousotherx2 = otherx2;
  previousothery2 = othery2;
}

void batterywarning(){

}

void changepassword(){
  screen.fillScreen(backcolor);
  screen.fillScreen(COLOR_RGB565_DGRAY);
  screen.fillRoundRect(0, 0, 320, 240, 15, backgroundcolor);
  screen.fillRoundRect(5, 5, 310, 230, 15, backcolor);
  screen.setTextColor(backgroundcolor);
  screen.setTextSize(3);
  screen.setCursor(30, 11);
  screen.print("Change PASS");
  screen.drawFastHLine(10, 35, 300, COLOR_RGB565_GREEN);
  screen.drawFastHLine(10, 36, 300, COLOR_RGB565_GREEN);
  screen.setTextColor(COLOR_RGB565_GREEN);
  screen.setTextSize(1);
  screen.setCursor(40, 100);
  screen.print("Do three gestures to set new password...");
  
  password[0] = 0;
  password[1] = 0;
  password[2] = 0;

  int gesturepasscount = 0;
  redo:
  if(gr10_30.getDataReady()){
    gestures = gr10_30.getGesturesState();
    if(gestures&GESTURE_UP){
      Serial.println("Up");
      password[gesturepasscount] = GESTURE_UP;
    }
    if(gestures&GESTURE_DOWN){
      Serial.println("Down");
      password[gesturepasscount] = GESTURE_DOWN;
    }
    if(gestures&GESTURE_LEFT){
      Serial.println("Left");
      password[gesturepasscount] = GESTURE_LEFT;
    }
    if(gestures&GESTURE_RIGHT){
      Serial.println("Right");
      password[gesturepasscount] = GESTURE_RIGHT;
    }
    if(gestures&GESTURE_FORWARD){
      password[gesturepasscount] = GESTURE_FORWARD;
    }
    if(gestures&GESTURE_BACKWARD){
      password[gesturepasscount] = GESTURE_BACKWARD;
    }
    if(gestures&GESTURE_CLOCKWISE){
      password[gesturepasscount] = GESTURE_CLOCKWISE;
    }
    if(gestures&GESTURE_COUNTERCLOCKWISE){
      password[gesturepasscount] = GESTURE_COUNTERCLOCKWISE;
    }
    if(gestures&GESTURE_WAVE){
      password[gesturepasscount] = GESTURE_WAVE;
    }
    if(gestures&GESTURE_HOVER){
      password[gesturepasscount] = GESTURE_HOVER;
    }
    if(gestures&GESTURE_CLOCKWISE_C){
      password[gesturepasscount] = GESTURE_CLOCKWISE_C;
    }
    if(gestures&GESTURE_COUNTERCLOCKWISE_C){
      password[gesturepasscount] = GESTURE_COUNTERCLOCKWISE_C;
    }
    EEPROM.write(gesturepasscount,password[gesturepasscount]);
    EEPROM.commit();
    gesturepasscount++;
    Serial.println("gesturepasscount: " + String(gesturepasscount));   
  }

  if (gesturepasscount != passwordlength){
    goto redo;
  }
  Serial.println("Finished!");   
  gesturepasscount = 0;
  startDisplay();
  
}

void readThrottle(){
  throttleval = map(analogRead(throttlepin),throttleoffvalue,throttleonvalue,0,4095);
  //Serial.print("Throttle: ");
  //Serial.println(throttleval);
  //Serial.println("Throttle: " + String(throttleval));
}

void readBattery(){
  if ((millis() - lastbatreading) > readbatteryint){
    if (curbatread < batteryreadings){
      batsum = batsum + analogRead(batterypin);
      curbatread++;
    }
    else{
      float batteryread = batsum/batteryreadings;
      float batpinvolt = (batteryread*3.3)/4095;//3.3V and 4095 is the max resolution of ESP32
      if (testing){
        batpinvolt = 2.2;
      }
      batteryvolts = batpinvolt*16.55;//(1000/(15000+1000)); //(R2/(R1+R2));//VOUT = VIN*R2/R1+R2 ; classic equation for voltage dividers
      
      curbatread = 0;
      batsum = 0;

    }
    lastbatreading = millis();
  }
}

void readGyro(){
  /*for (curgyroread=0;curgyroread<gyroreadings;curgyroread++){
    gyrosum = gyrosum + gyro.y;
    delay(readgyroint);
  }
  gyroy = gyrosum/gyroreadings;      
  curgyroread = 0;
  gyrosum = 0;*/
  
  if ((millis() - lastgyroreading) > readgyroint){
    if (curgyroread < gyroreadings){
      gyrosum = gyrosum + gyro.y;
      curgyroread++;
    }
    else{
      gyroy = gyrosum/gyroreadings;      
      curgyroread = 0;
      gyrosum = 0;
    }
    lastgyroreading = millis();
  }
}

void handleGestures(){
  if(gr10_30.getDataReady()){
    gestures = gr10_30.getGesturesState();
    if(gestures&GESTURE_UP){
      Serial.println("Up");
      cruiseon = true;
    }
    if(gestures&GESTURE_DOWN){
      Serial.println("Down");
      //if (cruiseon){
      //  ledsoff = !ledsoff;
      //}
      cruiseon = false;
    }
    if(gestures&GESTURE_LEFT){
      Serial.println("Left");
      if (rightturnsignal){
        rightturnsignal = false;
        pixels.clear();
        pixels.show();
      }
      else {
        leftturnsignal = true;
        lastturnstat = true;
      }
    }
    if(gestures&GESTURE_RIGHT){
      Serial.println("Right");
      if (leftturnsignal){
        leftturnsignal = false;
        pixels.clear();
        pixels.show();
      }
      else {
        rightturnsignal = true;
        lastturnstat = true;
      }
    }
    if(gestures&GESTURE_FORWARD){
      Serial.println("Forward");
      ebrakeon = true;
    }
    if(gestures&GESTURE_BACKWARD){
      Serial.println("Backward");
      ebrakeon = false;
    }
    if(gestures&GESTURE_CLOCKWISE){
      Serial.println("Clockwise");
    }
    if(gestures&GESTURE_COUNTERCLOCKWISE){
      Serial.println("Contrarotate");
    }
    if(gestures&GESTURE_WAVE){
      Serial.println("Wave");
    }
    if(gestures&GESTURE_HOVER){
      Serial.println("Hover");
    }
    if(gestures&GESTURE_CLOCKWISE_C){
      Serial.println("Continuous clockwise");
      headlight = !headlight;
    }
    if(gestures&GESTURE_COUNTERCLOCKWISE_C){
      Serial.println("Continuous counterclockwise");
      screen.fillRoundRect(15,50,80,50,12,backgroundcolor);
      screen.setTextSize(2);
      screen.setCursor(20,70);
      screen.setTextColor(COLOR_RGB565_RED);
      screen.print("Locked");
      screen.fillRoundRect(225,50,80,50,12,backgroundcolor);
      screen.setTextSize(2);
      screen.setCursor(235,70);
      screen.setTextColor(COLOR_RGB565_GREEN);
      screen.print("E ON");
      ebrakeon = true;
      locked = true;
    }
  }
}

void lockedloop(){
  if(gr10_30.getDataReady()){
    gestures = gr10_30.getGesturesState();
    Serial.print("Gesture: ");
    Serial.println(gestures);
    if (gestures&password[passc]){
      Serial.println("Correct!");
      Serial.println(password[passc]);
      passc++;
      Serial.println("PASSC: " + String(passc));
    }
    else {
      Serial.println("Wrong");
      passc=0;
    }
  }
  if (passc >= passwordlength){
    Serial.println("Unlocked!");
    passc=0;
    locked = false;
    //lock = false;
  }
}

void readGNSS(){
  utc = gnss.getUTC();
  date = gnss.getDate();
  latitude = gnss.getLat();
  longitude = gnss.getLon();
  altitude = gnss.getAlt();
  satelites = gnss.getNumSatUsed();
  knots = gnss.getSog();
  course = gnss.getCog();
}

void readAccelGyro(){
  int i = 0;
  int rslt;
  int16_t accelGyro[6]={0}; 
  
  //get both accel and gyro data from bmi160
  //parameter accelGyro is the pointer to store the data
  rslt = bmi160.getAccelGyroData(accelGyro);
  if(rslt == 0){
    for(i=0;i<6;i++){
      if (i<3){
        //the first three are gyro data
        //Serial.print(accelGyro[i]*3.14/180.0);Serial.print("\t");
        if (i==0){accel.x = accelGyro[i]*3.14/180.0;}
        else if (i==1){accel.y = accelGyro[i]*3.14/180.0;}
        else if (i==2){accel.z = accelGyro[i]*3.14/180.0;}
      }else{
        //the following three data are accel data
        //Serial.print(accelGyro[i]/16384.0);Serial.print("\t");
        if (i==3){gyro.x = accelGyro[i]/16384.0;}
        else if (i==4){gyro.y = accelGyro[i]/16384.0;}
        else if (i==5){gyro.z = accelGyro[i]/16384.0;}
      }
    }
    //Serial.println();
  }else{
    Serial.println("err");
  }
}

void readTempHum(){
  if(aht20.startMeasurementReady(/* crcEn = */true)){
    temperature = aht20.getTemperature_F();
    humidity = aht20.getHumidity_RH();
  }
  HI = 0.5 * (temperature + 61.0 + ((temperature-68.0)*1.2) + (humidity*0.094));
  if (HI > 80.0){
    HI = -42.379 + 2.04901523*temperature + 10.14333127*humidity - .22475541*temperature*humidity - .00683783*temperature*temperature - .05481717*humidity*humidity + .00122874*temperature*temperature*humidity + .00085282*temperature*humidity*humidity - .00000199*temperature*temperature*humidity*humidity;
    if ((temperature > 80.0 && temperature < 112.0) && (humidity < 13.0)){
      HI = ((13-humidity)/4)*sqrt((17-abs(temperature-95.0))/17);
    }
    else if ((temperature > 80.0 && temperature < 87.0) && (humidity > 85.0)){
      HI = ((humidity-85)/10) * ((87-temperature)/5);
    }
  }
  temperature = HI;
}

void readCurrent(){
  if ((millis() - lastcurreading) > readcurrentint){
    if (curcurread < currentreadings){
      cursum = cursum + analogRead(currentpin);
      curcurread++;
    }
    else{
      float currentread = cursum/currentreadings;
      float curpinvolt = (currentread*3.3)/4095;//3.3V and 4095 is the max resolution of ESP32
      current = (curpinvolt-1.65)/0.04;
      current = constrain(current,0,50);
      watts = current*batteryvolts;
      watts = constrain(watts,0,500);

      curcurread = 0;
      cursum = 0;
    }
    lastcurreading = millis();
  }
//Data processing:510-raw data from analogRead when the input is 0;
// 5-5v; the first 0.04-0.04V/A(sensitivity); the second 0.04-offset val;
}

void handleMotordriver(){
  //digitalWrite(cruisepin,cruiseon);
  digitalWrite(brakepin,ebrakeon);
  if (voltconversion){
    motorvalue = map(throttleval,3500,0,0,255);
    motorvalue = constrain(motorvalue,0,255);
  }
  else{
    motorvalue = map(throttleval,300,4000,0,255);
    motorvalue = constrain(motorvalue,0,255);
  }
  
  motorvalue = map(motorvalue,255,0,0,255);
  if (motorvalue > 245){
    digitalWrite(cruisepin, HIGH);
  }
  else {
    digitalWrite(cruisepin, LOW);
  }
  if (motorvalue >= 200 && motorvalue <= 245){
    if (abs(motorvalue - lastthrottleval) <= 5){
      motorvalue = lastthrottleval;
    }
    else {
      lastthrottleval = motorvalue;
    }
  }
  else if (motorvalue < 200 && motorvalue > 110){
    if (abs(motorvalue - lastthrottleval) <= 15){
      motorvalue = lastthrottleval;
    }
    else {
      lastthrottleval = motorvalue;
    }
  }
  else if (motorvalue <= 110 && motorvalue > 5){
    motorvalue = map(motorvalue,5,120,32,87);
  }
  if (motorvalue >= 250){motorvalue = 255;} else if (motorvalue <= 5){motorvalue = 0;}
  if ((lastthrottleval - motorvalue) <= -7){
    motorvalue = lastthrottleval - 8;
    lastthrottleval = motorvalue;
  }
  motorvalue = abs(motorvalue);
  
  motorvalue = constrain(motorvalue,0,255);
  if (throttleval == 0){
    motorvalue = 0;
  }

  Serial.print("Motor val: ");
  Serial.print(motorvalue);  Serial.print(" | ");
  //motorvalue = map(motorvalue,0,255,255,0);
  
  ledcWrite(speedChannel, motorvalue);//pwm signal for speed
}

void handleLeds(){
  if ((millis() - lastcoursereadtime) > coursechangetime){//handle turning signal
    coursechange = course - lastcoursereading;
    lastcoursereading = course; 
    lastcoursereadtime = millis();   
  }
  
  if (leftturnsignal == true || rightturnsignal == true){
    if (leftturnsignal){
      //brakelight(3);
      leftblinker();
    }
    if (rightturnsignal){
      //brakelight(3);
      rightblinker();
    }
  }
  else if (leftturnsignal == false && rightturnsignal == false){
    if (abs(coursechange) > courseturnsignalinc){
      if (coursechange < 0){
        //brakelight(3);
        leftblinker();
      }
      else {
        //brakelight(3);
        rightblinker();
      }
    }
    else {
      if (speeddiferrence >= speedbrakeinc){
        //pixels.clear();
        //pixels.show();
        brakelight(2);
      }
    }
  }

  if ((millis() - lastspeedreadtime) > speedchangetime){//handle brake light
    speeddiferrence = knots - lastspeedreading;
    if (speeddiferrence < speedbrakeinc){
      if (rightturnsignal){
        pixels.setPixelColor(5, pixels.Color(255,0,0));
        pixels.setPixelColor(6, pixels.Color(255,0,0));
        pixels.show();
      }
      else if (leftturnsignal){
        pixels.setPixelColor(9, pixels.Color(255,0,0));
        pixels.setPixelColor(8, pixels.Color(255,0,0));
        pixels.show();
      }
      else {
        brakelight(1);
      }
    }
    //else {
    //  brakelight(1);
    //}
    lastspeedreading = knots;
    lastspeedreadtime = millis();
  }

  if (headlight){
    headlights(true);
  }
  else {
    headlights(false);
  }

  handleFootlight();
}

void leftblinker(){
  int turningsignalcolor = pixels.Color(0, 20, 255);
  if (animationcountleft == 1){
    if ((millis() - startmillis) < 250){
      pixels.setPixelColor(7, turningsignalcolor);
      pixels.show();
    }
    else {
      animationcountleft++;
      startmillis = millis();
    }
  }
  else if (animationcountleft == 2){
    if ((millis() - startmillis) < 250){
      pixels.setPixelColor(7, pixels.Color(0, 0, 0));
      pixels.setPixelColor(6, turningsignalcolor);
      pixels.show();
    }
    else {
      animationcountleft++;
      startmillis = millis();
    }
  }
  if (animationcountleft == 3){
    if ((millis() - startmillis) < 750){
      pixels.setPixelColor(6, pixels.Color(0, 0, 0));
      pixels.setPixelColor(5, turningsignalcolor);
      pixels.show();
    }
    else {
      animationcountleft++;
      startmillis = millis();
    }
  }
  if (animationcountleft == 4){
    if ((millis() - startmillis) < 400){
      pixels.setPixelColor(5, pixels.Color(0, 0, 0));
      pixels.show();
    }
    else {
      animationcountleft = 1;
      startmillis = millis();
    }
  }
}

void rightblinker(){
  int turningsignalcolor = pixels.Color(0, 20, 255);
  if (animationcountright == 1){
    if ((millis() - startmillis) < 250){
      pixels.setPixelColor(7, turningsignalcolor);
      pixels.show();
    }
    else {
      animationcountright++;
      startmillis = millis();
    }
  }
  else if (animationcountright == 2){
    if ((millis() - startmillis) < 250){
      pixels.setPixelColor(7, pixels.Color(0, 0, 0));
      pixels.setPixelColor(8, turningsignalcolor);
      pixels.show();
    }
    else {
      animationcountright++;
      startmillis = millis();
    }
  }
  if (animationcountright == 3){
    if ((millis() - startmillis) < 750){
      pixels.setPixelColor(8, pixels.Color(0, 0, 0));
      pixels.setPixelColor(9, turningsignalcolor);
      pixels.show();
    }
    else {
      animationcountright++;
      startmillis = millis();
    }
  }
  if (animationcountright == 4){
    if ((millis() - startmillis) < 400){
      pixels.setPixelColor(9, pixels.Color(0, 0, 0));
      pixels.show();
    }
    else {
      animationcountright = 1;
      startmillis = millis();
    }
  }
}

void brakelight(int brakelighton){
  if (brakelighton == 1){
    for (int i=0;i<5;i++){
      pixels.setPixelColor(brake[i], pixels.Color(255, 0, 0));//on brake light
    }
    pixels.show();
  }
  else if (brakelighton == 2){
    for (int i=0;i<5;i++){
      pixels.setPixelColor(brake[i], pixels.Color(60, 0, 0));//on brake light
    }
    pixels.show();
  }
  else {
    for (int i=0;i<5;i++){
      pixels.setPixelColor(brake[i], pixels.Color(0, 0, 0));//on brake light
    }
    pixels.show();
  }
}

void headlights(bool on){
  if (on){
    pixels.setPixelColor(0, pixels.Color(255, 255, 255));//brake light on
    pixels.setPixelColor(1, pixels.Color(255, 255, 255));//brake light on
    pixels.setPixelColor(2, pixels.Color(255, 255, 255));//brake light on
    pixels.setPixelColor(3, pixels.Color(255, 255, 255));//brake light on
    pixels.setPixelColor(4, pixels.Color(255, 255, 255));//brake light on
    pixels.show();
  }
  else {
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));//dim brake light
    pixels.setPixelColor(1, pixels.Color(0, 0, 0));//dim brake light
    pixels.setPixelColor(2, pixels.Color(0, 255, 0));//dim brake light
    pixels.setPixelColor(3, pixels.Color(0, 0, 0));//dim brake light
    pixels.setPixelColor(4, pixels.Color(0, 0, 0));//dim brake light
    pixels.show();
  }
}

void handleFootlight(){
  if (locked){
    if (panimationcount > 235 && pup){
      pup = false;
    }
    else if (panimationcount < 0 && !pup){
      pup = true;
    }

    if (pup){
      panimationcount+=8;
    }
    else {
      panimationcount-=8;
    }

    for (int i=0;i<4;i++){
      pixels.setPixelColor(footlight[i], pixels.Color(panimationcount,0,0));
      pixels.show();
    }
    //delayMicroseconds(1);
  }
  else if (knots < 1){
    if (panimationcount > 235 && pup){
      pup = false;
    }
    else if (panimationcount < 25 && !pup){
      pup = true;
    }

    if (pup){
      panimationcount+=8;
    }
    else {
      panimationcount-=8;
    }

    for (int i=0;i<4;i++){
      pixels.setPixelColor(footlight[i], pixels.Color(0,panimationcount,0));
      pixels.show();
    }
    //delayMicroseconds(1);
  }
  else {
    for (int i=0;i<4;i++){
      pixels.setPixelColor(footlight[i], pixels.Color(0,20,255));
      pixels.show();
    }
  }
}

void startDisplay(){
  screen.fillScreen(backcolor);
  screen.setTextWrap(false);

  screen.fillScreen(COLOR_RGB565_DGRAY);
  screen.fillRoundRect(0, 0, 320, 240, 15, backgroundcolor);
  screen.fillRoundRect(5, 5, 310, 230, 15, backcolor);
  
  //title
  screen.setTextColor(backgroundcolor);
  screen.setTextSize(3);
  screen.setCursor(30, 11);
  screen.print("DIY E-Scooter");

  screen.drawFastHLine(10, 35, 300, COLOR_RGB565_GREEN);
  screen.drawFastHLine(10, 36, 300, COLOR_RGB565_GREEN);

  //speed label
  screen.setTextColor(COLOR_RGB565_YELLOW);
  screen.setTextSize(2);
  screen.setCursor(125,40);
  screen.print("Speed");

  //dist and time to empty labels
  screen.setTextColor(COLOR_RGB565_YELLOW);
  screen.setTextSize(2);
  screen.setCursor(91,170);
  screen.print("Dist   Time");

  //boost button
  screen.drawRoundRect(225,50,80,50,12,backgroundcolor);
  screen.setTextSize(2);
  screen.setCursor(235,70);
  screen.setTextColor(COLOR_RGB565_RED);
  screen.print("E OFF");

  //lock button
  screen.drawRoundRect(15,50,80,50,12,backgroundcolor);
  screen.setTextSize(1);
  screen.setCursor(25,70);
  screen.setTextColor(COLOR_RGB565_GREEN);
  screen.print("Unlocked");

  //cruise button
  screen.drawRoundRect(225,110,80,50,12,backgroundcolor);
  screen.setTextSize(2);
  screen.setCursor(235,130);
  screen.setTextColor(COLOR_RGB565_GREEN);
  screen.print("C OFF");
}

void startGestureSensor(){

  if(gr10_30.begin() != 0){
    Serial.println(" Sensor initialize failed!!");
    delay(1000);
  }
  /** Set the gesture to be enabled
 *  GESTURE_UP
 *  GESTURE_DOWN
 *  GESTURE_LEFT
 *  GESTURE_RIGHT
 *  GESTURE_FORWARD
 *  GESTURE_BACKWARD
 *  GESTURE_CLOCKWISE
 *  GESTURE_COUNTERCLOCKWISE
 *  GESTURE_WAVE              It is not suggested to enable rotation gesture (CW/CCW) and wave gesture at the same time.
 *  GESTURE_HOVER             Disable other gestures when hover gesture enables.
 *  GESTURE_UNKNOWN
 *  GESTURE_CLOCKWISE_C
 *  GESTURE_COUNTERCLOCKWISE_C
 */
  gr10_30.enGestures(GESTURE_UP|GESTURE_DOWN|GESTURE_LEFT|GESTURE_RIGHT|GESTURE_FORWARD|GESTURE_BACKWARD|GESTURE_CLOCKWISE|GESTURE_COUNTERCLOCKWISE|GESTURE_CLOCKWISE_C|GESTURE_COUNTERCLOCKWISE_C);
  /**
 * Set the detection window you want, only data collected in the range are valid
 * The largest window is 31, the configured number represents distance from the center to the top, bottom, left and right
 * For example, if the configured distance from top to bottom is 30, then the distance from center to top is 15, and distance from center to bottom is also 15
 * udSize Range of distance from top to bottom      0-31
 * lrSize Range of distance from left to right      0-31
 */
  gr10_30.setUdlrWin(30, 30);//0-31,0-31
  /**
 * Set moving distance that can be recognized as a gesture
 * Distance range 5-25, must be less than distances of the detection window
 */
  gr10_30.setLeftRange(10);
  gr10_30.setRightRange(10);
  gr10_30.setUpRange(10);
  gr10_30.setDownRange(10);
  //gr10_30.setForwardRange(10);
  //gr10_30.setBackwardRange(10);
  /**
 * Set distance of moving forward and backward that can be recognized as a gesture
 * Distance range 1-15
 */
  gr10_30.setForwardRange(10);
  gr10_30.setBackwardRange(10);
/**
 * Set rotation angle that can trigger the gesture
 * count Default is 16 range 0-31
 * count Rotation angle is 22.5 * count
 * count = 16 22.5*count = 360  Rotate 360° to trigger the gesture
 */
  gr10_30.setCwsAngle(/*count*/16);
  gr10_30.setCcwAngle(/*count*/16);
  /**
 * Set degrees of continuous rotation that can trigger the gesture
 * count Default is 4  range 0-31
 * count The degrees of continuous rotation is 22.5 * count
 * For example: count = 4 22.5*count = 90
 * Trigger the clockwise/counterclockwise rotation gesture first, if keep rotating, then the continuous rotation gesture will be triggered once every 90 degrees
 */
  gr10_30.setCwsAngleCount(/*count*/8);
  gr10_30.setCcwAngleCount(/*count*/8);
}

/*void interruptRoutine(){
  Serial.println("Interrupt...");
}*/

Settings.h:

//Arduino Cloud
const char DEVICE_LOGIN_NAME[]  = "*********************************";
const char DEVICE_KEY[]  = "***************";    // Secret device password

//WiFi networks
const char SSID1[] = "****************";
const char PASS1[] = "********";
const char SSID2[] = "";
const char PASS2[] = "";
const char SSID3[] = "";
const char PASS3[] = "";

//Motor Driver
#define brakepin  16 //D11
#define cruisepin A4  // actually enable pin, so able to push scooter manually when on
#define speedpin A3 
//#define rpmpin A4

//Display
#define TFT_DC  25 //D2
#define TFT_RST 26 //D3
#define TFT_CS  14 //D6
#define TOUCH_CS 4 //D12
#define TFT_BL  12 //D13

//Throttle
#define throttlepin A0 //throttle pin

//LEDs
#define LEDPIN 17//D10

//battery
#define batterypin A2

//current sensor
#define currentpin A1

//Password
int password[] = {GESTURE_UP,GESTURE_DOWN,GESTURE_LEFT};//Adjustable gesture password; can adjust password length (right now it is set to 3 in the "passwordlength" integer)

I would really appreciate some tips!
Thanks in advance!

The binary backtrace is meaningless without the actual binary, decode it using Releases · me-no-dev/EspExceptionDecoder · GitHub to get a readable backtrace to see where the error is.

Abort indicates a fatal error was detected, e.g. an assertion that failed.

Hi @PieterP ; thanks for responding!

That's what I thought.

I tried, but I couldn't get it to work. I added it to the tools folder under "Arduino", but it still doesn't show up even after I restarted Arduino. I'm on a Mac fyi.

IIRC, the exception decoder only works for version 1.8.x of the IDE. Are you using the 2.x IDE?

Ohhh, I have 2.x and 1.8.x; I tried it on the 2.x though.

It seems it was only displaying part of the error; I managed to get the rest of it:

E (33) gpiE (36) gpio: GPIO can only be used as input mode
E (36) gpio: gpio_set_level(226): GPIO output gpio_num error
E (37) ledc: ledc_channel_config(608): gpio_num argument is invalid

What does this mean?

The first error appears quite self explanatory. See the table in the following link: ESP32 Pinout Reference: Which GPIO pins should you use? | Random Nerd Tutorials

Hi @6v6gt !

Yeah, but im not using GPIO pin 36 at all :thinking:.

Oh, duh :roll_eyes:. A0 is GPIO 36 :man_facepalming:.

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