openobject.org

Bike POV Bytes Beta 1

From Open Source Urbanism

Code for the Arduino Bike POV project, Byte version

Version: B1.0

Status: not working (due to memory problems)
(use the font.h code from Bike_POV_Beta_4)

//============================================================
// Bike POV Bytes
//
// 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/>.
//
// B1.0
// 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"

// define the Arduino LED pins in use
const unsigned int LEDpins[] = {
  1,2,3,4,5,6,7};

// number of LEDs
const unsigned int charHeight = sizeof(LEDpins);
const unsigned int charWidth = 5;

// set up display parameters
const unsigned int numFrames = 350;	// number of frames per rotation
unsigned long frameDuration = 1000;	// time for each frame in microseconds - updated from rotation speed
const unsigned int letterSpace = 4;	// number of frames between letters
const unsigned int stringSpace = 10;	// number of frames between text string repeat
unsigned long startTime = (millis() * 1000);	// start time for wheel rotation in microseconds
unsigned int byteNum = 0; // the byte being displayed

// sensor setup
const unsigned int sensorPIN = 0;  // define the Arduino sensor pin
const unsigned int mean = 508;  // sensor at rest (no magnet)
const unsigned 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 wheelCurcum = 1100;  // bike wheel circumfrance in mm (adjust this to match your bike)

// text string
byte byteString[200]; // the text as a byte string for display

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
  // load some text into the byte array
  updateByteArray("HELP");
}


void loop()
{
  // set the LED pattern
  updateDisplay();
  // wait for a while (duration of 1 frame)
  pauseFrame(1);
}

void updateDisplay()
{
  if(byteNum < sizeof(byteString)){
    byte b = byteString[byteNum];
    // check for end of text flag
    if(b != 0xFF){
      // bit shift through the byte and output it to the pins
      for (int j=0; j<charHeight; j++) {
        digitalWrite(LEDpins[j], !!(b & (1 << j)));
      }
      byteNum++;
    }
  }
}

void pauseFrame(int frames){
  unsigned long currentTime;
  int sensVal;  // variable to store the value coming from the sensor
  unsigned long endTime = (millis() * 1000) + (frames * frameDuration);  // calculate the end time

  while((millis() * 1000) < endTime){

    // check the sensor
    sensVal = analogRead(sensorPIN);  // read the Hall Effect Sensor
    if (sensVal > (mean + sensitivity) || sensVal < (mean - sensitivity)) {
      currentTime = millis() * 1000;  // in microseconds
      if(currentTime < (startTime + (20 * frameDuration))){  // debounce the sensor reading
        startTime = currentTime;  // reset the start time
      } 
      else {
        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
        updateByteArray(newText(currentTime - startTime));
        startTime = currentTime;  // reset the start time
        byteNum = 0;
        break;
      }
    }
  }
}

char* newText(unsigned long duration){
  int n; // number of char written to the string (not used)
  char newString[70];
  // calculate distance
  unsigned long distancem = numWheelRotations * wheelCurcum / 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 = wheelCurcum * 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 (newString, "%ld.%ld km   %ld.%ld km/hr \n", distancekm, distanceRem, speedkm, speedRem);

  return newString;
}

void updateByteArray(char textString[])
{
  int x=0;
  for (int i=0; i<strlen(textString); i++){
    char ch = textString[i];
    // 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 > 96){
      ch = 32;
    }
    // subtract the space character
    ch -= 32; // converts the ASCII number to the font index number
    // step through each byte of the character array
    for (int j=0; j<charWidth; j++) {
      byteString[x++] = font[ch][j];
    }
    // add space between letters
    for(int k=0; k<letterSpace; k++) {
      byteString[x++] = 0;
    }
  }
  // add space at the end of the string
  for(int l=0; l<stringSpace; l++) {
    byteString[x++] = 0;
  }
  // end with an eight bit flag (the text only uses 7 bites)
  byteString[x] = 0xFF;
}