Joshua Newth / Mbed 2 deprecated POV01

Dependencies:   mbed

main.cpp

Committer:
mrfurious
Date:
2010-11-04
Revision:
0:e4ea0ca99174

File content as of revision 0:e4ea0ca99174:

/*
Date: 04/08/10
Version 0.1.3

Notes
Write strings to display
Update speed reporting based on calculated time


Bugs
Can update displayed strings, but cant stay at constant speed
at value not equal to 0, 10, or 20. during accel it will increase
from 10 to 20 1 at a time.

Known Issues
1.Pin20 seems a bit dodgy. InterruptIn does not work on that pin.
2. Pin19 seems a bit dodgy. InterruptIn does not work on that pin.

*/

#include "mbed.h"
#include "FontPack.h"

using namespace FontPack;

#define true 1
#define false 0

#define MSEC_USEC 1000
/*
we get msec/rev, what we want is miles/hour
[1rev/(PI*Dia)in]*[12in/ft]*[5280ft/1mi]*[1sec/1000ms]*[1hr/3600sec]
% has units of hr/mi, so invert
 */
#define POV_DIAMETER 26.5
#define PI 3.14 

#define POV_NUM_SAMPLES 3

#define POV_NUM_COLS 360 //how many cols make up the whole wheel
#define POV_MIN_SPEED_MPH 3

#define POV_NUM_LEDS 8 //leds to paint
#define POV_HALL_DEBOUNCE_US 2000*MSEC_USEC //debug code - long suppression

//#define POV_HALL_DEBOUNCE_US 250*POV_MSEC_TO_USEC

//DigitalOut led[POV_NUM_LEDS] = { p21, p22, p23, p24, p25, p26, p27, p28};
DigitalOut led[POV_NUM_LEDS] = {p28, p27, p26, p25, p24, p23, p22, p21};
InterruptIn hall(p17);
Ticker paintTimer; //repeating ISR call
//Timeout suppressHallTimer; //single ISR call
Timer wheelSpeedTimer; //true timer, not an ISR call
/*
CONVERTER when multiplied by msec/rev results in hr/mi
so the inversion of the product is mph
pov_converter = [12in/1ft]*[5280ft/1mi]*[1sec/1000msec]*[1hr/3600s]
pov_converter = pov_diameter/pov_converter
mph = pov_converter/ (ms/rev)
*/
static double POV_CONVERTER=.0056;

static bool hallFlag = false;
static bool hallSuppressed = false;
static bool paintFlag = false;
static int columnCounter = 0;
static int wheelSpeedCounter_ms = 0;



/*FUNCTION DECLARATIONS*/
static void paintInterrupt(void);
//static void suppressInterrupt(void);
static void hallEffectDetected(void);
static void paint(char canvas[]);
static void updateCanvas(char canvas[], float wheelSpeed_mph);
static int writeString(char canvas[], const char* msg, int index) ;

float updateWheelSpeed(int wheelSpeedCtr_us);
static void turnLightsOn(bool isOn);

int main() {
    float wheelSpeed_mph = 0;
    int colSpeed_us = 0;
    char canvas[POV_NUM_COLS] = {0};
    POV_CONVERTER = POV_DIAMETER / POV_CONVERTER;

    turnLightsOn(false);
    hall.fall(&hallEffectDetected);  // attach the address of the handling routine
    hall.mode(PullUp);
    wheelSpeedTimer.start();
    paintTimer.attach(&paintInterrupt, 1);

    while (true) {
        if (hallFlag) {
            hallFlag = false;
            colSpeed_us = wheelSpeedCounter_ms*MSEC_USEC / POV_NUM_COLS;
            wheelSpeed_mph = updateWheelSpeed(wheelSpeedCounter_ms);
            updateCanvas(canvas, wheelSpeed_mph);
            if (wheelSpeed_mph > POV_MIN_SPEED_MPH) {
            //if (true) {
                paintFlag = true;
                paintTimer.attach_us(&paintInterrupt, colSpeed_us);
                columnCounter = 0;
                //paintTimer.attach(&paintInterrupt, 1); //debug - msec, slow update
            }
            hallSuppressed = false;
        }

        if (paintFlag) {
            paintFlag = false;
            paint(canvas);
        }
    }
}

static void paintInterrupt(void) {
    ++columnCounter;
    paintFlag = true;
}


static void hallEffectDetected(void) {
    if (!hallSuppressed) {
        hallSuppressed = true;
        paintFlag = false;
        wheelSpeedCounter_ms = wheelSpeedTimer.read_ms();
        wheelSpeedTimer.reset();
        hallFlag = true;
    }
}

static void paint(char canvas[]) {
    if (columnCounter >= POV_NUM_COLS) return;
    int LED = canvas[columnCounter];
    for (int i=0; i < POV_NUM_LEDS; i++) {
        led[i] = (LED >> i) & 0x01; //just get the last bit for comparison
    }
}


static void updateCanvas(char canvas[], float wheelSpeed_mph) {
    int index = 120;
    char msg[30];
    memset(canvas, 0x00, POV_NUM_COLS);
    float bike_distance = 0;
    //sprintf(msg, "Distance: %2f Speed: %2.2f MPH", wheelSpeed_mph);
   // sprintf(msg, "Speed: %2.1fMPH Distance: %2.1f", wheelSpeed_mph);
   
   
    
    sprintf(msg, "Speed: %2.1f MPH", wheelSpeed_mph);
    
    index = writeString(canvas, msg, 90);
    
}

static int writeString(char canvas[], const char* msg, int index) {

    while ((msg != NULL) && (*msg != '\0')) {
        index = writeChar(*msg, canvas, index);
        msg++;
    }
    return index;
}


static void turnLightsOn(bool isOn) {
    for (int i=0; i < POV_NUM_LEDS; i++) {
        led[i]=isOn;
    }
}


//Aggregates and stores num samples in the averager
//computes running average by always replacing value at index
//with new measured value, then updating sample with new measured value

float updateWheelSpeed(int wheelSpeedCtr_ms) {
    static float samples[POV_NUM_SAMPLES] =  {0};
    static char index = 0;
    static float avgSpeed_mph = 0;

    //float lin = POV_CONVERTER/((float) wheelSpeedCtr_ms);
    //return lin;
    
     if (wheelSpeedCtr_ms != 0) {
        float linearSpeed_mph = POV_CONVERTER/((float) wheelSpeedCtr_ms);
        //calculate new running average
        avgSpeed_mph = avgSpeed_mph - samples[index]/POV_NUM_SAMPLES + linearSpeed_mph/POV_NUM_SAMPLES;
        //store new sample
        samples[index] = linearSpeed_mph;
        //update averager index
        index = ++index % POV_NUM_SAMPLES;
    }
    
    return avgSpeed_mph;
}