Hi,
I have the same problem in two different cases, my problem:
complete reset after trying to connect with a tcp client.
The two cases:
- in the main loop I try to do a get request using the tcp client every 5 seconds until I get the information I need from the server then I turn the wifi off. I’m not using delays in my code just checking how long passed with millis() to make sure 5 seconds passed before I try again.
2.After turning Wifi.on and waiting for connection meaning: while (WiFi.status() != WIFI_ON) { SPARK_WLAN_Loop() ; }
I try to do another get request to inform the server I’m done, again the core randomly crashes on me, and resets, usually I see blinking red lights before the full reset.
Its very crucial for me to report to the server without fault so I’ll implement a write to the eeprom and I’ll check if I have something there every time the core starts and report.
Anyone encountered something similar or have other workarounds to suggest?
Thank you!
Including the code, although its really a work in progress.
// This #include statement was automatically added by the Spark IDE.
#include "flashee-eeprom/flashee-eeprom.h"
// This #include statement was automatically added by the Spark IDE.
#include "neopixel/neopixel.h"
using namespace Flashee;
//Wifi & Http
TCPClient client;
char roshenShay[] = "rosenshay.com";
//Change object Id here CRUDE! TODO::change it
char urlGetDuration[] = "****?obj=11";
char urlCloseTask[] = "*****close_task.php?";
long httpGetTimer;
#define GETREQUESTCHECKDELAY 5000
// NeoPixel
#define NEOPIXEL_PIN D2
#define NUMOFPIXELS 24
#define NEOPIXEL_TYPE WS2812B
#define RED strip.Color(10, 0, 0)
#define GREEN strip.Color(0, 10, 0)
#define BLUE strip.Color(0, 0, 10)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMOFPIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE);
//Array to keep current color of each led on the strip
uint32_t leds[NUMOFPIXELS] ;
long currentTaskDuration;
long startTaskTime;
//Fading Led Variables
int colorFadeLevel = 10;
int LastLedToFade = 0;
boolean isRed = false;
boolean isLightGoingUp = true;
float calc ;
int ledLightIntensity = 5;
int fadeLevelArray[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
long fadeLedCheck = 0;
//End Fading
#define TIMEFRAME 300000
#define TIMECONSTRAINTBETWEENBUTTONCLICKS 10000
int numberOfLedsOn = NUMOFPIXELS;
//Button Variables
int button = D0;
long timeFromLastClick = 0;
//State variables
long taskScheduledDuration;
long endFillEffectCheck = 0;
int taskId;
int state = 0 ;
bool taskStarted = false;
bool DEBUG = true;
//object that will help in saving to eeprom
FlashDevice* flash;
void setup()
{
state = 0;
if (DEBUG){
Serial.begin(9600);
}
httpGetTimer = millis();
fillStrip(BLUE, NUMOFPIXELS);
taskScheduledDuration = 0;
pinMode(button, INPUT);
flash = Devices::createAddressErase();
}
bool once = true;
void loop()
{
if (once) {
//DEBUG!! REMOVE
//while (!Serial.available()) SPARK_WLAN_Loop();
char buf[50];
flash->read(buf, 0, 50);
debug("eeprom:");
debug(String(buf));
once = false;
}
switch (state)
{
//Waiting for Duration and debug flag (not yet implemented) from server
case 0: {
char args[] = " ";
getRequestWithDelay(roshenShay, urlGetDuration, args);
String result = checkForHttpResult();
if (result != "") {
getDurationFromHttpResult(result);
getTaskIDFromHttpResult(result);
}
if (taskScheduledDuration != 0) {
state = 1;
WiFi.off();
while (WiFi.status() != WIFI_OFF) {
SPARK_WLAN_Loop(); // run backgound task so wifi can turn off
}
fillStrip(0, NUMOFPIXELS);
refreshStrip();
}
}
break;
//standby until first button click
case 1: {
debug("WaitForFirstClick");
//go dark and wait for first click
fillStrip(0, NUMOFPIXELS);
if (checkButtonState()) {
state = 2;
}
}
break;
//Leds Count down until second button click, TODO:: or 5 minutes passed(not yet implemented)
case 2: {
debug("starting Led");
taskCountDown();
if (checkButtonState()) {
state = 3;
//debug
flash->writeString("testi", 0);
once = true;
}
}
break;
//
case 3: {
if (finishedBlueEffect()) {
state = 4;
}
}
break;
case 4: {
debug("Going out of sleep");
WiFi.on();
while (WiFi.status() != WIFI_ON) {
SPARK_WLAN_Loop() ; // run backgound task so wifi can turn on
}
state = 5;
}
break;
//Wait for connection to be made
case 5: {
String taskIdString = String(taskId);
String durationString = String(currentTaskDuration);
String argsString = "task=" + taskIdString + "&duration=" + durationString;
char charBuf[argsString.length() + 1];
argsString.toCharArray(charBuf, argsString.length() + 1) ;
flash->writeString(charBuf, 0);
debug(charBuf);
//TODO: Make sure connection does not fail and returns success, replace this 3 iterations with server response verification
getRequestWithDelay(roshenShay, urlCloseTask, charBuf);
String result = checkForHttpResult();
if (checkSuccessCloseTask(result)) {
state = 6;
debug(result);
}
}
break;
//check that returned OK meaning we finished the close task request
//Go to sleep till next time
case 6: {
debug("going to deep sleep");
fillStrip(0, NUMOFPIXELS);
refreshStrip();
Spark.sleep(SLEEP_MODE_DEEP, 20);
}
break;
}
refreshStrip();
}
String sendGetRequest(const char * server, const char * url, const char * args)
{
String result = "";
if (client.connect(server, 80)) {
debug("connected");
client.print("GET ");
client.print(url);
if (sizeof(args) > 3) {
client.print(args);
}
client.println(" HTTP/1.0");
client.println("Connection: close");
client.print("Host: ");
client.println(server);
client.println("Accept: text/html, text/plain");
client.println();
result = "connected";
} else
{
debug("connection failed");
result = "failed";
}
return result;
}
String getRequestWithDelay(char rosenShay[], char url[], char args[]) {
if (millis() - httpGetTimer > GETREQUESTCHECKDELAY ) {
httpGetTimer = millis();
return sendGetRequest(rosenShay, url, args);
}
else return "false";
}
void getDurationFromHttpResult(String result) {
if (checkForValidResult(result)) {
//Get only the content without the headers
String resultContent = result.substring(result.indexOf("\r\n\r\n"));
//Get the duration
String durationString = resultContent.substring(resultContent.indexOf(":") + 1);
taskScheduledDuration = stringToLong(durationString);
debug(" Duration : ");
debug(taskScheduledDuration);
}
}
void getTaskIDFromHttpResult(String result) {
if (checkForValidResult(result)) {
//Get only the content without the headers
String resultContent = result.substring(result.indexOf("\r\n\r\n"));
//Get the taskid
String taskIdString = resultContent.substring(0, resultContent.indexOf(":"));
taskId = (int)stringToLong(taskIdString);
debug(" taskId : ");
debug(taskId);
}
}
long stringToLong(String str) {
char longbuf[32]; // make this at least big enough for the whole string
cleanChars(longbuf, 32);
str.toCharArray(longbuf, sizeof(longbuf));
return atol(longbuf);
}
void cleanChars(char* charArray, int length) {
//make sure theres no garbage in the memory
for (int j = 0; j < length; j++) {
charArray[j] = *"";
}
}
bool checkForValidResult(String result) {
if (result.indexOf("\r\n\r\n") != -1) {
if (result.indexOf(":") > 0 ) {
return true;
} else
return false;
} else
return false;
}
String checkForHttpResult() {
String result = "";
bool stopClient = false;
while (client.available())
{
char letter = client.read();
//TODO:: Crude way of adding char to string, this was a quick bug fix, replace this code!
result += " ";
result[result.length() - 1] = letter;
}
if (!client.connected()) {
client.flush();
client.stop();
}
return result;
}
bool checkSuccessCloseTask(String result) {
if (result.length() > 0) {
if (result.indexOf("OK") != -1) {
return true;
}
}
return false;
}
bool checkButtonState() {
if (millis() - timeFromLastClick > TIMECONSTRAINTBETWEENBUTTONCLICKS ) {
if (digitalRead(button) == 1) {
timeFromLastClick = millis();
return true;
} else return false;
}
else return false;
}
void fillStrip(uint32_t color, int numberOfOnPixels) {
//Fill with green
for (int i = 0; i < NUMOFPIXELS; i++) {
if (i >= numberOfOnPixels) {
leds[i] = strip.Color(0, 0, 0);
}
else {
leds[i] = color;
}
}
}
void refreshStrip() {
//Updates all the leds on the strip
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, leds[i]);
}
strip.show();
}
void fadeLedEffect(int ledNumber, uint32_t color) {
if ( millis() - fadeLedCheck > 120) {
fadeLedCheck = millis();
//Fade the last led:
if (isLightGoingUp) {
colorFadeLevel++;
}
else {
colorFadeLevel--;
}
if (colorFadeLevel >= 10) {
isLightGoingUp = false;
}
else if (colorFadeLevel <= 0) {
isLightGoingUp = true;
}
}
if (ledNumber > 24) {
debug("Error in fadeLedEffect:led number larger then 24");
ledNumber = 24;
} else if (ledNumber < 0) {
debug("Error in fadeLedEffect:led number smaller then 0");
ledNumber = 0;
}
if (color == GREEN) {
leds[ledNumber] = GREEN * colorFadeLevel;
} else if (color == RED) {
leds[ledNumber] = RED * colorFadeLevel;
} else if (color == BLUE) {
leds[ledNumber] = BLUE * colorFadeLevel;
}
}
void taskCountDown(void) {
if (!taskStarted) {
currentTaskDuration = 0;
startTaskTime = millis();
taskStarted = true;
}
currentTaskDuration = millis() - startTaskTime;
//prevent led blink from the first led
if (currentTaskDuration == 0) {
currentTaskDuration++;
}
long timeLeft = taskScheduledDuration - currentTaskDuration;
debug(String(timeLeft));
//TODO:: FIX TASKS LONGER THEN TIMEFRAME HALTS THE PROGRAM
calc = (float)timeLeft / (float)TIMEFRAME;
if (calc > 1) {
calc = 1;
}
debug(String(calc));
numberOfLedsOn = (int)(abs(calc * NUMOFPIXELS));
//first led is 0 in the led array
numberOfLedsOn --;
if (numberOfLedsOn > 24) {
numberOfLedsOn = 24;
}
if (numberOfLedsOn < 0) {
numberOfLedsOn = 0;
}
//If we moved to another lead reset fade.
if (LastLedToFade != numberOfLedsOn) {
colorFadeLevel = 10;
isLightGoingUp = false;
}
LastLedToFade = numberOfLedsOn;
if ( timeLeft > 0) {
fillStrip(GREEN * ledLightIntensity, numberOfLedsOn );
isRed = false;
}
else {
fillStrip(RED * ledLightIntensity, numberOfLedsOn);
isRed = true;
}
if (!isRed) {
fadeLedEffect(LastLedToFade, GREEN);
}
else {
fadeLedEffect(LastLedToFade, RED);
}
}
bool finishedBlueEffect() {
if (millis() - endFillEffectCheck > 23) {
endFillEffectCheck = millis();
numberOfLedsOn++;
if ( numberOfLedsOn <= 24) {
fillStrip(BLUE, numberOfLedsOn);
}
else if ( numberOfLedsOn <= 48) {
fillStrip(BLUE, 48 - numberOfLedsOn);
}
else {
fadeLedEffect(0, BLUE);
return true;
}
}
return false;
}
void debug(String str) {
if (DEBUG) {
Serial.println(str);
}
}
void debug(long str) {
if (DEBUG) {
Serial.println(str);
}
}
void debug(int str) {
if (DEBUG) {
Serial.println(str);
}
}