Firstly, apologies if this is the wrong section to ask this question, it’s been a little while:)
I’ve been trying to build a device that’ll track whether people use a soap dispenser through a variety of infrared sensors, and I’m having a hell of a time getting it to work.
No matter what I try, I can’t get it to print more than one line to the csv file on the card. I’m hoping someone can point me at my mistake, as I’m baffled. In my case it’ll create the file, and print “I like PURPLE BUTTERFLIES”. exactly once. No errors are given in the serial.
Here’s the code:
#include "application.h"
#include "neopixel.h"
#include "VCNL4010.h"
#include "SdFat.h"
SYSTEM_MODE(MANUAL);
// Pick an SPI configuration.
// See SPI configuration section below (comments are for photon).
#define SPI_CONFIGURATION 0
//------------------------------------------------------------------------------
// Setup SPI configuration.
#if SPI_CONFIGURATION == 0
// Primary SPI with DMA
// SCK => A3, MISO => A4, MOSI => A5, SS => A2 (default)
SdFat sd;
const uint8_t chipSelect = SS;
#elif SPI_CONFIGURATION == 1
// Secondary SPI with DMA
// SCK => D4, MISO => D3, MOSI => D2, SS => D1
SdFat sd(1);
const uint8_t chipSelect = D1;
#elif SPI_CONFIGURATION == 2
// Primary SPI with Arduino SPI library style byte I/O.
// SCK => A3, MISO => A4, MOSI => A5, SS => A2 (default)
SdFatLibSpi sd;
const uint8_t chipSelect = SS;
#elif SPI_CONFIGURATION == 3
// Software SPI. Use any digital pins.
// MISO => D5, MOSI => D6, SCK => D7, SS => D0
SdFatSoftSpi<D5, D6, D7> sd;
const uint8_t chipSelect = D0;
#endif // SPI_CONFIGURATION
//------------------------------------------------------------------------------
int LED = D7;
int lsen= A1;
int msen= D2;
int rsen= A7;
int lsread = 0;
int msread = 0;
int rsread = 0;
int buzzer = D6;
int switchPin = A0;
int switchState = 0;
int switchPos = 0;
int stripReset = 0;
unsigned long previousMillis = 0;
String dataString2 = String();
String delimitedChar = String(",");
String csvHeader=("Time,People Detected,Clean People Detected,Mode");
File myFile;
//Neopixel Pin Declarations
#define PIXEL_COUNT 8
#define PIXEL_PIN D5
#define PIXEL_TYPE WS2812B
//Neopixel Function Declarations
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
void colorAll(uint32_t c) {
uint16_t i;
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
}
void writeFile(String sdData){
// open the file for write at end like the "Native SD library"
if (!myFile.open("DATA.CSV", O_WRITE | O_CREAT | O_APPEND | O_AT_END)) {
sd.errorHalt("opening test.txt for write failed");
}
// if the file opened okay, write to it:
Serial.print("Writing to DATA.CSV...");
myFile.println("I Like PURPLE BUTTERFLIES!");
/*myFile.printf("fileSize: %d\n", myFile.fileSize());*/
// close the file:
myFile.close();
Serial.println("done.");
}
VCNL4010 vcnl;
//Variables
int triggered = 0;
long triggeredtime = 0; // time long range sensors were triggered
long washtime = 10000; //time in millisecodns before needs to wash
long people = 0; //number of times proximity sensors were triggered
int handdetect = 2500; //Proximity value from close range sensor
int handdetected = 0; //Did we detect a hand?
int closethreshold = 5200; //Proximity value that indicates use
unsigned long cleanpeople = 0;
int threshold = 1600;
int stripTime = 300;
int stripCount = 0;
int ledState = LOW; // ledState used to set the LED
int outEnable = 0;
unsigned long currentMillis = 0;
void setup(){
Serial.begin(9600);
//Pin Type Declarations
pinMode(buzzer, OUTPUT);
pinMode(switchPin, INPUT);
pinMode(lsen,INPUT);
pinMode(msen, INPUT);
pinMode(rsen, INPUT);
//LED Strip Initializations
strip.begin();
strip.show();
// Initialize SdFat or print a detailed error message and halt
// Use half speed like the native library.
// Change to SPI_FULL_SPEED for more performance.
if (!sd.begin(chipSelect, SPI_HALF_SPEED)) {
sd.initErrorHalt();
}
if (! vcnl.begin()){
Serial.println("Sensor not found :(");
while (1);
}
Serial.println("Found VCNL4010");
// see if the card is present and can be initialized:
if (!sd.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
//Syncs time with Cloud
/*Particle.syncTime();*/
//Creates Header for CSV File
Serial.println("Writing Header");
writeFile(csvHeader);
}
void loop(){
Particle.process();
lsread = analogRead(lsen);
msread = digitalRead(msen);
rsread = analogRead(rsen);
switchPos = analogRead(switchPin);
/*Serial.print("Left Sensor Reading: ");Serial.print(lsread);Serial.print("Right Sensor Reading: ");Serial.println(rsread);
delay(500);*/
/*Serial.print("Msread Value: "); Serial.println(msread);
delay(200);*/
//Serial.print("Long Range:");Serial.println(msread);
//Serial.print("SHORT RANGE:");Serial.println(vcnl.readProximity());
strip.show(); //Turns off LEDs
if (msread == 1){
triggered = 1;
people += 1;
Serial.println(people); Serial.print("People Detected");Serial.print(switchPos);Serial.print("Trigger Level");Serial.print(msread);Serial.print("Close Sensor:");Serial.println(vcnl.readProximity());
triggeredtime = millis();
if (switchPos > 500){
outEnable = 1;
colorAll(strip.Color(255, 128, 0)); // Orange
strip.show();
}
else{
outEnable = 0;
}
if(triggered == 1){
while ((triggeredtime + washtime) > millis()){
//Checks to see if they used the device
/*currentMillis = millis();
if ((currentMillis - previousMillis >= stripTime) && (outEnable == 1)){
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
/*digitalWrite(ledPin, ledState);*/
/*if (ledState == LOW){
colorAll(strip.Color(0, 0, 0)); // Orange
strip.show();
}
else{
colorAll(strip.Color(255, 128, 0)); // Orange
strip.show();
}
}*/
handdetect = vcnl.readProximity();
if ((handdetect > closethreshold) && (triggered == 1)){
triggered = 0;
cleanpeople += 1;
Serial.print("Someone washed their hands!");
Serial.print("Clean People:"); Serial.println(cleanpeople);
handdetected = 1;
if (switchPos > 500){
colorAll(strip.Color(0, 255, 0)); // Green
strip.show();
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
delay(100);
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
colorAll(strip.Color(0, 0, 0)); // Green
strip.show(); //Turns off LEDs
//Writes Data to SD Card
//"Time,People Detected,Clean People Detected,Mode"
Particle.process();
dataString2 = String(millis()) + delimitedChar + people + delimitedChar + cleanpeople + delimitedChar + switchPos;
/*Serial.print("data written: ");Serial.println(dataString2);*/
writeFile(dataString2);
delay(2000);
break;
}
}
lsread = analogRead(lsen);
msread = analogRead(msen);
rsread = analogRead(rsen);
if (((lsread > threshold) || (rsread > threshold)) && (triggered == 1)){
//Detects if they walk by the side sensor
triggered = 0;
Serial.println("Side sensor triggered, Someone didn't wash their hands");
if (switchPos > 500){
colorAll(strip.Color(255, 0, 0));
strip.show();
digitalWrite(buzzer, HIGH);
delay(300);
digitalWrite(buzzer, LOW);
delay(100);
colorAll(strip.Color(0, 0, 0));
strip.show();
}
Particle.process();
dataString2 = String(millis()) + delimitedChar + people + delimitedChar + cleanpeople + delimitedChar + switchPos;
Serial.print("data written: ");Serial.println(dataString2);
writeFile(dataString2);
delay(2000);
break;
}
if((triggeredtime+washtime) < (millis() + 5000)){
//Escapes triggered mode if enough time has elapsed
triggered = 0;
Serial.println("Timed Out");
colorAll(strip.Color(0, 0, 0)); // Off
strip.show(); //Turns off LEDs
Particle.process();
dataString2 = String(millis()) + delimitedChar + people + delimitedChar + cleanpeople + delimitedChar + switchPos;
Serial.print("data written: ");Serial.println(dataString2);
writeFile(dataString2);
break;
}
}
}
}
Particle.process();
}
It seems like a very simple modification to the trymefirst example, because I don’t need crazy speed or anything fancy, just a line of csv rows on the card. Thank you!