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
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:
}
User contributions licensed under CC BY-SA 3.0