Help with POV Clock sketch

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Help with POV Clock sketch

Postby bafil » Fri Apr 20, 2012 3:13 pm

Hello all you Arduino experts out there.

I am working on a POV clock project but I need some help with the code. So far I have learned how to do basic programming of my Arduino UNO, such as blinking LED's and a Knight Rider sequence. I also did a very very basic POV that will spell out a predefined word that reads from an X-Y grid. I have looked at many many many internet sites for Arduino specific POV clock code but I cannot find much. Although I have found plenty using PIC's. I am hoping someone can point me into some Arduino sketch code to make one.

So far here is what my plans are and what parts I have.

I would like to use 8-LED's but I am willing to change that if its too much of a problem (I don't think it would be much different than a smaller cluster of LED's)

I also want the characters to appear as 5 LED's wide, which seems pretty common.

I am going to be using an Adafruit RTC DS1307 breakout board to take care of the clock stuff.

I am thinking that I need to sample the time portion from the RTC then somehow map a character set to each digit from the RTC then display them. I don't know where to start.

The motor speed control will be independent from the Arduino stuff.

My electronics experience is very extensive so I am just asking for help with a POV Clock code or help getting an RTC clock code to work with a POV code. I do have some experience in programming some other microcontrollers like 8051's in assembly (yuck), and I have learned how to write C code but not at an expert level.

Thanks everyone.

Oh and please go easy on me since this is my very first post and I am new to this stuff.
bafil
 
Posts: 9
Joined: Sun Apr 15, 2012 10:16 am

Re: Help with POV Clock sketch

Postby mtbf0 » Fri Apr 20, 2012 10:12 pm

here is some minipov3 code that does some of what you want. takes an ascii string as input and outputs as a pov display. very slowly. this was supposed to be used with uv leds to write on walls painted with phosphorescent paint, so you'd want to speed up the timer interrupt.

the interesting stuff's in the interrupt service routine.

if the code is of no interest you can at least snag the bitmaps for the digits.

Code: Select all
/*
    MENEpov.c - Version 1.0

    Copyright 2009 Bobby Cossum.  All Rights reserved.

    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 banned FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    This firmware is written to run on a minipov3 board from www.adafruit.com.
    The red leds supplied with the kit should be replaced with ultra-violet ones
    and a prompting led should be installed between the signal and ground pins
    of the sensor inputs.  Care must be taken to provide adequate voltage for
    to drive the uv leds which typically have a voltage drop higher than the
    red leds supplied with the board.  The values of the current limiting
    resistors will have to be selected based on your supply voltage and the
    specifications of the leds you use.

    My prototype uses leds with a 3.2 volt drop, a 5v supply, and 100 ohm series
    resistors.  Something like 90 ohms would have been a better choice if i had
    had any.

    Finally, please do not look directly at ultra-violet leds.
*/
#include "avr/io.h"             // i/o definitions
#include "avr/interrupt.h"      // definitions for interrupts
#include "avr/pgmspace.h"       // definitions for data in program memory
#include "avr/sleep.h"          // definitions for idling mcu

#define GLYFWIDTH 5

//
//  data in program memory
//
//  foo      - avrobjdump trashes the first symbol after the interrupt vectors,
//        so we'll just feed it this.
//  text   - display text is a single string with lines delimited with nulls
//  povGlyf   - character bitmaps.  each character is 5 bytes, one per column of
//        of a 5x8 cell.  low order bit is the top.

int foo PROGMEM = 666;

char text[] PROGMEM = "The Moving Finger writes; and, having writ,\0"
                      "Moves on; nor all your Piety nor Wit\0"
                 "Shall lure it back to cancel half a Line,\0"
                 "Nor all your Tears wash out a Word of it.";

uint8_t povGlyf[] PROGMEM = {
/*   */ 0x00,0x00,0x00,0x00,0x00, /* ! */ 0x00,0x00,0x5f,0x00,0x00,
/* " */ 0x00,0x07,0x00,0x07,0x00, /* # */ 0x14,0x7f,0x14,0x7f,0x14,
/* $ */ 0x24,0x2a,0x7f,0x2a,0x12, /* % */ 0x23,0x13,0x08,0x64,0x62,
/* & */ 0x36,0x49,0x55,0x22,0x50, /* ' */ 0x00,0x05,0x03,0x00,0x00,
/* ( */ 0x00,0x1c,0x22,0x41,0x00, /* ) */ 0x00,0x41,0x22,0x1c,0x00,
/* * */ 0x08,0x2a,0x1c,0x2a,0x08, /* + */ 0x08,0x08,0x3e,0x08,0x08,
/* , */ 0x00,0x50,0x30,0x00,0x00, /* - */ 0x08,0x08,0x08,0x08,0x08,
/* . */ 0x00,0x60,0x60,0x00,0x00, /* / */ 0x20,0x10,0x08,0x04,0x02,
/* 0 */ 0x3e,0x51,0x49,0x45,0x3e, /* 1 */ 0x00,0x42,0x7f,0x40,0x00,
/* 2 */ 0x42,0x61,0x51,0x49,0x46, /* 3 */ 0x21,0x41,0x45,0x4b,0x31,
/* 4 */ 0x18,0x14,0x12,0x7f,0x10, /* 5 */ 0x27,0x45,0x45,0x45,0x39,
/* 6 */ 0x3c,0x4a,0x49,0x49,0x30, /* 7 */ 0x01,0x71,0x09,0x05,0x03,
/* 8 */ 0x36,0x49,0x49,0x49,0x36, /* 9 */ 0x06,0x49,0x49,0x29,0x1e,
/* : */ 0x00,0x36,0x36,0x00,0x00, /* ; */ 0x00,0x56,0x36,0x00,0x00,
/* < */ 0x00,0x08,0x14,0x22,0x41, /* = */ 0x14,0x14,0x14,0x14,0x14,
/* > */ 0x41,0x22,0x14,0x08,0x00, /* ? */ 0x02,0x01,0x51,0x09,0x06,
/* @ */ 0x32,0x49,0x79,0x41,0x3e, /* A */ 0x7e,0x11,0x11,0x11,0x7e,
/* B */ 0x7f,0x49,0x49,0x49,0x36, /* C */ 0x3e,0x41,0x41,0x41,0x22,
/* D */ 0x7f,0x41,0x41,0x22,0x1c, /* E */ 0x7f,0x49,0x49,0x49,0x41,
/* F */ 0x7f,0x09,0x09,0x01,0x01, /* G */ 0x3e,0x41,0x41,0x51,0x32,
/* H */ 0x7f,0x08,0x08,0x08,0x7f, /* I */ 0x00,0x41,0x7f,0x41,0x00,
/* J */ 0x20,0x40,0x41,0x3f,0x01, /* K */ 0x7f,0x08,0x14,0x22,0x41,
/* L */ 0x7f,0x40,0x40,0x40,0x40, /* M */ 0x7f,0x02,0x04,0x02,0x7f,
/* N */ 0x7f,0x04,0x08,0x10,0x7f, /* O */ 0x3e,0x41,0x41,0x41,0x3e,
/* P */ 0x7f,0x09,0x09,0x09,0x06, /* Q */ 0x3e,0x41,0x51,0x21,0x5e,
/* R */ 0x7f,0x09,0x19,0x29,0x46, /* S */ 0x46,0x49,0x49,0x49,0x31,
/* T */ 0x01,0x01,0x7f,0x01,0x01, /* U */ 0x3f,0x40,0x40,0x40,0x3f,
/* V */ 0x1f,0x20,0x40,0x20,0x1f, /* W */ 0x7f,0x20,0x18,0x20,0x7f,
/* X */ 0x63,0x14,0x08,0x14,0x63, /* Y */ 0x03,0x04,0x78,0x04,0x03,
/* Z */ 0x61,0x51,0x49,0x45,0x43, /* [ */ 0x00,0x00,0x7f,0x41,0x41,
/* \ */ 0x02,0x04,0x08,0x10,0x20, /* ] */ 0x41,0x41,0x7f,0x00,0x00,
/* ^ */ 0x04,0x02,0x01,0x02,0x04, /* _ */ 0x40,0x40,0x40,0x40,0x40,
/* ` */ 0x00,0x01,0x02,0x04,0x00, /* a */ 0x20,0x54,0x54,0x54,0x78,
/* b */ 0x7f,0x48,0x44,0x44,0x38, /* c */ 0x38,0x44,0x44,0x44,0x20,
/* d */ 0x38,0x44,0x44,0x48,0x7f, /* e */ 0x38,0x54,0x54,0x54,0x18,
/* f */ 0x08,0x7e,0x09,0x01,0x02, /* g */ 0x08,0x14,0x54,0x54,0x3c,
/* h */ 0x7f,0x08,0x04,0x04,0x78, /* i */ 0x00,0x44,0x7d,0x40,0x00,
/* j */ 0x20,0x40,0x44,0x3d,0x00, /* k */ 0x00,0x7f,0x10,0x28,0x44,
/* l */ 0x00,0x41,0x7f,0x40,0x00, /* m */ 0x7c,0x04,0x18,0x04,0x78,
/* n */ 0x7c,0x08,0x04,0x04,0x78, /* o */ 0x38,0x44,0x44,0x44,0x38,
/* p */ 0x7c,0x14,0x14,0x14,0x08, /* q */ 0x08,0x14,0x14,0x18,0x7c,
/* r */ 0x7c,0x08,0x04,0x04,0x08, /* s */ 0x48,0x54,0x54,0x54,0x20,
/* t */ 0x04,0x3f,0x44,0x40,0x20, /* u */ 0x3c,0x40,0x40,0x20,0x7c,
/* v */ 0x1c,0x20,0x40,0x20,0x1c, /* w */ 0x3c,0x40,0x30,0x40,0x3c,
/* x */ 0x44,0x28,0x10,0x28,0x44, /* y */ 0x0c,0x50,0x50,0x50,0x3c,
/* z */ 0x44,0x64,0x54,0x4c,0x44, /* { */ 0x00,0x08,0x36,0x41,0x00,
/* | */ 0x00,0x00,0x7f,0x00,0x00, /* } */ 0x00,0x41,0x36,0x08,0x00,
/* ~ */ 0x08,0x08,0x2a,0x1c,0x08, /*   */ 0x08,0x1c,0x2a,0x08,0x08
};

//
//  data in sram
//
char c = 0;         // character being output
uint8_t pauseBefore = 95;   // pause at the end of each line this long
uint8_t blink = 1;      // then turn on indicator for this long
uint8_t pauseAfter = 48;   // then wait this long before next line
volatile uint8_t run = 1;   // main program loop runs while (run);
uint8_t buffB;         // hold PORTB output 'til next interrupt
char* textPtr = text;      // pointer into display text
uint8_t* glyfPtr;      // pointer into character bitmap table
uint8_t glyfColumn;      // how far we are through the current character

ISR (TIMER0_OVF_vect) {
  PORTB = buffB;      // ouput one column
  if (c) {         // not at end of string
    if (glyfColumn++ < GLYFWIDTH) {
      buffB = pgm_read_byte (glyfPtr++);
    }
    else {         // we've output all 5 columns of character
      buffB = 0;      // prepare to put space between characters
      c = pgm_read_byte (textPtr++);   // get next character
      if (c) c -= 31;      // if it's not null, map to glyph array
      glyfPtr = (uint8_t*)((povGlyf - 5) + ((int)c << 2) + (int)c);
      glyfColumn = 0;      // start counting at first column
    }
  }
  else if (pauseBefore) {   // pause 2 sec before blinking led
    pauseBefore--;
  }
  else if (blink) {      // turn on green led
    blink--;
    PORTD |= (1 << PD2);
  }
  else if (pauseAfter) {   // pause 1 sec after blinking led
    PORTD &= ~(1 << PD2);
    pauseAfter--;
  }
  else if (textPtr < (char*)(text + sizeof(text))) {   // if there's more text
    c = 0xff;         // force acquisition of 1st char of next line
    glyfColumn = 5;      // ditto
    pauseBefore = 95;      // 2 seconds based on 48Hz interrupt frequency
    blink = 1;         // 1/48 second
    pauseAfter = 48;      // 1 second
  }
  else {         // end of text, signal main program to terminate
    run = 0;
  }
}

int main (void) {
//
//  set up i/o ports
//
  PORTD = 0x00;         // PD2 out
  PORTB = 0x00;         // all out
  DDRD = (1 << PD2);      // indicator led
  DDRB = 0xff;         // pov display
//
//  setup timer 0, 1/1024 prescale, mode 7, 48Hz, enable interrupt
//
  TCCR0A = (1 << WGM01) | (1 << WGM00);      // select fast pwm w/ top = OCR0A
  TCCR0B = (1 << WGM02) | (1 << CS02) | (1 << CS00);   // and prescale = 1024
  OCR0A = 163;         // gives interrupt freq ca 48Hz
  TIMSK = (1 << TOIE0);      // enable overflow interrupt
  sei ();         // enable interrupts
  MCUCR = (1 << SE);      // enable idle sleep mode
  while (run) {
    sleep_cpu ();
  }
  TCCR0B = 0x00;      // stop timer
  DDRB = 0;
  DDRD = 0;
  PORTB = 0;
  PORTD = 0;
  MCUCR = (1 << SE) | (1 << SM0);// enable shutdown sleep mode
  sleep_cpu ();         // zzzzzzzzzzzz
}
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca


Return to Arduino

Who is online

Users browsing this forum: wildan03 and 10 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [102]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[33]
LCDs & Displays[48]
Components & Parts[69]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[109]
 
Wireless[14]
Cables[60]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]