Dear all,
I have a strange issue since today and I can’t figure out what’s going on. The code below worked now for some while. I just had some issues with the UDP / WiFi stability and did some modifications. In particular I played around with SYSTEM_THREAD(ENABLED) to see if that solves the topic because in the forum someone has stated that this might solve it. But I have redone all changes and now my photon always crashes with the SOS (Hard fault) when the strip.show() method is beeing called. When I comment this out. the photon keeps running. So I was able to isolate this issue, but now I have no idea anymore.
The photon has firmware 0.6.0.
Any help is really appreciated!
Heres the code:
SYSTEM_MODE(MANUAL);
//STARTUP(WiFi.selectAntenna(ANT_INTERNAL)); // selects the CHIP antenna
//STARTUP(WiFi.selectAntenna(ANT_EXTERNAL)); // selects the u.FL antenna
STARTUP(WiFi.selectAntenna(ANT_AUTO)); // continually switches at high speed between antennas
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
// This #include statement was automatically added by the Particle IDE.
#include "my_helpers.h"
// This #include statement was automatically added by the Particle IDE.
#include <PietteTech_DHT.h>
//#################################################################
// GLOBAL DEFINITIONS
//#################################################################
// Define the LED strip parameters
#define PIXEL_COUNT 70 // Number of Pixels (1 Pixel = 10 cm)
#define PIXEL_PIN D0 // Pin of the data connection to the strip
#define PIXEL_TYPE TM1829 // Strip controller type
// Define the Temperature Sensor parameters
#define DHTPIN D2 // Digital pin for communications
#define DHTTYPE DHT22 // Sensor type DHT11/21/22/AM2301/AM2302
// Define the UDP parameters
const int UDP_TX_PACKET_MAX_SIZE=1024; //UDP package size
const unsigned int localPort = 8888; //UDP Port used for two way communication
const unsigned int localPortLED = 8001; //UDP Port used to ping back the LED color
const unsigned int localPortMeasures = 8002; //UDP Port used to ping back the Temperature
const unsigned int OH_Port = 25002; //UDP Port to send the data to
const IPAddress OpenHabIP(192,168,178,134); //IP Adress of the openhab server. This is needed when the connection is initated by the photon and not by OH
const unsigned long beat_rate = 10000; // hearbeat rate to do something every some seconds
// Switch debugging on(1)/off(0)
const int debug = 1;
//#################################################################
// Needed Objects
//#################################################################
// An UDP instance to let us send and receive packets over UDP
UDP Udp;
// create some helping fuctions
my_helpers h = my_helpers(debug);
// construct the strip object
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
//buffer to hold incoming packet
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
// Temperature Sensor instantiate
PietteTech_DHT DHT(DHTPIN, DHTTYPE);
//#################################################################
// The Variables we need
//#################################################################
// timer to do something every x seconds
unsigned long time_stamp = 0;
// the port of the remote device sending the command
int remoteport= 0;
// the IP address of the remote device sending the command
IPAddress remoteIP(0,0,0,0);
// the measured DHT Humidity
String Humidity = "";
// the measured DHT Temperature
String Temperature = "";
// the RGB Value for the LED Strip
int RGBValues[3];
// the number of pixels we want to change individually
int pixels;
// the array to store the ID of the pixel and the color
int Pixel[4];
// the data pack to send back to the sender
char callbackData[0];
int DHTerrorcode;
// The temperature & humidity data which gets send back
String measured_values ="";
// The MAC Address of the access point
byte bssid[6];
// size of the received UDP Package
//int packetSize;
//count the loops for debuging
unsigned long loopcount = 0;
//String datagram ="";
//#################################################################
// Setup
//#################################################################
void setup() {
// Print your device IP Address via serial for debuging
if (debug == 1){Serial.begin(9600);}
if (debug == 1){delay (8000);}
// connect to the hood
WiFi.on();
// connect to my network
WiFi.setCredentials("mywlan", "topsecrect");
WiFi.connect();
while(!WiFi.ready());
if (debug == 1){Serial.print("My IP: ");}
if (debug == 1){Serial.println(WiFi.localIP());}
// start the UDP
Udp.begin(localPort);
//Setup the strip & initialize all pixels to 'off'
strip.begin();
strip.show();
Particle.syncTime(); // Sync time with cloud
Time.zone(1); // From UTC to CET
if (debug == 1){Serial.print("Current time: ");}
if (debug == 1){Serial.println(Time.timeStr());} // Wed May 21 01:08:47 2014
} // end setup
//#################################################################
// LOOP
//#################################################################
void loop() {
int packetSize = Udp.parsePacket();
memset(&packetBuffer[0], 0, sizeof(packetBuffer));
if(packetSize)
{
if (debug == 1){Serial.print("Received packet of size ");}
if (debug == 1){Serial.println(packetSize);}
if (debug == 1){Serial.print("From ");}
remoteIP = Udp.remoteIP();
remoteport = Udp.remotePort();
// Print the remote IP & port
if (debug == 1)
{for (int i =0; i < 4; i++){
Serial.print(remoteIP[i], DEC);
if (i < 3){Serial.print(".");}}}
if (debug == 1){Serial.print(", port ");}
if (debug == 1){Serial.println(remoteport);}
// read the packet into packetBufffer
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
if (debug == 1){Serial.println("Contents UDP datagram:");}
if (debug == 1){Serial.println(packetBuffer);}
//store the datagram
String datagram = String(packetBuffer);
// DO CHANGES TO THE LED STRIP
// ff = function number e.g. 01, 02 ...
// rrr, ggg, bbb RGB values 0 - 255
// ppp = pixel number 000 - 999
switch (datagram.substring(0,2).toInt())
{
//#####################################################################################################################
case 0: // 0 = Off: Switch off the strip
colorAll(strip.Color(0, 0, 0), 0);
break; // end if ("Off")
//#####################################################################################################################
case 1: // 1 = ColorWipe: change the strip pixel by pixel. data package: ffrrrgggbbb
h.RGBFromString(RGBValues, datagram.substring(2));
if (debug == 1){Serial.println("ColorWipe");}
if (debug == 1){Serial.println("Data: ");}
if (debug == 1){Serial.println(datagram.substring(2));}
if (debug == 1){Serial.println("RGB Values: ");}
if (debug == 1){Serial.println(RGBValues[0]);}
if (debug == 1){Serial.println(RGBValues[1]);}
if (debug == 1){Serial.println(RGBValues[2]);}
colorWipe(strip.Color(RGBValues[0], RGBValues[1], RGBValues[2]), 300);
//echo back the UDP message
h.UDP_callback(localPortLED, packetBuffer, remoteIP, OH_Port);
break; // end else if ("ColorWipe")
//#####################################################################################################################
case 2: // 2=ColorAll: change the strip at once. data package: ffrrrgggbbb
h.RGBFromString(RGBValues, datagram.substring(2));
if (debug == 1){Serial.println("ColorAll");}
if (debug == 1){Serial.println("Data: ");}
if (debug == 1){Serial.println(datagram.substring(2));}
if (debug == 1){Serial.println("RGB Values: ");}
if (debug == 1){Serial.println(RGBValues[0]);}
if (debug == 1){Serial.println(RGBValues[1]);}
if (debug == 1){Serial.println(RGBValues[2]);}
colorAll(strip.Color(RGBValues[0], RGBValues[1], RGBValues[2]), 0);
//echo back the UDP message
h.UDP_callback(localPortLED, packetBuffer, remoteIP, OH_Port);
break; // end else if (command == "ColorAll")
//#####################################################################################################################
case 9: // 9 = Pixel: control one ore more pixel individually data package: ffppprrrgggbbbppprrrgggbbb...
// determine the number of pixels we have to change. one pixel control package has always 12 characters in the data package (ppprrrgggbbb).
// so the number of pixels is the length of the data package / 12
pixels = (datagram.length()-2) / 12;
if (debug == 1){Serial.println("Pixel");}
if (debug == 1){Serial.println("Data: ");}
if (debug == 1){Serial.println(datagram.substring(2));}
// fill the pixel array from the data package
for (int i=0; i < pixels; i++)
{
h.pixeldata (Pixel, datagram.substring((i+2) * 12, ((i+2) * 12) + 12)); // cut the data package into the pixel control packages
strip.setPixelColor(Pixel[0], strip.Color(Pixel[1], Pixel[2], Pixel[3]));
if (debug == 1){Serial.println("Pixel Data: ");}
if (debug == 1){Serial.println(Pixel[0]);}
if (debug == 1){Serial.println(Pixel[1]);}
if (debug == 1){Serial.println(Pixel[2]);}
if (debug == 1){Serial.println(Pixel[3]);}
}
strip.show();
//echo back the UDP message
h.UDP_callback(localPortLED, packetBuffer, remoteIP, OH_Port);
break; // end else if ("Pixel")
//#####################################################################################################################
case 8: // 8 = Temp: return temperature and humidity
sendTemp(remoteIP);
break; // end else if ("Temp")
} // end switch
//#####################################################################################################################
} // end if(packetSize)
// Do something every some seconds
if (time_stamp < millis()){
// This was recommended by the forum. Sometimes the UDP just stops receiving packages
Udp.stop();
delay(1);
Udp.begin(localPort);
// Show some WiFi data for debugging
if (debug == 1){Serial.print("My IP: ");}
if (debug == 1){Serial.println(WiFi.localIP());}
if (debug == 1){Serial.println("Connected to Accesspoint: ");}
if (debug == 1){WiFi.BSSID(bssid);}
if (debug == 1){Serial.printlnf("%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); }
if (debug == 1){Serial.println("signal strength from -127 (weak) to -1dB (strong):"); }
if (debug == 1){Serial.println(WiFi.RSSI());}
sendTemp(OpenHabIP);
loopcount++;
time_stamp = millis() + beat_rate;
} //end loop timer
} //end loop function
//#################################################################
// Some Functions
//#################################################################
// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) {
uint16_t i;
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
delay(wait);
}
// Fill the dots one after the other with a color, wait (ms) after each one
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
// Send temperature and humidity via a small JSON to a specific IP
void sendTemp (IPAddress sendtoIP)
{
DHTerrorcode = DHT.acquireAndWait();
if (debug == 1){switch (DHTerrorcode) {
case DHTLIB_OK:
Serial.println("OK");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Error\n\r\tChecksum error");
break;
case DHTLIB_ERROR_ISR_TIMEOUT:
Serial.println("Error\n\r\tISR time out error");
break;
case DHTLIB_ERROR_RESPONSE_TIMEOUT:
Serial.println("Error\n\r\tResponse time out error");
break;
case DHTLIB_ERROR_DATA_TIMEOUT:
Serial.println("Error\n\r\tData time out error");
break;
case DHTLIB_ERROR_ACQUIRING:
Serial.println("Error\n\r\tAcquiring");
break;
case DHTLIB_ERROR_DELTA:
Serial.println("Error\n\r\tDelta time to small");
break;
case DHTLIB_ERROR_NOTSTARTED:
Serial.println("Error\n\r\tNot started");
break;
default:
Serial.println("Unknown error");
break;
}} // end debug switch
//Get the Humidity
Humidity = String(DHT.getHumidity(), 2);
if (debug == 1){Serial.print("Humidity (%): ");}
if (debug == 1){Serial.println(Humidity);}
//Get the Temperature
Temperature = String(DHT.getCelsius(), 2);
if (debug == 1){Serial.print("Temperature (oC): ");}
if (debug == 1){Serial.println(Temperature);}
// Create a JSON Feedback e.g.: {"T1":25.21,"H1":40.43}
measured_values = "{\"Time\":\"" + Time.timeStr() + "\",\"T1\":" + Temperature + ",\"H1\":" + Humidity + ",\"Loops\":" + loopcount + "}";
memset(&callbackData, 0, measured_values.length());
measured_values.toCharArray(callbackData, measured_values.length()+1);
if (debug == 1){Serial.print("Values to send: ");}
if (debug == 1){Serial.println(callbackData);}
if (debug == 1){Serial.print("Sending to IP: ");}
if (debug == 1){Serial.println(sendtoIP);}
if (debug == 1){Serial.print("Port: ");}
if (debug == 1){Serial.println(OH_Port);}
if (debug == 1){Serial.print("From Port: ");}
if (debug == 1){Serial.println(localPortMeasures);}
h.UDP_callback(localPortMeasures, callbackData, sendtoIP, OH_Port);
}