POV Waving Device

Hi,

it is winter time and I played a bit with my arduino. I now this is not a very fresh idea however I want to share.

I tried to sync the waving with a mercury switch, and even try to use the duration of an amplitude to control the delay. Of course the writing direction gets switched.

Works ok now, however it could need some more testing, but my arm hurts :wink:

This image is from the "prototype" ;D meaning the sync did not work, it is hard to make a picture when the sync works, this is more for the human eye.

/*
 * Wink: POV Display test
 * 
 */
#include <avr/pgmspace.h>

int dir = 1;
int time = 0;
int atime = 0;
int pos = 0;
int val = 0;

int myPins[] = {
  6,7,8,9,10,11,12,13};

//  + HALLO + 
prog_uchar PROGMEM BitMap[] = {
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00010000,
  B00010000,
  B01111100,
  B00010000,
  B00010000,
  B11111111,
  B00010000,
  B00010000,
  B11111111,
  B00000000,
  B11111111,
  B00010001,
  B00010001,
  B11111111,
  B00000000,
  B11111111,
  B10000000,
  B10000000,
  B10000000,
  B00000000,
  B11111111,
  B10000000,
  B10000000,
  B10000000,
  B00000000,
  B11111111,
  B10000001,
  B10000001,
  B11111111,
  B00000000,
  B00000000,
  B00000000,
  B00010000,
  B00010000,
  B01111110,
  B00010000,
  B00010000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000
};
int len = sizeof(BitMap);


void setup()                    // run once, when the sketch starts
{
  for (int i=0; i <= 7; i++){
    pinMode(myPins[i], OUTPUT);      // sets the digital pin as output
  } 
  pinMode(5, INPUT);      // RIGHT sets the digital pin as input
  pinMode(4, INPUT);      // LEFT  sets the digital pin as input
  pinMode(3, OUTPUT);      // sets the digital pin as output
  //Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps
  //Serial.println(sizeof(BitMap),DEC); 
}

void setLEDs(prog_uchar pattern)
{
  for (byte i=0; i <= 7; i++){
    if (pattern & (1<<i)) {
      digitalWrite(myPins[i],HIGH);   
    } 
    else {
      // turn off the LED at location (x,y)
      digitalWrite(myPins[i],LOW);   
    }
  } 
}

void loop()                     // run over and over again
{
  time++;
  if (digitalRead(4)==HIGH and dir==1)  // checks mercury switch at port 4
  {
    dir = -1;
    atime = time;
    time = 0;
    pos=0;    //sync to start of waving
  }
  else if (digitalRead(4)==LOW and dir==-1) 
  {
    dir = 1;
    atime = time;
    time = 0;
    pos=len;  //sync to start of waving
  }

  if (dir==1){
    digitalWrite(3,HIGH);
    pos = (pos + dir) % len ;
  }
  else
  {
    digitalWrite(3,LOW);
    pos = (pos + dir);
    if (pos<0)
    {
      pos = len;
    }
  }

  // Try to sync to waving speed
  val = atime+analogRead(2);    // read the value from the pot
  setLEDs(pgm_read_byte_near(&BitMap[pos]));
  delayMicroseconds(val);                  // waits 
  setLEDs(0);
  delayMicroseconds(val);                  // waits   
}

Any suggestions code wise and how to get the ultimative POV effect are welcome.

Carsten

Hi Carsten, good job!

 if (digitalRead(4)==HIGH and dir==1)

The C language uses && for a logical and. I have never seen the word and used instead of &&. Have you seen this documented somewhere? I guess it works if your sketch runs ok

Coding style is very much a personal thing, but FWIW here are some coding suggestions

Your code will be easier to understand if you use #defines for constants. For example:

pinMode(5, INPUT);  
if (digitalRead(4)==HIGH and dir==1)

could be:

#define LEFT 1
#define leftPin 4

 pinMode(leftPin, INPUT);      
 if (digitalRead(leftPin)==HIGH && dir== LEFT)  // checks mercury switch

It wont make a big difference, but there are some expressions you can simplify, for example you can replace:

    if (pattern & (1<<i)) {
      digitalWrite(myPins[i],HIGH);  
    }
    else {
      // turn off the LED at location (x,y)
      digitalWrite(myPins[i],LOW);  
    }

with:

     digitalWrite(myPins[i], pattern & (1<<i) ); // Set the LED state to match the bit at position i

but stick with what you feel most comfortable with.

Have fun!

Thanks mem for your kind words!

The "and" is really strange, I am used to programm in Python, so I don't mention it... No syntax error and it seems to work... Maybe the and is threaded as constant or something... Have to check.

The other suggestions I will use next time I touch the project! I like nice code, however I am a lazy guy also and this is more for recreation, like others doing puzzle games or such :wink:

Carsten :wink:

PS: The ugly code also results of the experiments and tries I did before, changed much without restarting a freah project etc.

Looks really good, I can't wait to try this with my breadboard...

My code now:

/*
 * Wink: POV Display test
 * Wire LEDs according to the pins below
 * The mercury switch needs to be on the left, so it closes while waving LEFT!
 */
#include <avr/pgmspace.h>

#define LEFT 1
#define RIGHT -1
#define MERCURYSW 4
#define DEBUG  3

int dir = 1;
int time = 0;
int atime = 0;
int pos = 0;
int val = 0;

int myPins[] = {
  6,7,8,9,10,11,12,13};

//  + HALLO + 
prog_uchar PROGMEM BitMap[] = {
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00010000,
  B00010000,
  B01111100,
  B00010000,
  B00010000,
  B11111111,
  B00010000,
  B00010000,
  B11111111,
  B00000000,
  B11111111,
  B00010001,
  B00010001,
  B11111111,
  B00000000,
  B11111111,
  B10000000,
  B10000000,
  B10000000,
  B00000000,
  B11111111,
  B10000000,
  B10000000,
  B10000000,
  B00000000,
  B11111111,
  B10000001,
  B10000001,
  B11111111,
  B00000000,
  B00000000,
  B00000000,
  B00010000,
  B00010000,
  B01111110,
  B00010000,
  B00010000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000
};
int len = sizeof(BitMap);


void setup()                    // run once, when the sketch starts
{
  for (int i=0; i <= 7; i++){
    pinMode(myPins[i], OUTPUT);      // sets the digital pin as output
  } 
  pinMode(MERCURYSW, INPUT);      //  sets the digital pin as input (mercury switch)
  pinMode(DEBUG, OUTPUT);      // sets the digital pin DEBUG as output
}

void setLEDs(prog_uchar pattern)
{
  for (byte i=0; i <= 7; i++){
      digitalWrite(myPins[i],pattern & (1<<i));   // Bit shifting magic
  } 
}

void loop()    // run over and over again
{
  time++;
  if (digitalRead(MERCURYSW)==HIGH && dir==LEFT)  // checks mercury switch
  {
    dir = RIGHT;
    atime = time;
    time = 0;
    pos=0;    //sync begin of text to start of waving
  }
  else if (digitalRead(MERCURYSW)==LOW && dir==RIGHT) 
  {
    dir = LEFT;
    atime = time;
    time = 0;
    pos=len;  //sync text end to start of waving
  }

  if (dir==1){
    digitalWrite(DEBUG,HIGH); // Debug LED used here to indicate the mercury switch state
    pos = (pos + dir) % len ;
  }
  else
  {
    digitalWrite(DEBUG,LOW); // Debug LED
    pos = (pos + dir);
    if (pos<0)
    {
      pos = len;
    }
  }

  // Try to sync to waving speed (still far from perfect!)
  val = atime+analogRead(2);    // read the value from the pot to change the frequency
  setLEDs(pgm_read_byte_near(&BitMap[pos])); // switch on the LEDs
  delayMicroseconds(val);                  // waits 
  setLEDs(0);                              // switch off all LEDs
  delayMicroseconds(val);                  // waits   
}