Have adapted sketch from Bee Counter v2 (written for Arduino) for use with Argon. Goal is to count bees entering and leaving the hive, using 24 gates. Have frequent, random reboots. Code is long but will include it.
......................................................................................................................................................................
const int LATCH = A5;
#include <LiquidCrystal_I2C_Spark.h>
#include <ThingSpeak.h>
LiquidCrystal_I2C *lcd;
TCPClient client;
int timehour=0;
int timeminute=0;
//unsigned long myChannelNumber =
//const char * myWriteAPIKey =
//Pins Argon
const byte powerGates1 = D4;
const byte powerGates2 = D5;
const int numberOfGates = 24; // 24 gates, 48 sensors
const int startGate = 0; //useful for testing
const int endGate = 24; //useful for testing
const int debeebounce = 30;
const int outputDelay = 20000; //prints bee counts every 20 seconds
unsigned long lastOutput = 0;
unsigned long currentTime = 0; // current time defined by milliseconds after program initiated
//boolean 0 or 1 sensor readings, 1 bee is present
boolean inSensorReading[numberOfGates];
boolean outSensorReading[numberOfGates];
boolean lastInSensorReading[numberOfGates];
boolean lastOutSensorReading[numberOfGates];
boolean checkStateIn[numberOfGates];
boolean checkStateOut[numberOfGates];
int inCount[numberOfGates];
int outCount[numberOfGates];
unsigned long startInReadingTime[numberOfGates];
unsigned long startOutReadingTime[numberOfGates];
unsigned long inSensorTime[numberOfGates];
unsigned long outSensorTime[numberOfGates];
unsigned long lastInFinishedTime[numberOfGates];
unsigned long lastOutFinishedTime[numberOfGates];
unsigned long inReadingTimeHigh[numberOfGates];
unsigned long outReadingTimeHigh[numberOfGates];
unsigned long lastInTime[numberOfGates];
unsigned long lastOutTime[numberOfGates];
unsigned long lastInReadingTimeHigh[numberOfGates];
unsigned long lastOutReadingTimeHigh[numberOfGates];
int totalTimeTravelGoingOut[numberOfGates];
int totalTimeTravelGoingIn[numberOfGates];
int firstTestInVariable[numberOfGates];
int firstTestOutVariable[numberOfGates];
int inTotal;
int outTotal;
int n = 0;
unsigned long target_time = 0 ; // used to help limiting publishing to every 360 min (0L)
#define PERIOD 60*60*1000
void setup ()
{
ThingSpeak.begin(client);
lcd = new LiquidCrystal_I2C(0x27, 16, 4);
lcd->init();
lcd->backlight();
lcd->setCursor(0,0);
lcd->print("Begin switch test.");
SPI.begin(); // Assumes LATCH = A5
SPI.beginTransaction(SPISettings(3*MHZ, MSBFIRST, SPI_MODE2));
pinMode (LATCH, OUTPUT);
digitalWrite (LATCH, HIGH);
pinMode (powerGates1, OUTPUT);
digitalWrite(powerGates1, LOW);
pinMode (powerGates2, OUTPUT);
digitalWrite(powerGates2, LOW);
} // end of setup
byte switchBank1;
byte oldSwitchBank1;
byte switchBank2;
byte oldSwitchBank2;
byte switchBank3;
byte oldSwitchBank3;
byte switchBank4;
byte oldSwitchBank4;
byte switchBank5;
byte oldSwitchBank5;
byte switchBank6;
byte oldSwitchBank6;
byte switchBank7;
byte oldSwitchBank7;
byte switchBank8;
byte oldSwitchBank8;
void loop ()
{
currentTime = millis();
digitalWrite(powerGates1, HIGH);
digitalWrite(powerGates2, HIGH);
delayMicroseconds(75); //first 24 gates only need 15us while gates closer to the end need ~40us-75us
digitalWrite (LATCH, LOW); // pulse the parallel load latch
delayMicroseconds(3);
digitalWrite (LATCH, HIGH);
delayMicroseconds(3);
digitalWrite(powerGates1, LOW);
digitalWrite(powerGates2, LOW);
//Reading 24 bits at 1Mhz should take about 24 microseconds,
//reading 24 bits at 3Mhz should take about 8us
//reading 48 bits at 3Mhz should take abotu 16us
switchBank1 = SPI.transfer (0); //8
switchBank2 = SPI.transfer (0); //16
switchBank3 = SPI.transfer (0); //24
switchBank4 = SPI.transfer (0); //32
switchBank5 = SPI.transfer (0); //40
switchBank6 = SPI.transfer (0); //48
if(switchBank1 != oldSwitchBank1 || switchBank2 != oldSwitchBank2 || switchBank3 != oldSwitchBank3 || switchBank4 != oldSwitchBank4 || switchBank5 != oldSwitchBank5 || switchBank6 != oldSwitchBank6)
{
//convert bytes to gate values
int gate = 0;
for(int i = 0; i < 8; i++)
{
if((switchBank1 >> i) & 1)
outSensorReading[gate] = HIGH;
else outSensorReading[gate] = LOW;
i++;
if((switchBank1 >> i) & 1)
inSensorReading[gate] = HIGH;
else inSensorReading[gate] = LOW;
gate++;
}
for(int i = 0; i < 8; i++)
{
if((switchBank2 >> i) & 1)
outSensorReading[gate] = HIGH;
else outSensorReading[gate] = LOW;
i++;
if((switchBank2 >> i) & 1)
inSensorReading[gate] = HIGH;
else inSensorReading[gate] = LOW;
gate++;
}
for(int i = 0; i < 8; i++)
{
if((switchBank3 >> i) & 1)
outSensorReading[gate] = HIGH;
else outSensorReading[gate] = LOW;
i++;
if((switchBank3 >> i) & 1)
inSensorReading[gate] = HIGH;
else inSensorReading[gate] = LOW;
gate++;
}
for(int i = 0; i < 8; i++)
{
if((switchBank4 >> i) & 1)
outSensorReading[gate] = HIGH;
else outSensorReading[gate] = LOW;
i++;
if((switchBank4 >> i) & 1)
inSensorReading[gate] = HIGH;
else inSensorReading[gate] = LOW;
gate++;
}
for(int i = 0; i < 8; i++)
{
if((switchBank5 >> i) & 1)
outSensorReading[gate] = HIGH;
else outSensorReading[gate] = LOW;
i++;
if((switchBank5 >> i) & 1)
inSensorReading[gate] = HIGH;
else inSensorReading[gate] = LOW;
gate++;
}
for(int i = 0; i < 8; i++)
{
if((switchBank6 >> i) & 1)
outSensorReading[gate] = HIGH;
else outSensorReading[gate] = LOW;
i++;
if((switchBank6 >> i) & 1)
inSensorReading[gate] = HIGH;
else inSensorReading[gate] = LOW;
gate++;
}
oldSwitchBank1 = switchBank1;
oldSwitchBank2 = switchBank2;
oldSwitchBank3 = switchBank3;
oldSwitchBank4 = switchBank4;
oldSwitchBank5 = switchBank5;
oldSwitchBank6 = switchBank6;
}
for (int i = startGate; i < endGate; i++)
//for (int i = 8; i < 12; i++)
{
if(inSensorReading[i] != lastInSensorReading[i]) //change of state on IN sensor
{
checkStateIn[i] = 0;
lastInSensorReading[i] = inSensorReading[i];
inSensorTime[i] = currentTime;
}
if(outSensorReading[i] != lastOutSensorReading[i]) //change of state on OUT sensor
{
checkStateOut[i] = 0;
lastOutSensorReading[i] = outSensorReading[i];
outSensorTime[i] = currentTime;
}
if(currentTime - inSensorTime[i] > debeebounce && checkStateIn[i] == 0) //debounce IN sensor
{
checkStateIn[i] = 1; //passed debounce
if(inSensorReading[i] == HIGH) //a bee just entered the sensor
{
startInReadingTime[i] = currentTime;
}
if(inSensorReading[i] == LOW) //a bee just exits the sensor; that is, it was HIGH, now it is LOW (empty)
{
lastInFinishedTime[i] = currentTime;
inReadingTimeHigh[i] = currentTime - startInReadingTime[i]; //this variable is how long the bee was present for
if(outReadingTimeHigh[i] < 650 && inReadingTimeHigh[i] < 650){ //should be less than 650ms
if(currentTime - lastOutFinishedTime[i] < 200){ //the sensors are pretty cose together so the time it takes to trigger on and then the other should be small.. ~200ms
inTotal++;
}
}
}
}
if(currentTime - outSensorTime[i] > debeebounce && checkStateOut[i] == 0) //debounce OUT sensor
{
checkStateOut[i] = 1; //passed debounce
if(outSensorReading[i] == HIGH) //a bee just entered the sensor
{
startOutReadingTime[i] = currentTime;
}
if(outSensorReading[i] == LOW) //a bee just exits the sensor; that is, it was HIGH, now it is LOW (empty)
{
lastOutFinishedTime[i] = currentTime;
outReadingTimeHigh[i] = currentTime - startOutReadingTime[i]; //this variable is how long the bee was present for
if(outReadingTimeHigh[i] < 600 && inReadingTimeHigh[i] < 600){ //should be less than 600ms
if(currentTime - lastInFinishedTime[i] < 200){ //the sensors are pretty cose together so this time should be small
outTotal++;
}
}
}
}
}
delay (15); // debounce
if (currentTime - lastOutput > outputDelay)
{
sendData();
lastOutput = currentTime;
inTotal = 0;
outTotal = 0;
}
}
void sendData() {
lcd->setCursor(0,0);
lcd->print("Bee Transit Data ");
lcd->setCursor(0,3);
lcd->print("T, ");
lcd->print(outTotal);
lcd->print(", ");
lcd->print(inTotal);
ThingSpeak.setField(1,outTotal);
ThingSpeak.setField(2,inTotal);
// Write the fields that you've set all at once.
// ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
// delay(16000);
}