Good day everyone i prepared a code for a datalogger to determine honeybees entering a feeding station. It supposed to have a real time clock but as of now i want to fix some bugs on my present code. thanks!!
On my csv format on the excel. lots of data are being stored because it logs every data repeatedly. I only want to log the number the counter was sensing.
On my sensor B when one passes it counts two times. But same code as with sensor A i don't know why?
here's my code have patience please
//Program by Jeremy Blum
//www.jeremyblum.com
//SD Card Demonstration
//Some code from public domain work by Tom Igoe
//Assisted by Inigo D. Villanueva III
//Edited by Ignacio D. Villanueva III
//For thesis purpose entitled "
//Thesis members: James Santiago. Belen Cruz. Franzes Francisco, Kaye Agut
#include <SD.h> //SD Card Library
//SPI SD Card Pins
//MOSI = Pin 11
//MISO = Pin 12
//SCLK = PIN 13
int CS_pin = 10;
int pow_pin = 8;
// this constant won't change:
const int buttonPin1 = 2; // the pin that the pushbutton is attached to
const int buttonPin2 = 5;
// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
int buttonPushCounter1 = 0; // counter for the number of button presses
int buttonState1 = 0; // current state of the button
int lastButtonState1 = 0; // previous state of the button
long lastEvent= 0; // The last time a bee has entered the feeding station
long interval= 300; // The debounce time
void setup() {
Serial.begin(9600);
Serial.println("Initializing Card");
//CS Pin is an output
pinMode(CS_pin, OUTPUT);
//SD Card will Draw Power from Pin 8, so set it high
pinMode(pow_pin, OUTPUT);
digitalWrite(pow_pin, HIGH);
//Initialize Card
if (!SD.begin(CS_pin))
{
Serial.println("Card Failure");
return;
}
Serial.println("Card Ready");
// initialize the button pin as a input:
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
// initialize serial communication:
Serial.begin(9600);
//Write Log File Header
File logFile = SD.open("LOG.csv", FILE_WRITE);
if (logFile)
{
logFile.println(", ,"); //Just a leading blank line, incase there was previous data
String header = "FEEDING_STATION_1, FEEDING_STATION_2";
logFile.println(header);
logFile.close();
Serial.println(header);
}
else
{
Serial.println("Couldn't open log file");
}
}
void loop() {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin1);
// compare the buttonState to its previous state
if (buttonState != lastButtonState)
{
// if the state has changed, increment the counter
if (buttonState == HIGH && millis() - lastEvent > interval)// Ignore this reading if it is too close to the last one
{
lastEvent= millis(); // a bee can be recorded)
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
Serial.println("Bees are being detected entering Feeding Station A");
Serial.print("number of bees that entered Feeding Station A: ");
Serial.println(buttonPushCounter);
}
lastButtonState= buttonState;
}
buttonState1 = digitalRead(buttonPin2);
if (buttonState1 != lastButtonState1)
{
// if the state has changed, increment the counter
if (buttonState1 == HIGH && millis() - lastEvent > interval)// Ignore this reading if it is too close to the last one
{
lastEvent= millis(); // a bee can be recorded)
// if the current state is HIGH then the button
// wend from off to on:
}
buttonPushCounter1++;
Serial.println("Bees are being detected entering Feeding Station B");
Serial.print("number of bees that entered Feeding Station B: ");
Serial.println(buttonPushCounter1);
}
lastButtonState1= buttonState1;
//Create Data string for storing to SD card
//We will use CSV Format
String dataString = String(buttonPushCounter) + ", " + String(buttonPushCounter1);
//Open a file to write to
//Only one file can be open at a time
File logFile = SD.open("LOG.csv", FILE_WRITE);
if (logFile)
{
logFile.println(dataString);
logFile.close();
Serial.println(dataString);
}
else
{
Serial.println("Couldn't open log file");
}
}
I don't know if these will address the problems you're seeing, but I see a few things that could be improved with your code:
Don't use the String class. It's buggy and eats up memory. Use character arrays instead, if you really need to store strings, or don't even bother (I don't see anything in your code that needs strings to work at all).
Use more descriptive and consistent variable names. Why, for example, are you using buttonPushCounter to count bees? Why is buttonPushCounter1 used for buttonPin2 for feeding station B? Try, for example, beeCounterA for beeSensorPinA for feeding station A.
Add variables for lastBeeCounterA and lastBeeCounterB.
Then you can do something like this (not compiled and tested, but the concept is sound):
This will print a new log entry only when there's been a change to either beeCounterA or beeCounterB. Note that there's no need at all to use any kind of string construction here--you can print the first variable, then print a comma and space, then println the second variable; the println adds a newline character at the end of the line.
DO NOT use digital pins as power supplies. Use controllable voltage regulator or a MOSFET switch circuit. You could find a lot in google about those two terms. The idea is to use the digital pin as a "flag" to tell whether the "switch" should be open or closed. Using digital pins as power supplies could and probably would destroy your peripheral device (that is being powered) and definitely your arduino board.
Your SD card, depending on the speed class could draw more then the limit of 40mAh of the digital pins.
Thanks, i was wondering also if you could give me an insight about the RTC DS1307 that i will use. I wanna log only the time when my sensor had sensed something,
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
char logString[30];
int beeCounterA = 0;
int lastBeeCounterA = 0;
int beeCounterB = 0;
int lastBeeCounterB = 0;
time_t t;
void setup()
{
setSyncProvider(RTC.get);
//open the card and logfile, and do the rest of your setup
}
void loop()
{
//do whatever you do to read the counter devices
if ((beeCounterA != lastBeeCounterA) || (beeCounterB != lastBeeCounterB))
{
t = now();
sprintf(logString,"%.2d/%.2d/%.4d %.2d:%.2d:%.2d,%.3d,%.3d",
month(t), day(t), year(t), hour(t), minute(t), second(t), beeCounterA, beeCounterB);
logFile.println(logString);
lastBeeCounterA = beeCounterA;
lastBeeCounterB = beeCounterB;
}
}
This logs complete date and time as mm/dd/yyyy hh:mm:ss, and gives three digits for both counters--you can adjust the sprintf statement to give a different format if you prefer. This will only log to the file when there's been a change in either beeCounterA or beeCounterB, and at that time it will log the date and time, and both counters.
This code isn't complete; I don't have the library or the code in there to open the SD card, create and open the file, read the counter devices, etc. But it should get you going.
//Program by Jeremy Blum
//www.jeremyblum.com
//SD Card Demonstration
//Some code from public domain work by Tom Igoe
//Assisted by Inigo D. Villanueva III
//Edited by Ignacio D. Villanueva III
//For thesis purpose entitled "
//Thesis members: James Santiago. Belen Cruz. Franzes Francisco, Kaye Agut
#include <SD.h> //SD Card Library
//SPI SD Card Pins
//MOSI = Pin 11
//MISO = Pin 12
//SCLK = PIN 13
int CS_pin = 10;
int pow_pin = 8;
// this constant won't change:
const int buttonPinA = 2; // the pin that the pushbutton is attached to
const int buttonPinB = 5;
// Variables will change:
int buttonBeeCounterA = 0; // counter for the number of button presses
int beeCounterA = 0; // current state of the button
int lastBeeCounterA = 0; // previous state of the button
int buttonBeeCounterB = 0; // counter for the number of button presses
int beeCounterB = 0; // current state of the button
int lastBeeCounterB = 0; // previous state of the button
long lastEvent= 0; // The last time a bee has entered the feeding station
long interval= 300; // The debounce time
void setup() {
Serial.begin(9600);
Serial.println("Initializing Card");
//CS Pin is an output
pinMode(CS_pin, OUTPUT);
//SD Card will Draw Power from Pin 8, so set it high
pinMode(pow_pin, OUTPUT);
digitalWrite(pow_pin, HIGH);
//Initialize Card
if (!SD.begin(CS_pin))
{
Serial.println("Card Failure");
return;
}
Serial.println("Card Ready");
// initialize the button pin as a input:
pinMode(buttonPinA, INPUT);
pinMode(buttonPinB, INPUT);
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// read the pushbutton input pin:
beeCounterA = digitalRead(buttonPinA);
// compare the buttonState to its previous state
if (beeCounterA != lastBeeCounterA)
{
// if the state has changed, increment the counter
if (beeCounterA == HIGH && millis() - lastEvent > interval)// Ignore this reading if it is too close to the last one
{
lastEvent= millis(); // a bee can be recorded)
// if the current state is HIGH then the button
// wend from off to on:
buttonBeeCounterA++;
Serial.println("Bees are being detected entering Feeding Station A");
Serial.print("number of bees that entered Feeding Station A: ");
Serial.println(buttonBeeCounterA);
}
lastBeeCounterA= beeCounterA;
}
beeCounterB = digitalRead(buttonPinB);
if (beeCounterB != lastBeeCounterB)
{
// if the state has changed, increment the counter
if (beeCounterB == HIGH && millis() - lastEvent > interval)// Ignore this reading if it is too close to the last one
{
lastEvent= millis(); // a bee can be recorded)
// if the current state is HIGH then the button
// wend from off to on:
}
buttonBeeCounterB++;
Serial.println("Bees are being detected entering Feeding Station B");
Serial.print("number of bees that entered Feeding Station B: ");
Serial.println(buttonBeeCounterB);
}
lastBeeCounterB= beeCounterB;
//Write Log File Header
File logFile = SD.open("DATALOG.csv", FILE_WRITE);
if (logFile)
{
logFile.print(buttonBeeCounterA);
logFile.print(",");
logFile.println(buttonBeeCounterB);
Serial.print(buttonBeeCounterA);
Serial.print(",");
Serial.println(buttonBeeCounterB);
}
else
{
logFile.print("LogFile cannot be opened");
}
}
i wonder why there is no data being stored in my SD card, i have deleted the string and state it this way..
Doesn't look like it will work--if the log file can't be opened, how are you going to print the error message to the log file?
oh my, it must be Serial.println
anyway tried doing that. but still no data was being stored on the file name DATALOG.CSV
i wonder because when i use string it actually works, the only problem is that the data keep repeating so there's a lot of data being stored
iNgine:
i followed it but same result as the string does. so many data being stored, tons of data. i wonder why?
Because you're storing the two variables to your log file every time you run through the loop, without regard to whether either of them has changed. You'd want something like this:
if (beeCounterA != lastBeeCounterA)
{
// if the state has changed, increment the counter
if (beeCounterA == HIGH && millis() - lastEvent > interval)// Ignore this reading if it is too close to the last one
{
lastEvent= millis(); // a bee can be recorded)
// if the current state is HIGH then the button
// wend from off to on:
buttonBeeCounterA++;
Serial.println("Bees are being detected entering Feeding Station A");
Serial.print("number of bees that entered Feeding Station A: ");
Serial.println(buttonBeeCounterA);
//Write Log File Header
File logFile = SD.open("DATALOG.csv", FILE_WRITE);
if (logFile)
{
logFile.print(buttonBeeCounterA);
logFile.print(",");
logFile.println(buttonBeeCounterB);
Serial.print(buttonBeeCounterA);
Serial.print(",");
Serial.println(buttonBeeCounterB);
}
else
{
Serial.println("LogFile cannot be opened");
}
}
lastBeeCounterA= beeCounterA;
}
You'll want to make sure all the braces match here, but they look right. BTW, when posting your code, please use the Auto Format tool under the Tools menu first--it'll make the code a bit easier to follow.
You'll want to make sure all the braces match here, but they look right. BTW, when posting your code, please use the Auto Format tool under the Tools menu first--it'll make the code a bit easier to follow.
can't find the tools menu, thanks a lot. ill keep you posted.
im doing it one step at a time, i wish i can make it right so i can proceed to the RTC and the temperature/ humidity sensor.. thanks!!
however, i wish i could make something like this where you don't include the data of sensor A when the sensor B was incremented, like this
Hard to see in that tiny picture, but writing out the changed value in column 1 or column 2 or both is trivial. If one or more values change, you need to write a record. For each column, determine what to put in that column - a new value or a series of spaces. Then, write the record.
Hard to see in that tiny picture, but writing out the changed value in column 1 or column 2 or both is trivial. If one or more values change, you need to write a record. For each column, determine what to put in that column - a new value or a series of spaces. Then, write the record.
I modified my post. I wish i can create a logger like the one on the second picture. Can you suggest what can i do? thanks!!
if (logFile)
{
logFile.print(buttonBeeCounterA);
logFile.print(",");
logFile.println(buttonBeeCounterB);
Serial.print(buttonBeeCounterA);
Serial.print(",");
Serial.println(buttonBeeCounterB);
}
inside an if test:
if (beeCounterA != lastBeeCounterA)
It's hard to tell whether you have a similar prevBeeCounterB, or not. You would need one.
The variable names used in this application are terrible. I look at a name like buttonBeeCounterA and I think of a pin that a switch is connected to. I can't imagine why writing a pin number to the output file is of any interest.
I think that the best thing, at this point, is for you to post all of your code.
Changing the whether to log code is easy:
if (beeCounterA != lastBeeCounterA || beeCoutnerB != lastBeeCounterB)
But, like I said, I can't tell that the correct stuff is being tested, or that the correct stiff is being written to the file, since the names are horrible.
I think that the best thing, at this point, is for you to post all of your code.
im sorry for the terrible names, i changed it a little bit i hope it will be more understandable.
//Program by Jeremy Blum
//www.jeremyblum.com
//SD Card Demonstration
//Some code from public domain work by Tom Igoe
//Assisted by Inigo D. Villanueva III
//Edited by Ignacio D. Villanueva III
//For thesis purpose entitled "
//Thesis members: James Santiago. Belen Cruz. Franzes Francisco, Kaye Agut
#include <SD.h> //SD Card Library
//SPI SD Card Pins
//MOSI = Pin 11
//MISO = Pin 12
//SCLK = PIN 13
int CS_pin = 10;
int pow_pin = 8;
// this constant won't change:
const int buttonPinA = 3; // the pin that the pushbutton is attached to
const int buttonPinB = 5;
// Variables will change:
int CurrentNumberofBeesA = 0; // counter for the number of button presses
int ActualStateofCounterA = 0; // state of the button (Either HIGH or LOW)
int PreviousStateofCounterA = 0; // previous state of the button (Either HIGH or LOW)
int CurrentNumberofBeesB = 0; // counter for the number of button presses
int ActualStateofCounterB = 0; // state of the button (Either HIGH or LOW)
int PreviousStateofCounterB= 0; // previous state of the button (Either HIGH or LOW)
long lastEvent= 0; // The last time a bee has entered the feeding station
long interval= 300; // The debounce time
void setup() {
Serial.begin(9600);
Serial.println("Initializing Card");
//CS Pin is an output
pinMode(CS_pin, OUTPUT);
//SD Card will Draw Power from Pin 8, so set it high
pinMode(pow_pin, OUTPUT);
digitalWrite(pow_pin, HIGH);
//Initialize Card
if (!SD.begin(CS_pin))
{
Serial.println("Card Failure");
return;
}
Serial.println("Card Ready");
// initialize the button pin as a input:
pinMode(buttonPinA, INPUT);
pinMode(buttonPinB, INPUT);
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// read the pushbutton input pin:
ActualStateofCounterA= digitalRead(buttonPinA);
ActualStateofCounterB = digitalRead(buttonPinB);
// compare the buttonState to its previous state
if ((ActualStateofCounterA != PreviousStateofCounterA ) || (ActualStateofCounterB != PreviousStateofCounterB))
{
// if the state has changed, increment the counter
if (ActualStateofCounterA == HIGH && millis() - lastEvent > interval)// Ignore this reading if it is too close to the last one
{
lastEvent= millis(); // a bee can be recorded)
// if the current state is HIGH then the button
// wend from off to on:
CurrentNumberofBeesA++;
Serial.println("Bees are being detected entering Feeding Station A");
Serial.print("number of bees that entered Feeding Station A: ");
Serial.println(CurrentNumberofBeesA);
}
{
// if the state has changed, increment the counter
if (ActualStateofCounterB == HIGH && millis() - lastEvent > interval)// Ignore this reading if it is too close to the last one
{
lastEvent= millis(); // a bee can be recorded)
// if the current state is HIGH then the button
// wend from off to on:
}
CurrentNumberofBeesB++;
Serial.println("Bees are being detected entering Feeding Station B");
Serial.print("number of bees that entered Feeding Station B: ");
Serial.println(CurrentNumberofBeesB);
}
//Write Log File Header
File logFile = SD.open("DATALOG.csv", FILE_WRITE);
if (logFile)
{
if(ActualStateofCounterA != PreviousStateofCounterA)
logFile.print(CurrentNumberofBeesA);
logFile.print(", ");
logFile.println(CurrentNumberofBeesB);
logFile.close();
Serial.print(CurrentNumberofBeesA);
Serial.print(", ");
Serial.println(CurrentNumberofBeesB);
}
else
{
Serial.println("LogFile cannot be opened");
}
CurrentNumberofBeesA= ActualStateofCounterA;
CurrentNumberofBeesB= ActualStateofCounterB;
}
}