ESP32 RC car project issue

0

im using nipplejjs like virtual joystick by sending json request to esp32 to remote a rc car with to dc motors the front motor is for direction and the back motor for speed

the fonction rorat hendle the json request i retrive the (distance , angle , degree ,type ) variables

var els = {
        position : {
            x : "x" ,
            y: "y"
        },
        force : "force",
        pressure : "pressure",
        distance : "distance",
        angle : {
            radian : "radian",
            degree : "degree"
        },
        direction: {
            x : "x",
            y : "y",
            angle :"angle"
        },
        type : "type"
    };

the problem is in loop() fonction i think

link to github

github link

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x40001277  PS      : 0x00060630  A0      : 0x800d1b9a  A1      : 0x3ffb1f40
A2      : 0x00000000  A3      : 0x3f40152c  A4      : 0x00000001  A5      : 0x00000001
A6      : 0x00060220  A7      : 0x00000000  A8      : 0x800e2270  A9      : 0x3ffb1f10
A10     : 0x00000002  A11     : 0x3f4020a0  A12     : 0x80088d90  A13     : 0x3ffbc570
A14     : 0x00000000  A15     : 0x3ffb0060  SAR     : 0x00000010  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff

Backtrace: 0x40001277:0x3ffb1f40 0x400d1b97:0x3ffb1f50 0x400d1c1b:0x3ffb1f70 
0x400d209d:0x3ffb1f90 0x400e4355:0x3ffb1fb0 0x40088b7d:0x3ffb1fd0

Code

 #include <Arduino.h>
#include <WiFi.h>
#include <SPIFFSIO.cpp>

#include <ArduinoAdapter.h>
#include <ESPAsyncWebServer.h>
#include <AsyncJson.h>
#include <ArduinoJson.h>
#include <analogWrite.h>

int LED_BUILTIN = 2;

/** CONFIG VALUES */
// Settings for local access point used for configuring wifi
int pin_in1 = 14;
int pin_in2 = 12;
int pin_enm = 13;

int pin_in3 = 27;
int pin_in4 = 26;
//int pin_enm2 = 25;

int _distance ;
const char * _angle;
const char * _type;
int _degre;

#define AP_NAME "RC_CAR"
#define AP_PASSWORD ""

bool accessPointMode = true;
bool useAP = false;

const char *ssid;
const char *password;

const char *dist;
const char *angl;
const char *sta;

// AsyncWebServer object on port 80
AsyncWebServer server(80);

/** Scan for wifi access points and return how many found */
int wifiScan()
{
  int n = WiFi.scanNetworks();
  Serial.println("Scan done");
  if (n == 0)
    Serial.println("No networks found");
  return n;
}

/** Read saved wifi settings
 * 'ssid' and 'password' files can be created manually to data folder for connecting to predefined wifi
 * */
void getSavedWifi()
{
  ssid = strdup(readString("/ssid").c_str());
  password = strdup(readString("/password").c_str());
  if (strcmp(ssid, "-1") != 0 && strcmp(password, "-1") != 0)
    accessPointMode = false;
}

/** Try to connect to wifi or create an access point */
bool setupWifi()
{

  if (accessPointMode)
  {
    Serial.print("Creating access point: ");
    Serial.print(AP_NAME);
    Serial.print(" - ");
    Serial.println(AP_PASSWORD);
    WiFi.softAP(AP_NAME, AP_PASSWORD);
  }
  else
  {
    // Try to connect
    WiFi.begin(ssid, password);
    int tries = 0;
    while (WiFi.status() != WL_CONNECTED && tries <= 8)
    {
      Serial.println("Connecting to WiFi..");
      delay(1000);
      tries++;
    }

    // Failed, setup ap for configuring
    if (WiFi.status() != WL_CONNECTED)
    {
      Serial.print("WiFi connection failed");
      accessPointMode = true;
      WiFi.disconnect();
      setupWifi();
      return false;
    }
    else // successfully connected
    {
      accessPointMode = false;
      Serial.print("Current IP: ");
      Serial.print(accessPointMode ? WiFi.softAPIP() : WiFi.localIP());
    }
  }

  Serial.print("Current IP: ");
  Serial.print(accessPointMode ? WiFi.softAPIP() : WiFi.localIP());
  if (accessPointMode)
    delay(3500);
  return true;
}

// initialize output pins
void initmotors(){
  pinMode(pin_in1, OUTPUT);
  pinMode(pin_in2, OUTPUT);
  pinMode(pin_in3, OUTPUT);
  pinMode(pin_in4, OUTPUT);

  analogWriteResolution(pin_enm, 8);
}

// back motor cw retation with pwm 
void smovecw(int speed){

        digitalWrite(pin_in1, HIGH);
        digitalWrite(pin_in2, LOW);
        analogWrite(pin_enm,speed,255);
  }    

//back motor ccw rotation with pwm
  void smoveccw( int speed){

        digitalWrite(pin_in1, LOW);
        digitalWrite(pin_in2, HIGH);
        analogWrite(pin_enm,speed,255);
  }

// front motor cw rotation
  void dmovecw(){
        digitalWrite(pin_in3, HIGH);
        digitalWrite(pin_in4, LOW);
  }    

// front motor ccw rotation
  void dmoveccw(){
        digitalWrite(pin_in3, LOW);
        digitalWrite(pin_in4, HIGH);
  }

enum State {
        up,
        down,
        right,
        left,
        nothing
};

// convert char string to enum 

 State stringtoenum(const char *str){

  if (!strcmp(str,"up")) return up;
  if (!strcmp(str,"down")) return down;
  if (!strcmp(str,"right")) return right;
  if (!strcmp(str,"left")) return left;
  return nothing;

}

// motors off
void stop() {
                digitalWrite(pin_in1, LOW);
                digitalWrite(pin_in2, LOW);     
                digitalWrite(pin_in3, LOW);
                digitalWrite(pin_in4, LOW);
  }  

// convert enum to char string 

inline const char *stateToString(State val)
{
  switch (val)
  {
  case up:
    return "up";
  case down:
    return "down";
  case right:
    return "right";
  case left:
    return "left";
  default:
    return "nothing";
  }
}

// rotat motors in loop 
void rotat() {

Serial.println(_angle);

const State _state = stringtoenum(_angle);
Serial.println(_state);

if (strcmp(_type,"end") == 0)  {
  Serial.println("Stop");
     stop();

     } else 
     {
     switch (_state) {

        case up :
          if(_distance >=0 && _distance <=150 ){
                 Serial.println("yes");
                smovecw(_distance);
                // write duty to LEDC
               Serial.println(_distance);
                } 
          break;

        case down :
        if(_distance >=0 && _distance <=150 ){
                 Serial.println("yes");
                 Serial.println(_distance);
                smoveccw(_distance);
                // write duty to LEDC
                } 
        break;
        case right:

         if(_distance >=0 && _distance <=50 ){
            Serial.println(_distance);
         dmovecw();

       } else  if (_distance >=50 && _distance <=150 ){
               Serial.println(_distance);

              if(_degre >=0 && _degre <=45 ){
                Serial.println(_distance);
                Serial.println(_degre);

                dmovecw();
                smovecw(_distance);

              } else if (_degre >=315 && _degre <=359 ){
                Serial.println(_distance);
                Serial.println(_degre);

                dmovecw();
                smoveccw(_distance);
                }   
        }
        break;

        case left :

        if(_distance >=0 && _distance <=50 ){

         Serial.println(_distance);
         dmoveccw();

       } else  if (_distance >=50 && _distance <=150 ){
          Serial.println(_distance);
              if(_degre >=135 && _degre <=180 ){
                Serial.println(_distance);
                Serial.println(_degre);
                dmoveccw();
                smovecw(_distance);

              } else if (_degre >=180 && _degre <=225 ){
                Serial.println(_distance);
                Serial.println(_degre);

                dmoveccw();
                smoveccw(_distance);
                }   
        }

        break ;
    case nothing :
      stop();
      break;
     }
    } 
   } 

// TODO: Validate data received and add permission management / restriction for certain features
/** Setup URL routers and handlers for server */
void setupServer()
{
  // Pages
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    if (accessPointMode && !useAP)
     // request->send(SPIFFS, "/wifisetup.html", "text/html");
   // else
      request->send(SPIFFS, "/control.html", "text/html");
      else
      request->send(SPIFFS, "/control.html", "text/html");
  });

  server.on("/format", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/format.html", "text/html");

     bool formatted = SPIFFS.format();

  if(formatted){
    Serial.println("\n\nSuccess formatting");
  }else{
    Serial.println("\n\nError formatting");
  }
  Serial.println("\n\n----Listing files after format----");

  });

  // Cache static resources
  server.serveStatic("/css/materialize.min.css", SPIFFS, "/css/materialize.min.css", "max-age=3600");
  server.serveStatic("/css/style.css", SPIFFS, "/css/style.css", "max-age=3600");
  server.serveStatic("/js/materialize.min.js", SPIFFS, "/js/materialize.min.js", "max-age=3600");

  server.serveStatic("/js/jquery-3.5.0.min.js", SPIFFS, "/js/jquery-3.5.0.min.js", "max-age=3600");
  server.serveStatic("/js/setupwifi.js", SPIFFS, "/js/setupwifi.js", "max-age=3600");
  server.serveStatic("/js/nipplejs.min.js", SPIFFS, "/js/nipplejs.min.js", "max-age=3600");
  server.serveStatic("/js/raphael-2.1.4.min.js", SPIFFS, "/js/raphael-2.1.4.min.js", "max-age=3600");
    server.serveStatic("/js/justgage.js", SPIFFS, "/js/justgage.js", "max-age=3600");

    server.serveStatic("/js/speedbat.js", SPIFFS, "/js/speedbat.js", "max-age=3600");

  server.serveStatic("/js/init.js", SPIFFS, "/js/init.js", "max-age=3600");

  // Get current state of the machine as a json object, ie. all variables that can be changed using the json API
  server.on("/api/get-state", HTTP_GET, [](AsyncWebServerRequest *request) {
    DynamicJsonBuffer jsonBuffer;
    JsonObject &jsonObj = jsonBuffer.createObject();

    AsyncResponseStream *response = request->beginResponseStream("application/json");
    jsonObj.printTo(*response);
    request->send(response);
  });

  // Get a single variable value from the machine
  AsyncCallbackJsonWebHandler *getValueHandler = new AsyncCallbackJsonWebHandler("/api/get-value", [](AsyncWebServerRequest *request, JsonVariant &json) {
    JsonObject &jsonObj = json.as<JsonObject>();


    /*
    if (getVariable(jsonObj["id"]) != NULL)
      jsonObj["v"] = *getVariable(jsonObj["id"]);
    else if (getPin(jsonObj["id"]) != -1)
      jsonObj["v"] = getPinValue(getPin(jsonObj["id"]));
    */
    AsyncResponseStream *response = request->beginResponseStream("application/json");
    jsonObj.printTo(*response);
    request->send(response);
  });

  // Set a variable value of the machine
  AsyncCallbackJsonWebHandler *setValueHandler = new AsyncCallbackJsonWebHandler("/api/set-value", [&](AsyncWebServerRequest *request, JsonVariant &json) {
    JsonObject &jsonObj = json.as<JsonObject>();

    /*
    setValue(jsonObj["id"], jsonObj["v"]);
    if (getVariable(jsonObj["id"]) != NULL)
      jsonObj["v"] = *getVariable(jsonObj["id"]);
     */ 
    AsyncResponseStream *response = request->beginResponseStream("application/json");
    jsonObj.printTo(*response);
    request->send(response);
  });

  // Start scanning access points
  server.on("/api/access-points", HTTP_GET, [](AsyncWebServerRequest *request) {
    AsyncResponseStream *response = request->beginResponseStream("application/json");
    DynamicJsonBuffer jsonBuffer;
    JsonObject &json = jsonBuffer.createObject();
    JsonArray &jsonAPs = json.createNestedArray("accessPoints");

    // Scan wifis and add to json
    int n = wifiScan();
    for (int i = 0; i < n; ++i)
    {
      JsonObject &accessPoint = jsonBuffer.createObject();
      accessPoint["SSID"] = WiFi.SSID(i);
      accessPoint["encryption"] = WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? false : true;
      jsonAPs.add(accessPoint);
    }
    json.printTo(*response);
    request->send(response);
  });

  // Set wifi parameters and try to to connect with them
  AsyncCallbackJsonWebHandler *setWifiHandler = new AsyncCallbackJsonWebHandler("/api/set-wifi", [&](AsyncWebServerRequest *request, JsonVariant &json) {
    AsyncResponseStream *response = request->beginResponseStream("application/json");

    ssid = json["SSID"];
    password = json["password"];

    DynamicJsonBuffer jsonBuffer;
    JsonObject &returnJson = jsonBuffer.createObject();

    accessPointMode = false;
    if (setupWifi())
    {
      writeFile("/ssid", ssid);
      writeFile("/password", password);
      returnJson["info"] = "Connected to " + String(ssid) + " with IP: " + WiFi.localIP().toString();
    }
    else
    {
      returnJson["info"] = "Couldn't connect to " + String(ssid);
    }

    returnJson.printTo(*response);
    request->send(response);
  });

 //json from joydata joystick movements
  AsyncCallbackJsonWebHandler *controlHandler = new AsyncCallbackJsonWebHandler("/api/joydata", [&](AsyncWebServerRequest *request, JsonVariant &json) {
    AsyncResponseStream *response = request->beginResponseStream("application/json");

    _distance = json["distance"];
   // Serial.println(_distance);
     _angle = json["direction"]["angle"];
   // Serial.println(_angle);
     _type = json["type"];

   // Serial.println(_type);
    _degre = json["angle"]["degree"];
    // Serial.println(_degre);

    //rotat();

    DynamicJsonBuffer jsonBuffer;
    JsonObject &returnJson = jsonBuffer.createObject();

    if (strcmp(_type, "end") == 0) {
     returnJson["info"] = "Stop";
     returnJson["speed"] = 0 ;
     } else
     {
    returnJson["info"] = "Driving";
    returnJson["speed"] = _distance ;
     }

    returnJson.printTo(*response);
    request->send(response);
  });

  //server.addHandler(getValueHandler);
  //server.addHandler(setValueHandler);
  server.addHandler(setWifiHandler);
   server.addHandler(controlHandler);
}

 void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
  initmotors();
  initializeSPIFFS();
  getSavedWifi();
  setupWifi();
  setupServer();
  server.begin();
}

void loop() {
 rotat();
 // put your main code here, to run repeatedly:
}
loops
arduino
esp32
arduino-c++
asked on Stack Overflow May 11, 2020 by user3047429 • edited May 11, 2020 by user3047429

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0