Strange If Statement Behavior on ESP32-S3
Posted: Mon Mar 11, 2024 5:59 pm
Hello! I am working on a project and writing a custom library, in which I have found a weird if statement bug.
Here is my .h file:
Here is my .cpp file:
Pretty much no matter what, the if statement in the handlePaq function, "if (accessPtr->PaqsCollected == accessPtr->reqCount)" evaluates to true. I am printing the values of those integers inside the if statement, and I can clearly see that they are not equal. If I print the value of that bool outside of the if statement, it is false, but if I print it inside, it is true. It doesn't matter if I assign the integers to local or global variables and then evaluate them in the if statement. The only way I have gotten the if statement to return false is by literally writing if (false). I have tried increasing stack size increase it is some weird memory error to no avail. I also tried disabling compiler optimization to no avail. It may be something dumb I'm overlooking, I am unsure. Any help is greatly appreciated. Thank you!
Here is my .h file:
Code: Select all
#include <Arduino.h>
#include <ArduinoJson.h>
#include <painlessMesh.h>
#include <UARTProtocol.h>
#include <EasyTransfer.h>
#ifndef NMESHMANAGE_H
#define NMESHMANAGE_H
#define DEFAULTPAQARRAY {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}
class sensor {
public:
int ID;
int outerID;
int axis;
int *axisIDs;
char **axisVals;
//0 = pending certification
//1 = ready to request
//2 = pending response
int *state;
sensor *nextSensor;
char encryptString[65];
unsigned long lastReqTime[9];
};
class Paq {
public:
int PaqID;
int reqCount;
int PaqsCollected;
unsigned long birthday;
int *waitingOn;
int *axisIds;
const char **axisLbls;
float *data;
Paq () { PaqsCollected = 0; reqCount = 0;}
};
//initialize the connection of a sensor
//return vals
//0 = success
//1 =
int initSensor(uint32_t from, painlessMesh &mesh, DynamicJsonDocument &msgDoc);
//validate encrypt
//0 = success
//1 = incorrect
//2 = fail
int validateSensor(int ID, char* cypher);
//request neccessary data
//0 = success
//1 =
int requestData(painlessMesh &mesh);
//handle incoming data
//0 = success
//1 = failed to match paq id
int handlePaq(uint32_t from, DynamicJsonDocument &msgDoc, SEND_DATA_STRUCTURE &txpaq, EasyTransfer &UARTout);
int disconnectSensor(int ID);
//0 = all good
//1 = lagger found
int findLaggers();
//polling rate lookup table
//in hertz
int pollingPeriodLookup(const char* tag);
int PollSensorsConnected();
#endif
Code: Select all
#include <Arduino.h>
#include <ArduinoJson.h>
#include <painlessMesh.h>
#include <Cipher.h>
#include <UARTProtocol.h>
#include <EasyTransfer.h>
#include <newMeshManage.h>
#define PAQ_TIMEOUT 5000
int sensorsConnected;
int axisConnected;
int validatedSensors;
int packCount;
int lastCheckedPaq;
int lastCheckedID;
sensor *firstSens;
char* key = "bUcgPYcMfmYSZAWF";
Cipher * cipher = new Cipher();
Paq *paqArray[20] = DEFAULTPAQARRAY; //number can be changed but this is basically the amount of open paqs we can manage at a time
//only stores 2 ints so memory usage is very small
int openPaqs = 0;
void cryptoString(int length, char* output) {
char* eligible_chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890";
randomSeed(esp_random());
for (int i = 0; i < length; i++) {
uint8_t random_index = random(0, 61);
*output = eligible_chars[random_index];
output++;
}
}
int initSensor(uint32_t from, painlessMesh &mesh, DynamicJsonDocument &msgDoc) {
Serial.println("MESH: INIT NEW SENSOR");
sensor *newSens = new sensor;
newSens->outerID = from;
newSens->axis = msgDoc["axis"];
if (sensorsConnected == 0) {
firstSens = newSens;
} else {
sensor *newest = firstSens;
for (int i = 1; i < sensorsConnected; i++) {
newest = newest->nextSensor;
}
newest->nextSensor = newSens;
}
newSens->axisVals = new char*[newSens->axis];
for (int i = 0; i < newSens->axis; i++) {
newSens->axisVals[i] = new char[6];
}
newSens->axisIDs = new int[newSens->axis];
for (int i = 0; i < newSens->axis; i++) {
strcpy(newSens->axisVals[i], msgDoc["axisTags"][i]);
axisConnected ++;
newSens->axisIDs[i] = axisConnected;
}
newSens->state = new int[newSens->axis];
for (int i = 0; i < newSens->axis; i++) {
newSens->state[i] = 0;
}
sensorsConnected ++;
StaticJsonDocument<1024> doc;
doc["to"] = from;
cipher->setKey(key);
char encryptString[65];
encryptString[64] = '\0';
cryptoString(64, encryptString);
strcpy(newSens->encryptString, encryptString);
doc["crypt"] = cipher->encryptString(encryptString);
String tempString = doc["crypt"];
newSens->ID = sensorsConnected;
doc["newID"] = newSens->ID;
doc["topic"] = "cert";
char msgOut[measureJson(doc)];
serializeJson(doc, msgOut, measureJson(doc));
mesh.sendSingle(from, msgOut);
return 0;
}
int validateSensor(int ID, char* cypher) {
Serial.println("MESH: VALIDATING SENSOR");
unsigned long timeTag = millis();
bool matchedID;
sensor *match = firstSens;
for (int i = 0; i < sensorsConnected; i++) {
if (match->ID == ID) {
matchedID = true;
break;
} else {
for (int z = 0; z < 9; z++) {
match->lastReqTime[z] = timeTag;
}
match = match->nextSensor;
}
}
if (matchedID != true) {
return 2;
//should delete sensor and likely send NACK packet
}
if (strcmp(match->encryptString, cypher) == 0) {
validatedSensors ++;
for (int i = 0; i < match->axis; i++) {
match->state[i] = 1;
}
Serial.println("MESH: VALIDATING SUCCESS");
return 0;
} else {
for (int i = 0; i < match->axis; i++) {
delete match->axisVals[i];
}
delete match->axisIDs;
delete match;
return 1;
}
return 2;
}
int requestData(painlessMesh &mesh) {
sensor *accessPtr = firstSens;
StaticJsonDocument<1024> msg;
bool haveNeed = false;
int reqs = 0;
JsonObject temp = msg.createNestedObject("need");
unsigned long currentTime = millis();
int waitOnBuilder[validatedSensors];
for (int i = 0; i < validatedSensors; i++) {
if (!i == 0) {
accessPtr = accessPtr->nextSensor;
}
JsonObject need = temp.createNestedObject(String(accessPtr->ID));
for (int z = 0; z < accessPtr->axis; z++) {
int pollingPeriod = pollingPeriodLookup(accessPtr->axisVals[z]);
if ((currentTime - accessPtr->lastReqTime[z] >= pollingPeriod*1000 - 10) && (accessPtr->state[z] == 1)) { //-10 for travel time, can be optimized
need[String(z)] = 1;
haveNeed = true;
accessPtr->lastReqTime[z] = currentTime;
accessPtr->state[z] = 2;
waitOnBuilder[reqs] = accessPtr->axisIDs[z];
reqs++;
} else {
need[String(z)] = 0;
}
}
}
if (haveNeed == true) {
msg["topic"] = "req";
msg["paqID"] = packCount;
Paq *newPaq = new Paq;
newPaq->PaqID = packCount;
newPaq->reqCount = reqs;
newPaq->data = new float[reqs];
newPaq->axisIds = new int[reqs];
newPaq->axisLbls = new const char*[reqs];
newPaq->waitingOn = new int[reqs];
for (int i = 0; i < reqs; i++) {
Serial.println(i);
newPaq->waitingOn[i] = waitOnBuilder[i];
}
newPaq->birthday = millis();
//for (int i = 0; i < reqs; i++) {
// newPaq->axisLbls[i] = new char[6];
//}
paqArray[openPaqs] = newPaq;
openPaqs++;
char docOut[measureJson(msg)];
serializeJson(msg, docOut, measureJson(msg));
serializeJson(msg, Serial);
mesh.sendBroadcast(docOut);
Serial.println("MESH: SENT DATA REQ");
packCount ++;
}
return 0;
}
int handlePaq(uint32_t from, DynamicJsonDocument &msgDoc, SEND_DATA_STRUCTURE &txpaq, EasyTransfer &UARTout) {
Serial.println("MESH: HANDLING PAQ");
if (msgDoc["ID"] == lastCheckedID && msgDoc["paqID"] == lastCheckedPaq) {
Serial.print("DUPEPAQ: ");
Serial.println(int(msgDoc["paqID"]));
return 1;
}
Paq *accessPtr = nullptr;
for (int i = 0; i < openPaqs; i++) {
if (paqArray[i]->PaqID == msgDoc["paqID"]) {
accessPtr = paqArray[i];
break;
}
}
if (accessPtr == nullptr) {
Serial.println("NULLPAQREFERENCED");
return 1;
}
sensor *sensPtr = firstSens;
while (1) {
if (sensPtr->ID == msgDoc["ID"]) {
break;
} else {
sensPtr = sensPtr->nextSensor;
}
}
lastCheckedID = msgDoc["ID"];
lastCheckedPaq = msgDoc["paqID"];
int dataAdded = 0;
for (int i = 0; i < msgDoc["data"].size(); i++) {
String test = msgDoc["data"][i];
if (strcmp("null", test.c_str()) == 0) {
Serial.println("null got");
continue;
}
accessPtr->axisIds[i + accessPtr->PaqsCollected] = sensPtr->axisIDs[i];
accessPtr->data[i + accessPtr->PaqsCollected] = msgDoc["data"][i];
accessPtr->axisLbls[i + accessPtr->PaqsCollected] = sensPtr->axisVals[i];
sensPtr->state[i] = 1;
dataAdded ++;
}
if (dataAdded == 0) {
return 0;
}
accessPtr->PaqsCollected += dataAdded;
if (accessPtr->PaqsCollected == accessPtr->reqCount) {
Serial.println(accessPtr->PaqsCollected == accessPtr->reqCount);
Serial.print("reqs");
Serial.println(accessPtr->reqCount);
Serial.print("collect");
Serial.println(accessPtr->PaqsCollected);
Serial.println(uxTaskGetStackHighWaterMark(NULL));
SEND_DATA_STRUCTURE txdata;
txdata.parts = (accessPtr->PaqsCollected + 16) / 16;
int offset = 0;
bool catchEnd = false;
int count = 0;
for (int i = 0; i < accessPtr->PaqsCollected; i++) {
txdata.data[i - offset] = accessPtr->data[i];
txdata.ids[i - offset] = accessPtr->axisIds[i];
strcpy(txdata.axislbl[i - offset], accessPtr->axisLbls[i]);
txdata.recieptType = 0;
txdata.status = 1;
if (i+1 >= 16 + offset) {
txpaq = txdata;
SEND_DATA_STRUCTURE temp;
txdata = temp;
txdata.parts = (accessPtr->PaqsCollected + 16) / 16;
UARTout.sendData();
offset += 16;
}
if (i + 1 == 48) {
catchEnd = true;
}
count ++;
}
if (catchEnd == false) {
txpaq = txdata;
strcpy(txpaq.axislbl[count - offset], "null_");
Serial.println("PACK TRANSFERED");
UARTout.sendData();
}
//for (int i = 0; i < accessPtr->reqCount; i++) {
// delete[] accessPtr->axisLbls[i];
//}
delete[] accessPtr->data;
delete[] accessPtr->axisIds;
delete[] accessPtr->axisLbls;
delete[] accessPtr->waitingOn;
//paqArray[openPaqs - 1] = nullptr;
delete accessPtr;
openPaqs --;
return 0;
}
}
int disconnectSensor(int ID) {
for (int i = 0; i < sensorsConnected; i++) {
}
}
int findLaggers() {
Paq *paqptr;
for (int i = 0; i < openPaqs; i++) {
paqptr = paqArray[i];
if (paqptr == nullptr) {
break;
} else {
if (millis() - paqptr->birthday >= PAQ_TIMEOUT) {
sensor *sensPtr = firstSens;
for (int z = 0; z < sensPtr->axis; z++) {
for (int y = 0; y < paqptr->reqCount; y++) {
if (sensPtr->axisIDs[z] == paqptr->waitingOn[y]) {
sensPtr->state[z] = 1;
}
}
}
delete[] paqptr->data;
delete[] paqptr->axisIds;
delete[] paqptr->axisLbls;
delete[] paqptr->waitingOn;
delete paqptr;
for (int z = 0; z < openPaqs - i; z++) {
paqArray[i - z] = paqArray[i - z + 1];
}
openPaqs --;
return 1;
}
}
}
return 0;
}
int pollingPeriodLookup(const char* tag) {
if (strcmp(tag, "bme_t") == 0) {
return 1;
}
if (strcmp(tag, "bme_p") == 0) {
return 1;
}
if (strcmp(tag, "bme_h") == 0) {
return 1;
}
if (strcmp(tag, "therm") == 0) {
return 1;
} //add as sensors are developed
return 1;
}
int PollSensorsConnected() {
return validatedSensors;
}