Stopwatch Codez
Posted by Justin Bernard on May 9, 2013
hey look at the attached file.
this is the current stopwatch code.
Arduino doesnt have a RTC (real time clock) so it has not sense of what time it is, it CAN however start time from a set point and count how many mS it has been thus how the stopwatch is working now.
I want to tweak this file so that for one instead of logging to .XXX decimal places it just does seconds. that part is in the 'padding zeros' about 3/4 the way down.
2nd thing i want to tweak is when the button state changes (stopwatch is pushed again) for it to call to the RTC and pull the current timestamp,
so right now in my serial COM window its giving me time in X.xxx seconds, id like it to do X.xxx, 05/08/2013
so that will print that per a new line every time the stopwatch is initiated. then we can pull that to bluetooth, convert seconds to hr/min/sec, then log that time for the day in the timestamp.
here's the code to call timestamp from the onboard RTC:
void loop () {
DateTime now = RTC.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
what thats doing is using the RTC.now() function which is pull timstamp, then everything below (now.year, ect) pulls that long timestamp apart and sections it into catagories so when it sends it to serial com window it will look like XX/XX/XX XX:XX:XX, but we just need the day/month/year so leave out hr/min/sec parts.
Comments
Justin Bernard on May 9, 2013:
nice, now i can have some fun.
ok so i cleaned up that text doc, removed some stuff that was remnant of copy/paste compiling and broke it into more legible functions
i have no way of testing on my end, so run this and let me know if/where it fails.
i added ".c" to file type so it color codes correctly through my editor sublime. you should be able to copy it into your ide as is. I'm also using a slightly different time lookup method. i included the lib file Time.h, that may be something thats baked into the ide, not sure. its set to include at the top of stopwatch.c you'll notice, which means to import it at runtime. if Time.h isn't a default class to include, you may have to learn where to put code classes you want to import.
let me know if you have any questions, this is my jamz.
Taylor Bernard on May 9, 2013:
stopwatch.pde: In function 'void printCurrentDate()':
stopwatch:106: error: 'month' was not declared in this scope
stopwatch:108: error: 'day' was not declared in this scope
stopwatch:110: error: 'year' was not declared in this scope
stopwatch.pde: In function 'void blinkLED()':
stopwatch:135: error: expected `}' before 'else'
i dont think we need to use Time.h, when using the RTC we do
#include <Wire.h>
#include "RTClib.h"
wire establishes connectivity to the RTC chip since it does this thing called i2C (2 wire connectivity to an offboard chip), so since the clock is offboard, we connect with wire.h then use RTClib.h for formatting/parsing i believe.
so saying that, i think we have to use this code to get time:
void loop () {
DateTime now = RTC.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
stopwatch_v002.pde: In function 'void blinkLED()':
stopwatch_v002:137: error: expected `}' before 'else'
stopwatch_v002.pde: At global scope:
stopwatch_v002:146: error: expected declaration before '}' token
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
and in the COM window, its spitting out this format, something odd for the date:
7.924
21061
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
721061
11521061
so still showing the '21061' as a date or something somehow. first sample was 7sec, other was 115sec.
Justin Bernard on May 9, 2013:
// printCurrentDate();
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
v004 with the date commented out was working best. pulling whole numbers, but it wasnt making a new line per each on/off.
v005 is doing some date thing again:
1488011
148805
148807
148809
looks like last 2 numbers are the seconds.
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
148807
148807
1488016
004 was working best, just wasnt making new line on button reset
Justin Bernard on May 9, 2013:
try:
Taylor Bernard on May 9, 2013:
ELAPSED TIME: 7
ELAPSED TIME: 0
ELAPSED TIME: 10
nice, that fixed that part. now on to the LED...what did you change from org file on that?
Justin Bernard on May 9, 2013:
what was causing the issues was i was using:
print('write something here');
instead of:
print("write something here")
C must be fickle on denoting a string. it must have intpreted that as code and converted to a number some how. odd. other languages i use you can swap '' and "" interchangeably on strings.
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
------
getting there.
ELAPSED TIME: 5
--> 165/165/2165
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
ELAPSED TIME: 8
--> 5/9/2013
----
add this to your file after initial setup and after serial (9600)
Wire.begin();
RTC.begin();
Justin Bernard on May 9, 2013:
whats next...
Justin Bernard on May 9, 2013:
for archive: working stopwatch code with timestamp.
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
yep, tactile on/off switch.
Justin Bernard on May 9, 2013:
i'm on that now... see if you can get it too.
Taylor Bernard on May 9, 2013:
Justin Bernard on May 9, 2013:
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
Justin Bernard on May 9, 2013:
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
Justin Bernard on May 9, 2013:
Taylor Bernard on May 9, 2013:
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// 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.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
Taylor Bernard on May 9, 2013:
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
// A simple data logger for the Arduino analog pins
// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL 1000 // mills between entries (reduce to take more/faster data)
// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
// the digital pins that connect to the LEDs
#define redLEDpin 2
#define greenLEDpin 3
// The analog pins that connect to the sensors
#define tempPin 0 // analog 1
RTC_DS1307 RTC; // define the Real Time Clock object
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
// red LED indicates error
digitalWrite(redLEDpin, HIGH);
while(1);
}
void setup(void)
{
Serial.begin(9600);
Serial.println();
// use debugging LEDs
pinMode(redLEDpin, OUTPUT);
pinMode(greenLEDpin, OUTPUT);
#if WAIT_TO_START
Serial.println("Type any character to start");
while (!Serial.available());
#endif //WAIT_TO_START
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
error("Card failed, or not present");
}
Serial.println("card initialized.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
// connect to RTC
Wire.begin();
if (!RTC.begin()) {
logfile.println("RTC failed");
#if ECHO_TO_SERIAL
Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
}
logfile.println("millis,stamp,datetime,temp,vcc");
#if ECHO_TO_SERIAL
Serial.println("millis,stamp,datetime,temp,vcc");
#endif //ECHO_TO_SERIAL
// If you want to set the aref to something other than 5v
analogReference(EXTERNAL);
}
void loop(void)
{
DateTime now;
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
digitalWrite(greenLEDpin, HIGH);
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(", ");
#if ECHO_TO_SERIAL
Serial.print(m); // milliseconds since start
Serial.print(", ");
#endif
// fetch the time
now = RTC.now();
// log time
logfile.print(now.unixtime()); // seconds since 1/1/1970
logfile.print(", ");
logfile.print('"');
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
logfile.print('"');
#if ECHO_TO_SERIAL
Serial.print(now.unixtime()); // seconds since 1/1/1970
Serial.print(", ");
Serial.print('"');
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
Serial.print('"');
#endif //ECHO_TO_SERIAL
analogRead(tempPin);
delay(10);
int tempReading = analogRead(tempPin);
// converting that reading to voltage, for 3.3v arduino use 3.3, for 5.0, use 5.0
float voltage = tempReading * aref_voltage / 1024;
float temperatureC = (voltage - 0.5) * 100 ;
float temperatureF = (temperatureC * 9 / 5) + 32;
logfile.print(", ");
logfile.print(temperatureF);
#if ECHO_TO_SERIAL
Serial.print(", ");
Serial.print(temperatureF);
#endif //ECHO_TO_SERIAL
// Log the estimated 'VCC' voltage by measuring the internal 1.1v ref
logfile.println();
#if ECHO_TO_SERIAL
Serial.println();
#endif // ECHO_TO_SERIAL
digitalWrite(greenLEDpin, LOW);
// Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
// which uses a bunch of power and takes time
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();
// blink LED to show we are syncing data to the card & updating FAT!
digitalWrite(redLEDpin, HIGH);
logfile.flush();
digitalWrite(redLEDpin, LOW);
}
Taylor Bernard on May 9, 2013:
http://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock-3
chick is actually pretty badass.
http://www.adafruit.com/about/
went to MIT, started this company, making mega bux.
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
Serial write is a great way to test to make sure its doing what you want, so now its working we just need to write to the onboard storage.
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
gotcha. almost have this part done, code over in a sec.
Taylor Bernard on May 10, 2013:
then we just want to open, write, and close the file everytime the stopwatch is ran.
using:
logfile.open()
http://arduino.cc/forum/index.php?topic=150753.0
Taylor Bernard on May 10, 2013:
dont know which is better....
http://arduinobasics.blogspot.com/2011/06/from-processingorg-how-to-append-text.html
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
stopwatch_v011:124: error: 'BufferedWriter' was not declared in this scope
stopwatch_v011:124: error: expected `;' before 'bw'
stopwatch_v011:126: error: 'FileWriter' was not declared in this scope
stopwatch_v011:126: error: expected `;' before 'fw'
stopwatch_v011:127: error: 'bw' was not declared in this scope
stopwatch_v011:127: error: expected type-specifier before 'BufferedWriter'
stopwatch_v011:127: error: expected `;' before 'BufferedWriter'
stopwatch_v011:128: error: 'System' was not declared in this scope
stopwatch_v011:129: error: expected type-specifier before 'IOException'
stopwatch_v011:129: error: exception handling disabled, use -fexceptions to enable
stopwatch_v011:129: error: expected `)' before 'e'
stopwatch_v011:129: error: expected `{' before 'e'
stopwatch_v011:129: error: 'e' was not declared in this scope
stopwatch_v011:129: error: expected `;' before ')' token
stopwatch_v011:132: error: 'finally' was not declared in this scope
stopwatch_v011:132: error: expected `;' before '{' token
stopwatch_v011:179: error: expected `}' at end of input
Justin Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Taylor Bernard on May 10, 2013:
in that link where this code is from the guy calls them out earlier with this,
saveData(myFileName, mySensorData, false);
-----------
would that fix it?
Taylor Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
copy big block of what its doing ...
Taylor Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
sketch_may10b.ino: In function 'void blinkLED()':
sketch_may10b:185: error: expected `;' before '{' token
sketch_may10b:187: error: expected `}' before 'else'
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
when i upload program and startup arduino, pops back:
SD CARD READ FAILED
when i start the timer, returns txt in com window:
*** BLANG BLANG **** like it should, about every 100ms
when i end timer, spits out date and time like we had working yesterday.
when i pull file off SD card, says ' ***TEST**** ' on about 100 lines, looks like its mirroring **** BLANG BLANG *** for LED, and at the same time, that same interval writing ' *** TEST **** ' to the card. but the date/stopwatch time that showed up in the COM window isnt on the card, just TEST.
also, LED blink during stopwatch record isnt working on this one.
Taylor Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
Justin Bernard on May 10, 2013:
ps, what is 'commands.txt'. does that exist on sd card? what is on it?
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
v012:150: error: invalid conversion from 'int' to 'const char*'
v012:150: error: initializing argument 1 of 'String::String(const char*)'
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
// INIT VARS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
*/
#include <Wire.h>
#include <SD.h>
#include "RTClib.h"
RTC_DS1307 RTC;
#define ledPin 3 // LED connected to digital pin 3
#define buttonPin 2 // button on pin 4
float refresh_rate = 1.0;
int CS_pin = 10;
int pow_pin = 8;
int _value = LOW; // LED state holder
int _btnState; // button state holder
int _lastBtnState; // archive button state
int _blinking; // LED blinking status conditional
long _interval = 100; // LED blink interval
long _prevMilli = 0; // millisecond archive
long _startClock; // stop watch init time
long _elapsedClock; // stop watch elapsed time
/*
// SETUP
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
*/
void setup() {
Serial.begin(9600);
Wire.begin();
RTC.begin();
pinMode( ledPin, OUTPUT ); // sets the digital pin as output
pinMode( buttonPin, INPUT ); // not really necessary, pins default to INPUT anyway
digitalWrite( buttonPin, HIGH ); // turn on pullup resistors. Wire button so that press shorts pin to ground.
pinMode(CS_pin, OUTPUT); // setup sd card
pinMode(pow_pin, OUTPUT);
digitalWrite(pow_pin, HIGH);
if (!SD.begin(CS_pin)) {
Serial.println("SD CARD CONNECT FAIL");
return;
}
Serial.println("");
File commandFile = SD.open("COMMANDS.txt");
if (commandFile) {
float decade = pow(10, (commandFile.available() - 1));
while(commandFile.available()) {
float temp = (commandFile.read() - '0');
refresh_rate = temp*decade+refresh_rate;
decade = decade/10;
}
Serial.print("REFRESH RATE: ");
Serial.print(refresh_rate);
Serial.println("MS");
} else {
// Serial.println("SD CARD READ FAIL");
return;
}
}
/*
// LOOP
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
*/
void loop() {
_btnState = digitalRead( buttonPin );
if ( _btnState == LOW && _lastBtnState == HIGH && _blinking == false ) {
_startClock = millis();
_blinking = true;
delay(5);
} else if ( _btnState == LOW && _lastBtnState == HIGH && _blinking == true ) {
_elapsedClock = millis() - _startClock;
_blinking = false;
printElapsedTime();
}
_lastBtnState = _btnState;
blinkLED();
}
/*
// PRINT ELAPSED TIME
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
*/
void printElapsedTime() {
Serial.print( "ELAPSED TIME: " );
Serial.print( (int)( _elapsedClock / 1000L ) );
Serial.println();
printCurrentDate();
}
/*
// PRINT CURRENT DATE
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
*/
void printCurrentDate() {
DateTime now = RTC.now();
Serial.print( " --> " );
Serial.print( now.month(), DEC );
Serial.print( "/" );
Serial.print( now.day(), DEC );
Serial.print( "/" );
Serial.print( now.year(), DEC );
Serial.println();
}
/*
// LOG DATA TO SD CARD
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
*/
void logSDData() {
DateTime now = RTC.now();
DateTime DataString = now.year;
File logFile = SD.open("LOG.txt", FILE_WRITE);
if (logFile) {
logFile.println(DataString);
logFile.close();
Serial.println(DataString);
} else {
Serial.println( "LOG.txt" );
Serial.println( " - SD WRITE FAILED" );
}
}
/*
// BLINK LED
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
*/
void blinkLED() {
if ( ( millis() - _prevMilli > _interval ) ) {
// BLINK IF RUNNING
if ( _blinking == true ) {
_prevMilli = millis();
if ( _value == LOW ) {
_value = HIGH;
Serial.print( "*** LED BLINK ***" );
// TEMP - WRITE DATA TO SD ON EVERY BLINK
logSDData();
} else {
_value = LOW;
}
digitalWrite( ledPin, _value );
} else {
// DONT ATTEMPT BLINK, HASNT REACHED BLINK INTERVAL
digitalWrite( ledPin, LOW );
}
}
}
Justin Bernard on May 10, 2013:
Taylor Bernard on May 10, 2013:
Justin Bernard on May 11, 2013: