by iepaul on Wed Nov 16, 2011 4:12 pm

Hi,

I want to use the minipov2 with a hall effect sensor. To test I was going to mount it on my kids bicycle wheel. Here is the code I have but I am not sure if this is the best was to handle it. This is pieced together from the samples on the site. I am wondering if there is a better way to do the timing also?

Code: Select all
#include <avr/io.h>      // this contains all the IO port definitions
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <util/delay.h>
#include <avr/pgmspace.h>

// This function basically wastes time
void delay_ms( uint16_t milliseconds)
{
   for( ; milliseconds > 0; milliseconds--)
   {
      _delay_ms( 1);
   }
}

// We use these macros because binary constants arent always supported. ugh.
#define HEX__(n) 0x##n##UL
#define B8__(x) ((x&0x0000000FLU)?1:0)  \
               +((x&0x000000F0LU)?2:0)  \
               +((x&0x00000F00LU)?4:0)  \
               +((x&0x0000F000LU)?8:0)  \
               +((x&0x000F0000LU)?16:0) \
               +((x&0x00F00000LU)?32:0) \
               +((x&0x0F000000LU)?64:0) \
               +((x&0xF0000000LU)?128:0)
#define B8(d) ((unsigned char)B8__(HEX__(d)))

// store all the image data in program memory (ROM)
// instead of RAM (the default)
const uint8_t large_image[] PROGMEM = {
B8(00000000),
B8(00000000),
B8(00000000),
B8(00000000),
B8(00000000),
B8(00000000),
B8(00000000),
B8(10000010),
B8(11111110),
B8(10100010),
B8(00100010),
B8(01011100),
B8(10000000),
B8(10000000),
B8(11000000),
B8(10111010),
B8(00100110),
B8(10111000),
B8(11000000),
B8(10000000),
B8(00000000),
B8(01111100),
B8(10000010),
B8(10000010),
B8(10000010),
B8(01000110),
B8(00000000),
B8(10000010),
B8(11111110),
B8(10010010),
B8(00010000),
B8(10010010),
B8(11111110),
B8(10000010),
B8(00000000),
B8(10000010),
B8(11111110),
B8(10010010),
B8(10111010),
B8(11000110),
B8(00000000),
B8(00000000),
B8(10000010),
B8(11111110),
B8(10000010),
B8(10000000),
B8(11100000),
B8(00000000),
B8(00000000),
};

// special pointer for reading from ROM memory
PGM_P largeimage_p PROGMEM = large_image;

#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))
int imagesize = NUM_ELEM(large_image);

uint8_t j = 0;

int main(void) {

  DDRB = 0xFF;        // set port B to output only
  PORTB = 0;          // turn off all LEDs

  DDRD = 0xFB;        // one input on pin D2
  PORTD = 0x04;       // turn on pullup on pin D2

  while (1) {
    if (PIND & 0x4) {        // if the sensor switch is off...
      PORTB = 0x0;
    } else {                 // if the sensor switch is on...
        // if (j >= imagesize)
      // j = 0;
      // read the image data from ROM
      
      for (j =0; j < imagesize + 1; j++)
      {
         PORTB = pgm_read_byte(largeimage_p + j);
         delay_ms(1);
      }         
    }
  }
}
iepaul
 
Posts: 1
Joined: Wed Nov 16, 2011 4:06 pm

by mtbf0 on Fri Nov 25, 2011 12:52 am

hopefully the following will work. i assume that your hall effect sensor is active low. otherwise use (PIND & 0x04)

Code: Select all
      while (1) {
        if (PIND ^ 0x4) {
          j = 0;
        }
        if (j < imagesize) {
         PORTB = pgm_read_byte(largeimage_p + j++);
         delay_ms(1);
        }


it would be better to have the sensor trigger an interrupt, because you can miss pulses during delay_ms. and, of course, this will only display correctly over a small range of wheel speeds. to correct the timing you'll want to start a timer and check it's value every time PIND ^ 4, then adjust your delay accordingly.
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more
User avatar
mtbf0
 
Posts: 1645
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

by adafruit_support_bill on Fri Nov 25, 2011 5:51 am

to correct the timing you'll want to start a timer and check it's value every time PIND ^ 4, then adjust your delay accordingly.

Have a look at the SpokePOV code to see how this is done there.
User avatar
adafruit_support_bill
 
Posts: 25323
Joined: Sat Feb 07, 2009 9:11 am