Bike POV Beta 5
From Open Source Urbanism
Code for the Arduino Bike POV project
Status: working (no EEPROM storage yet. Use the font.h code from Bike_POV_Beta_4)
Environment: Arduino 0011 (not working on version 12)
This code has been superseded. Get the latest version here.
//============================================================ // Arduino Bike POV // // by Scott Mitchell // www.openobject.org // Open Source Urbanism // // Copyright (C) 2008 Scott Mitchell 12-10-2008 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // A copy of the GNU General Public License // can be found at <http://www.gnu.org/licenses/>. // // B5.3 // Last Modified: October 16, 2008 //============================================================ #undef int() // fixes a bug with the stdio.h #include <stdio.h> // gives access to function sprintf // defining the alphabet #include "font.h" // get access to better timekeeping. ref: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1193623343 extern volatile unsigned long timer0_overflow_count; // define the Arduino LED pins in use const int LEDpins[] = { 1,2,3,4,5,6,7}; // number of LEDs const int charHeight = sizeof(LEDpins); const int charWidth = 5; // set up display parameters const int numFrames = 350; // number of frames per rotation unsigned long frameDuration = 1000; // time for each frame in microseconds - updated from rotation speed const int letterSpace = 4; // number of frames between letters const int textOffset = 10; // start distance from magnet in frames unsigned long startTime = microSeconds(); // start time for wheel rotation in microseconds unsigned long resetTime = 10000000; // reset time for text in microseconds (10 sec) // sensor setup const int sensorPIN = 0; // define the Arduino sensor pin const int mean = 508; // sensor at rest (no magnet) const int sensitivity = 30; // sensor sensitivity // distance and speed variables (floats are avoided because they slow the Arduino down) unsigned long numWheelRotations; // the base from which all other data is calculated const unsigned long wheelCircum = 1100; // bike wheel circumference in mm (adjust this to match your bike) // text string char textString[50] = "HELLO"; // declared large enough to hold a full string void setup() { for (int i = 0; i < charHeight; i++) pinMode(LEDpins[i], OUTPUT); // set each pin as an output // set the number of wheel rotations // future version should get this value from EEPROM memory // store the value in m then (numWheelRotations = distance * 1000 / wheelCurcum) numWheelRotations = 0; // for now just let it equal 0 } void loop() { // printing every letter of the textString for (int i=0; i<sizeof(textString); i++){ printLetter(textString[i]); // space between letters pauseFrame(letterSpace); if(microSeconds() > resetTime){ resetTime += 10000000; // add 10 seconds to it break; // restart the text string } } } void printLetter(char ch) { byte b; // make sure the character is within the alphabet bounds (defined by the font.h file) // if it's not, make it a blank character if (ch < 32 || ch > 126) ch = 32; // converts the ASCII number to the font index number ch -= 32; // step through each byte of the character array for (int i=0; i<charWidth; i++) { b = font[ch][i]; // bit shift through the byte and output it to the pin for (int j=0; j<charHeight; j++) { digitalWrite(LEDpins[j], !!(b & (1 << j))); } // space between columns pauseFrame(1); } //clear the LEDs for (int k=0; k<charHeight; k++) { digitalWrite(LEDpins[k], LOW); } } void pauseFrame(int frames){ unsigned long currentTime; int sensVal; // variable to store the value coming from the sensor unsigned long endTime = microSeconds() + (frames * frameDuration); // calculate the end time while(microSeconds() < endTime && microSeconds() < resetTime){ // check the sensor sensVal = analogRead(sensorPIN); // read the Hall Effect Sensor if (sensVal > (mean + sensitivity) || sensVal < (mean - sensitivity)) { currentTime = microSeconds(); // in microseconds if(currentTime < (startTime + (20 * frameDuration))){ // de-bounce the sensor reading startTime = currentTime; // reset the start time } else { resetTime = currentTime + (textOffset * frameDuration); // set the sensor flag variable frameDuration = (currentTime - startTime) / numFrames; // recalculate frameDuration if(frameDuration > 10000) frameDuration = 10000; // limit the frame duration to a reasonable time numWheelRotations++; // add 1 to the number of wheel rotations setTextString(currentTime - startTime); // reset the display text startTime = currentTime; // reset the start time } } } } void setTextString(unsigned long duration){ int n; // number of char written to the string (not used) // calculate distance unsigned long distancem = numWheelRotations * wheelCircum / 1000; // distance in metres unsigned long distancekm = distancem / 1000; // distance in km (this truncates the number) unsigned long distanceRem = distancem - (distancekm * 1000); // the bit after the decimal point // calculate speed // mm / microsecond x 1000 is mm / millisecond // mm / millisecond is equivalent to m / sec // m / sec x 60 x 60 is m / hr // m / hr / 1000 is km / hr unsigned long speed100m = wheelCircum * 36000 / duration; // 100m per hour unsigned long speedkm = speed100m / 10; // km per hour unsigned long speedRem = speed100m - (speedkm * 10); // the bit after the decimal point // print a new text string into the variable n = sprintf(textString, "%ld.%.3ld km %ld.%.ld km/hr \n", distancekm, distanceRem, speedkm, speedRem); } // get an accurate time reading. ref: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1193623343 unsigned long microSeconds(void) { return ((timer0_overflow_count << 8) + TCNT0)*4; }

