Old code that I know 100% sure was working properly for the serial communication:
// ##### ####### ####### ####### ### # # ##### #####
// # # # # # # ## # # # # #
// # # # # # # # # # #
// ##### ##### # # # # # # # #### #####
// # # # # # # # # # # #
// # # # # # # # ## # # # #
// ##### ####### # # ### # # ##### #####
//BEFORE DEPLOYMENT CHANGE THE FOLLOWING VALUES TO THAT OF THE LOCATION!!!
//Location's WiFi information
const char* SSID_Location = "XXXXXXXX"; //WiFi network name
const char* PASS_Location = "XXXXXXXX"; //Password of the network.
//The location in our database, don't forget: create location in database.
const int location = 4; //this is a predefined location found in the database.
//At what time the device should go to sleep.
const float sleepHour = 18;
const float sleepMinute = 3;
//At what time the device should wake up.
const float wakeupHour = 7;
const float wakeupMinute = 30;
//MAKE SURE ALL THESE VARIABLES ARE SET PROPERLY BEFORE DEPLOYING THE DEVICE AT THE LOCATION.
// # # ### ####### ###
// # # # # # #
// # # # # # #
// # # # # ##### #
// # # # # # #
// # # # # # #
// ## ## ### # ###
//WIFI CREDENTIALS for development
/*DO NOT CHANGE*/ const char* SSID = "XXXXXXXX";
/*DO NOT CHANGE*/ const char* PASS = "XXXXXXXX";
// # ### ###### ###### # ###### ### ####### #####
// # # # # # # # # # # # # # #
// # # # # # # # # # # # # #
// # # ###### ###### # # ###### # ##### #####
// # # # # # # ####### # # # # #
// # # # # # # # # # # # # # #
// ####### ### ###### # # # # # # ### ####### #####
#include <RunningMedian.h> //Averages the sensorValues to prevent false positives.
//Library by Rob Tillaart, https://github.com/RobTillaart
// # # # ###### ### # ###### # ####### #####
// # # # # # # # # # # # # # # #
// # # # # # # # # # # # # # #
// # # # # ###### # # # ###### # ##### #####
// # # ####### # # # ####### # # # # #
// # # # # # # # # # # # # # # #
// # # # # # ### # # ###### ####### ####### #####
//TIME RELATED MEASUREMENTS / TIMED ACTIVITIES
int tHour; //stores the hours
int tMinute; //stores the minutes
int tDay; //Used to know when it's weekend. 5, 6, 7 = Friday, Saturday, Sunday
int mMinute = 60; //used as a modulo to dictate time intervals (modulo is not necessary if you push only once per hour).
int tSecond; //stores the seconds
int dSecond = 60; //used to store when a data transfer can be initiated
int sOffset = 5; //after dSecond + sOffset the data transfer will begin
int cooldown = 750; //Cooldown periods ensuring certain functions are done properly.
//Moment for debugging, make sure this falls within the active / non sleep periods.
int debugStartHour = 9; //Starting hour of the debug interval
int debugStartMinute = 0; //Starting minute of the debug interval
int debugEndHour = 9; //Ending hour of the debug interval
int debugEndMinute = 15; //Ending minute (exclusive) of the debug interval
bool debugMode = false; //Used for other functions to detect if the device is in debug mode.
unsigned long printTimer; //Used to make the printing happen less often (once every interval)
int prInterval = 100; //Print interval
//Based on what time the device should go to sleep and wake up, the sleep time in seconds is calculated.
//DO NOT CHANGE THE FOLLOWING FORMULAS, THIS AUTOMATICALLY CALCULATES THE SLEEPTIME!
const long sleepTime = int((((24 - sleepHour) - (sleepMinute / 60) + wakeupHour + (wakeupMinute / 60)) * 3600) - 120);
const long sleepTimeWeekend = int(sleepTime + 172800); //sleepTime + 2 weekend days of 2 * 24 * * 60 * 60 seconds.
//PUBLISHSTRING used to Publish the location and value to the Particle Cloud.
char publishString[40];
//TRANSMISSION CONFIRMATIONS
int wifiState = 0; //Used to know if WiFi is on, working, connected and if a dataPublish is possible.
unsigned long stateTimer; //Used to make sure the wifiState has enough 'delay' to process all commands.
//DISTANCE SENSOR
int sensorPin = (A0); //Pin that reads out the values of the distence sensor
int sensorValue; //Raw sensor values
bool sensorState = false; //Used to know if sensor is low, high or recently low, prevents multiple data additions to value. Range is 0, 1, 2.
uint16_t value = 0; //Amount of people that walked by.
int statePin = D5; //The pin which turns the sensor on or off (connected to low-end transistor)
int oST = 1000; //Original sensorThreshhold
int sensorThreshold = oST; //Threshold of the sensor (above this value and somebody walked by).
int sensorOffset = 300; //When threshold is met, apply filter to ensure no flickering readings.
unsigned long sensorTimer; //Used to make sure there are not constant readings or value additions from the sensor.
int sensorTimeOffset = 333; //The amount of time that has to pass between high and low reading of the sensor.
int sensorMedian; //The actual average that's getting output from the value sensorValues RunningMedian.
int sampleSize = 100; //The size of the samples to be used in the RunningMedian
RunningMedian sensorValues = RunningMedian(sampleSize); //Creates an array to average the data which then gets stored in value.
//FIRST RUN & EEPROM DATA
bool firstRun = true; //Used to activate several parts of the Photon before continuing.
int eepromAddress[] = {0, 2}; //Address of the stored values in EEPROM (uint16_t = 2 bytes)
uint16_t eepromValue1; //Value 1, compared to value 2.
uint16_t eepromValue2; //Value 2, compared to value 1.
//Two values are used to ensure that there's *always* a backup value.
//If one fails, the other one can still be used (due to i.e. a power cut)
// ##### ####### ####### # # ######
// # # # # # # # #
// # # # # # # #
// ##### ##### # # # ######
// # # # # # #
// # # # # # # #
// ##### ####### # ##### #
void setup(){
//Setting up the credentials for WiFi
//Multiple credentials for the deploy location and development location
WiFi.setCredentials(SSID, PASS);
WiFi.setCredentials(SSID_Location, PASS_Location);
//Initiates the statePin as an output pin, to turn the sensor on or off.
pinMode(statePin, OUTPUT);
//Initiates a serial communication.
Serial.begin(9600);
}
// # ####### ####### ######
// # # # # # # #
// # # # # # # #
// # # # # # ######
// # # # # # #
// # # # # # #
// ####### ####### ####### #
void loop(){
//This is executed when Photon turns on (this includes after a deep sleep)
while(firstRun == true){
photonWakeUp();
}
//Functions used to gather data.
detectTime(); //Detects time
readSensor(); //Reads the distance sensor to detect passersby.
//Function doing something with the gathered data.
timedActivities(); //Ensures time related activities are being executed, including dataPublish.
//Function to debug baed on the gathered data.
serialPrint(); //Used to communicate data to a serial monitor, i.e. the computer.
}
// ####### ### # # ####### #####_
// # # ## ## # # #
// # # # # # # # # #
// # # # # # ##### # #
// # # # # # # #
// # # # # # # #
// # ### # # ####### #####`
// # ##### ####### ### # # ### ####### ### ####### #####
// # # # # # # # # # # # # # #
// # # # # # # # # # # # #
// # # # # # # # # # # ##### #####
// ####### # # # # # # # # # #
// # # # # # # # # # # # # # #
// # # ##### # ### # ### # ### ####### #####
//All activities related to timing and specific moments of when they need to be executed.
//Including the intervalled dataPublish.
void timedActivities(){
//=========================================================================//
//DEBUG WINDOW
//The Photon is turned on to make it possible to debug, upload new code and so on.
if(tHour >= debugStartHour && tHour <= debugEndHour && tMinute >= debugStartMinute && tMinute < debugEndMinute){
if(WiFi.ready()){
debugMode = true;
}
else{
WiFi.on();
WiFi.connect();
}
}
else{
debugMode = false;
}
//=========================================================================//
//=========================================================================//
//SLEEPMODE
//At a specified moment, the Photon goes into a timed deep sleep mode.
//This sleepTime is automatically calculated based on the settings.
//But first, it checks if there's still data that hasn't been pushed.
//Sleep mode otherwise flushes this data, so it must be sent before sleep.
if(tHour == sleepHour && tMinute == sleepMinute){
if(value != 0){
tMinute = mMinute = 0;
}
else{
photonSleep();
}
}
//=========================================================================//
//=========================================================================//
//DATAPUBLISH
//At a specified interval a data transfer will be initiated.
if(tMinute % mMinute == 0){
switch (wifiState){
case 0:
WiFi.on();
WiFi.connect();
wifiState++;
break;
case 1:
if(WiFi.ready()){
wifiState++;
stateTimer = millis();
}
break;
case 2:
if(millis() > stateTimer + cooldown){
Particle.process();
wifiState++;
stateTimer = millis();
}
break;
case 3:
if(millis() > stateTimer + cooldown){
if(Particle.connected()){
wifiState++;
stateTimer = millis();
}
}
break;
case 4:
if(millis() > stateTimer + cooldown){
dataPublish();
wifiState++;
}
break;
case 5:
if(debugMode == false){
WiFi.off();
}
break;
}
}
else {
wifiState = 0;
if(debugMode == false){
WiFi.off();
}
}
//=========================================================================//
}
// ##### ####### # # ####### ######
// # # # # # # # #
// # # # # # # # #
// # # # ####### ##### ######
// # # # # # # # #
// # # # # # # # #
// ##### # # # ####### # #
// ####### # # # # ##### ####### ### ####### # # #####
// # # # ## # # # # # # # ## # # #
// # # # # # # # # # # # # # # #
// ##### # # # # # # # # # # # # # #####
// # # # # # # # # # # # # # # #
// # # # # ## # # # # # # # ## # #
// # ##### # # ##### # ### ####### # # #####
//Publishes the location and the value to the Particle Cloud.
//The Particle Cloud uses a webhook to store this information in the database.
void dataPublish(){
//Converts the location and value into a string with identifiers (var1, var2)
sprintf(publishString, "{\"var1\": %u, \"var2\": %u}", location, value);
//The string is published under the identifier "trap"
//The Trapteller webhook is triggered by this identifier.
Particle.publish("trap", publishString);
//To make sure the publish is done properly, a cooldown is added.
//When not using if/for/switch functions, make sure this cooldown is 1 second.
delay(cooldown);
value = 0; //Resets the value after it has been sent.
}
//Time is synced with the Particle cloud and the values are stored
void detectTime(){
//Time correction because Particle Cloud is in another timezone than the Photon.
tHour = Time.hour() + 2;
if(tHour > 24){
tHour - 24;
}
tMinute = Time.minute();
tSecond = Time.second();
tDay = Time.weekday();
}
//Used during the night, ensures the Photon goes to sleep to preserve power.
//Automatically detects if its weekend or not.
void photonSleep(){
digitalWrite(statePin, LOW);
if(tDay != 6){
System.sleep(SLEEP_MODE_DEEP, sleepTime);
}
else if (tDay == 6){
System.sleep(SLEEP_MODE_DEEP, sleepTimeWeekend);
}
}
//Initiated after the Photon wakes up.
//Initializes all the functions of the Photon for it to work.
void photonWakeUp(){
printTimer = millis(); //giving a value to the printTimer
digitalWrite(statePin, HIGH); //Turning the distance sensor on.
WiFi.on(); //Turning WiFi on...
WiFi.connect(); //Making it connect...
//Getting previously stored values from the EEPROM.
//Used to check if there's still data from previous session.
EEPROM.get(eepromAddress[0], eepromValue1);
EEPROM.get(eepromAddress[1], eepromValue2);
//Checking if it's connected, to...
if(Particle.connected()){
delay(cooldown);
detectTime(); //detect time
firstRun = false; //and to exit the firstRun.
}
else{
photonWakeUp();
}
}
//Reads the distance sensor to detect someone passing by.
//Applying a filter to ensure that jittering values don't go above or under the threshold rapidly.
void readSensor(){
//Reading the sensor and adding it to the sensorMedian.
sensorValue = analogRead(sensorPin);
sensorValues.add(sensorValue);
sensorMedian = int(sensorValues.getMedian());
//Detects if the average of the sensorValue is over the threshold while the sensorState was false.
//If this is the case, the threshold is lowered (to ensure a better reading and no flickering)
//And value is increased by one (since one person passed by), at this point the sensorState is true, because someone is passing by.
if(sensorMedian > sensorThreshold && sensorState == false){
sensorThreshold -= sensorOffset;
value++;
sensorState = true;
sensorTimer = millis();
}
//Detects if people troll the device by swaying their hands in front of it.
if(sensorMedian > sensorThreshold && sensorState == true && (millis() < (sensorTimer + sensorTimeOffset))){
sensorTimer = millis();
}
//Since the threshold has been lowered, the sensorValue first has to drop
//Then, if this happens and a short timer has passed, the sensorState is put to false indicating someone has passed.
if(sensorMedian < sensorThreshold && sensorState == true && (millis() > (sensorTimer + sensorTimeOffset))){
sensorThreshold = oST;
sensorState = false;
}
/*value = (analogRead(sensorPin) % 7);
if(value == 0){
value++;
}*/
}
//Prints desired data to the console for debugging.
void serialPrint(){
if(millis() > printTimer + prInterval){
if(tHour < 10){
Serial.print("0");
}
Serial.print(tHour);
Serial.print(":");
if(tMinute < 10){
Serial.print("0");
}
Serial.print(tMinute);
Serial.print(":");
if(tSecond < 10){
Serial.print("0");
}
Serial.print(tSecond);
Serial.print("\t");
Serial.print("wifiState:");
Serial.print(wifiState);
Serial.print("\t");
Serial.print("Debug:");
Serial.print(debugMode);
Serial.print("\t");
Serial.print("Connected:");
Serial.print(Particle.connected());
Serial.print("\t");
Serial.print("Value:");
Serial.print(value);
Serial.print("\t");
Serial.print("Sensor:");
Serial.print(sensorMedian);
Serial.print("\t");
Serial.print("EEPROM:");
Serial.print(eepromValue1);
Serial.print("\t");
Serial.print(eepromValue2);
/*Serial.print("\t");
Serial.print("Day:");
Serial.print(tDay);
Serial.print("\t");
Serial.print("sleepTime:");
Serial.print(sleepTime);
Serial.print("/");
Serial.print(sleepTimeWeekend);*/
//Line Break
Serial.println();
//Resetting the printTimer.
printTimer = millis();
}
}
The code was written on 0.4.6 if I remember correctly. My device is currently running 0.5.2.
Is there a way to downgrade to 0.4.6 if necessary?


