boarduino w/ lilypad libs, bootloader and 32.768kHz crystal

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

boarduino w/ lilypad libs, bootloader and 32.768kHz crystal

Postby mtbf0 » Sat Nov 10, 2007 8:57 am

1). i'd like my boarduino to keep time, so i thought i'd ditch the resonator and install a watch crystal, instead. of course, that means it won't be running at 16MHz anymore, so i thought maybe i could use the libraries and bootloader for the new lilypad arduinos which also lacks a resonator or crystal.

2). i seem to recall that some avrs had the TOSC1 and TOSC2 pins compensated somehow so that you don't need capacitors between the leads of a low speed crystal and ground, but i don't see this anywhere in the mega168 datasheet.

my questions, then, are will 1) work and does anyone know about 2).

thanks.
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby mtbf0 » Sat Nov 10, 2007 11:16 am

ok, chapter 8 of the mega168 datasheet , near as i can tell, does not recommend capacitors for crystal frequencies below 900KHz. i also found a schematic with a 32.768KHz crystal connected across TOSC1 and TOSC2 without caps. the page was in german, which is, as they say, greek to me, so it may have been a "what not to do" example but i'll hope for the best.
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby adafruit » Tue Nov 13, 2007 7:40 pm

well, you can still keep time with a 16mhz crystal..just have to do some more math :)
are you planning to use the Arduino software to program the boarduino?
User avatar
adafruit
 
Posts: 10489
Joined: Thu Apr 06, 2006 3:21 pm
Location: nyc

Postby mtbf0 » Wed Nov 14, 2007 12:51 am

yes, i was planning to use the arduino software, assuming that timer2 is available. i've got two kits and a tinyusbisp. the plan is build one kit with the 16MHz resonator and use that board to reprogram the fuses to use the internal oscillator, then build the other kit with a watch crystal in place of the resonator, move the chip with the new fuse settings to that board and burn it with the lilypad bootloader, then, yeah, program it with the arduino software with, you know, the assumption previously stipulated. of course, if timer2 is not available i can always just code everything myself in c.

for now, i've got the flu, so i'm not allowed to play with the soldering iron and have plenty of time to think things out.

of course, if you've any ideas...
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby adafruit » Thu Nov 15, 2007 8:46 pm

i dont think this will work, the arduino software pretty much requires the chip to be running at a fixed clock speed. if you change the fuses its going to probably spazz out the chip.
User avatar
adafruit
 
Posts: 10489
Joined: Thu Apr 06, 2006 3:21 pm
Location: nyc

Postby mtbf0 » Thu Jan 10, 2008 1:42 pm

takes me a while to get around to things, but i finally soldered up a boarduino with a 3 pin female header soldered in place of the oscillator then dropped the oscillator into the header and hooked up my usbtinyisp. then applied a little ...

avrdude -c usbtiny -p m168 -U lfuse:w:0xf2:m

... to select the internal oscillator and removed the oscillator and fired up the arduino software, selected lilypad arduino and then burn bootloader.

then a wrote a little sketch to write "Hello, world!" back to the puter and flash the pin 13 led at 1Hz and it seems to be working, you know, using my old one mississippi, two mississippi time base. so the serial comms are working and the delay function is, anyways, close.

haven't tried any pwm, yet, but i am cautiously hopeful. alas, i soldered the headers in so crooked i can't get the thing into a breadboard, but i'll drop in a watch crystal and start working on a timekeeping sketch using my laptop for i/o.

can anyone suggest a way to pry the meag168 out of its socket?
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby adafruit » Thu Jan 10, 2008 3:15 pm

User avatar
adafruit
 
Posts: 10489
Joined: Thu Apr 06, 2006 3:21 pm
Location: nyc

Postby mtbf0 » Thu Jan 10, 2008 6:00 pm

yeah managed to extract myself from the web of power cords and programming dongles i'd trussed myself with and dug out the old computer tool kit and there it was. funny li'l u shaped thing with grabby bits at the ends. had to bend the power select jumper pins out of the way though.

now i've got a boarduino, (16MHz oscillator), a clockuino, (32.768KHz crystal), and a convertibleeno, (female header).

woohoo!
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby trialex » Tue Jan 15, 2008 11:47 pm

Dude this is awesome. Do you have any more details on getting an Arduino working with a watch crystal?
trialex
 
Posts: 188
Joined: Mon Apr 03, 2006 5:25 pm

Postby mtbf0 » Thu Jan 17, 2008 11:07 pm

trialex wrote:Dude this is awesome. Do you have any more details on getting an Arduino working with a watch crystal?


i used two boarduinos, and a usbtinyisp.

built one boarduino with the 16Mhz oscillator and one with a 32.768KHz watch crystal. the watch crystal should be soldered to the two outer pads of the three that the oscillator would have been in. install mega168 in board with 16MHz oscillator. attach usbtinyisp and run avrdude with

Code: Select all
avrdude -p m168 -cusbtiny -U lfuse:w:0xf2:m


this makes the chip run on its internal 8MHz oscillator. now, with the isp still connected, run the arduino software. from the tools menu select burn bootloader. select lilypad arduino.

now remove the the chip from the board with the oscillator and install it on the board with the watch crystal. you pretty much need a chip puller to remove the chip from the board. it also helps to remove the power select jumper.

you now have a boarduino that runs at 8MHz, instead of the standard 16MHz. everything seems to work. i have my board set up with a 2x16 character lcd and make heavy use of the delay routines. i also use pwm on digital 10 to control the back light on the lcd.

i originally used digital 11 for the backlight, but it turns out that the pwm on digital 11 is generated by timer 2, which we'll have to hijack to use the watch crystal.

out of curiosity i displayed the contents of the timer2 control registers on my lcd and found that the timer was already running when my setup routine was called, so the first thing to do is stop the timer. then we need to change its source from the chip's i/o clock, to the watch crystal and set up an appropriate prescaler. all of this is explained with much obfuscation in the mega168 datasheet.

to set up the timer, use the following code in the setup routine

Code: Select all
  TCCR2A = 0;
  TCCR2B = 0;                         // this stops the timer
  TCNT2 = 0;                          // reset the timer2 counter
  ASSR = (1 << AS2);             // select watch crystal as clock source
                                    // set prescaler to 128, this starts timer
  TCCR2B = (1 << CS22) | (1 << CS20);
  TIMSK2 = (1 << TOIE2);       // enable timer2 interrupt


and now that you've enabled an interrupt, you'll need an interrupt handler. here's one that turns the led at digital 13 on for 1 second, then off for 1 second.

Code: Select all
ISR (TIMER2_OVF_vect) {
  PORTB ^= (1 << PB5);           // digital 13 is portb pin 5
}


i'll post some pics if i can figure out how to set up a flicker account and i'll post my demo code that shows seconds ticking by on an lcd after i clean up the code a little. i just figured out setting up the timer this afternoon.
Last edited by mtbf0 on Fri Jan 18, 2008 9:02 am, edited 1 time in total.
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby mtbf0 » Fri Jan 18, 2008 9:01 am

here's my first timer test code. it just starts counting hours, minutes and seconds and displays them on a 2 line by 16 character lcd display, so it also includes example code for driving an lcd.

Code: Select all
/*
        Clock - timer

                requires 32.768kHz watch crystal in place of arduino resonator
                low fuse byte must be reprogrammed to 0xf2 to use mega168's
                internal oscillator
                bootloader must be replaced with lilypad version
                build for target lilypad arduino
               
                wants an lcd with an hd44780 or compatible controller
                connected as follows
               
                    RS      -  digital 2
                    R/W     -  ground
                    Enable  -  digital 3
                    data 4  -  digital 4
                    data 5  -  digital 5
                    data 6  -  digital 6
                    data 7  -  digital 7

                to control the lcd backlight by pwm on digital 10, connext
                digital 10 to the base of a small npn transistor, connect
                its collector to 5v, and emitter to pin 15 of the lcd.
                connect pin 16 of the lcd to ground,
               
                will eventually require some buttons but, for now, we'll
                talk to it over the serial port.

                will need a noise maker.

*/
#define BACKLIGHT 10
#define HEARTBEAT 13
#define LCD_RS 2
#define LCD_ENA 3
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7

#define lcdClear lcdCommand (0x01);

volatile unsigned char tick;

ISR (TIMER2_OVF_vect) {
  tick++;
  PORTB ^= (1 << PB5);
}

void lcdWrite (const unsigned char out) {
  PORTD &= 0x0f;                      // clear high nibble of portd
  PORTD |= out & 0xf0;                // output high nibble
  PORTD |= 1 << LCD_ENA;              // toggle enable
  delayMicroseconds (1);
  PORTD &= ~(1 << LCD_ENA);
  delayMicroseconds (3);              // timing determined experimentally
  PORTD &= 0x0f;                     
  PORTD |= out << 4;                  // output low nibble
  PORTD |= 1 << LCD_ENA;              // toggle enable
  delayMicroseconds (1);
  PORTD &= ~(1 << LCD_ENA);
  delayMicroseconds (35);             // timing determined experimentally
}

void lcdCommand (const unsigned char out) {
  PORTD &= ~(1 << LCD_RS);            // clear RS
  lcdWrite (out);                     // send command
}

void lcdData (const unsigned char out) {
  PORTD |= 1 << LCD_RS;              // set RS
  lcdWrite (out);                    // send character
}

unsigned char lcdMoveTo (const unsigned char line, const unsigned char pos) {
  unsigned char out;
  if ((line > 1) or (pos > 23)) return 0;
  out = 0x80;
  if (line == 1) out += 0x40;
  out += pos;
  lcdCommand (out);
  return 1;
}

void lcdPrint (const char out[]) {
  for (char i = 0; out[i]; i++) lcdData (out[i]);
}

void lcdPrintHex (const unsigned char out) {
  unsigned char temp;
  temp = out >> 4;
  temp += (temp > 9) ? 'A' - 10 : '0';
  lcdData (temp);
  temp = out & 0x0f;
  temp += (temp > 9) ? 'A' - 10 : '0';
  lcdData (temp);
}

char lcdBuffer[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
char lcdFill = '0';

void lcdPrintDec (const unsigned int out, const unsigned char precision) {
  unsigned int temp1;
  unsigned char temp2, i;
  if (precision > 16) {           // sanity check
    lcdData ('X');
    return;
  }
  temp1 = out;
  i = 15;
  do {                                // at least once
    temp2 = temp1 % 10;               // bust a digit off the low order end
    lcdBuffer[i--] = temp2 + '0';     // stick it in the buffer
    temp1 /= 10;                      // shift the whole mess to the right
  } while (temp1);                    // just so long as there's some left
  while (i >= (16 - precision)) lcdBuffer[i--] = lcdFill;
  i++;                                // went too far
  lcdPrint (&lcdBuffer[i]);
}

void setup_lcd () {
  pinMode (LCD_ENA, OUTPUT);
  pinMode (LCD_RS, OUTPUT);
  pinMode (LCD_D4, OUTPUT);
  pinMode (LCD_D5, OUTPUT);
  pinMode (LCD_D6, OUTPUT);
  pinMode (LCD_D7, OUTPUT);
  delay (15);
  PORTD &= 0x03;                        // clear PORTD except serial pins
  PORTD |= 0x30;                        // set 8 bit mode
  PORTD &= ~(1 << LCD_RS);              // set command mode, i.e. clear RS
  PORTD |= 1 << LCD_ENA;                // clock it out, i.e. toggle ENABLE
  delayMicroseconds (1);
  PORTD &= ~(1 << LCD_ENA);
  delay (5);
  PORTD |= 1 << LCD_ENA;                // clock it out, again
  delayMicroseconds (1);
  PORTD &= ~(1 << LCD_ENA);
  delay (1);
  PORTD |= 1 << LCD_ENA;                // ... and once more
  delayMicroseconds (1);
  PORTD &= ~(1 << LCD_ENA);
  delay (5);
  PORTD &= 0x0f;
  PORTD |= 0x20;                        // set four bit mode
  PORTD |= 1 << LCD_ENA;                // clock it out
  delayMicroseconds (1);
  PORTD &= ~(1 << LCD_ENA);
  delay (5);
  lcdCommand (0x28);                    // 4 bit interface, 2 lines
  delay (64);
  lcdCommand (0x08);                    // display off
  delay (20);
  lcdCommand (0x01);                    // clear display, home cursor
  delay (20);
  lcdCommand (0x06);                    // increment cursor,  no shift
  delay (20);
  lcdCommand (0x0c);                    // display on
  delay (100);
}

void setup_timer2 () {
  TCCR2A = 0;
  TCCR2B = 0;                           // stop timer
  TCNT2 = 0;                            // reset timer2 counter
  ASSR = (1 << AS2);                    // select external clock source
  TIMSK2 = (1 << TOIE2);                // enable timer2 overflow interrupt
  TCCR2B = (1 << CS22) | (1 << CS20);   // prescaler = 128, restarts timer
}

void setup () {
  pinMode (HEARTBEAT, OUTPUT);
  pinMode (BACKLIGHT, OUTPUT);
  analogWrite (BACKLIGHT, 127);
  setup_lcd ();
  setup_timer2 ();
  lcdPrint (" Clockuino v0.1");
  lcdMoveTo (1,4);
  lcdPrint (" 0:00:00");
}

unsigned char tock = 0;
unsigned char min = 0;
unsigned char hour = 0;

void loop () {
  if (tick) {
    tock += tick;
    tick = 0;
    if (tock > 59) {
      tock -= 60;
      if (++min > 60) {
        min = 0;
        if (++hour > 23) hour = 0;
        lcdFill = ' ';
        lcdMoveTo (1, 4);
        lcdPrintDec ((int)hour, 2);
        lcdData (':');
      }
      else lcdMoveTo (1,7);
      lcdFill = '0';
      lcdPrintDec ((int)min, 2);
      lcdData (':');
    }
    else lcdMoveTo (1, 10);
    lcdPrintDec ((int)tock, 2);
  }
}
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby adafruit » Fri Jan 18, 2008 1:02 pm

do you have a photo (or short video)? pretty please? :)
User avatar
adafruit
 
Posts: 10489
Joined: Thu Apr 06, 2006 3:21 pm
Location: nyc

Postby mtbf0 » Mon Jan 21, 2008 1:23 am

sorry. no tripod. toilet paper flash diffuser.

i put a stock boarduino in the shot, so you can maybe see the difference between the boards.

Image

time and date are set over the serial port.

in this picture the time has been set. once the date is set the date and day of the week are shown on the top line of the display.

i dug up a piezo buzzer today. i'm going to try to figure out how to hijack timer1 to drive it. then i need to add a button to kill the alarm.[/url]
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby mtbf0 » Wed Jan 23, 2008 1:02 am

turns out analogWrite (9, 127) puts out a nice 490Hz square wave. audible, annoying. just what i needed. let's see if it goes off at 5:00 tomorrow morning.
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby mtbf0 » Sat Jan 26, 2008 8:07 am

still proceeding.

current features...
    1) keeps and displays time.
    2) alarm only goes off on days that i work. i am always off on sunday and my other day off rotates from week to week. i set my day off for this week and the clock takes care of the rest. does not go off on federal holidays.
    3) automatic daylight saving adjustment.
    4) timer function.
    5) birthday, anniversary, whatever notifications.
    6) no buttons. ok, that's not a feature. currently has to be tethered to my laptop to set anything. not really a problem, since it's a set it and forget sort of thing anyway and having to boot up the laptop and dig out the ftdi cable to turn the alarm off is sure to get me up. pisses off the girlfriend, though. ... at 5:00 a.m.
    7) adjustable backlight.

still to do.
    1) add buttons. either 4 - alarm off, up, down, set/select - or a 4x4 matrix. i figure the matrix would greatly simplify the human interface coding. matter of fact, i could just keep what i'm using now to parse instructons from the laptop.
    2) occasional display glitches. i tuned the timing in the display routines pretty tight. apparently, too tight.
    3) see if i can integrate avr-usb so i don't need a $20 usb-ttl serial cable to talk to it. this is the reason the timer isr is so short. gotta keep that interrupt latency down. i think the arduino delay routines might cause a problem, but i only use them for display timing. might have to wire up the r/w pin on the display and poll the status bit. this would also fix the display glitches.
    4) honking huge scrolling led display. this was the distraction that kept me from completing an earlier 18f252 based version of this project. if i had a measurable attention span i wouldn't be working for the post office.
    5) change project name to houruino.
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Next

Return to Other Arduino products from Adafruit

Who is online

Users browsing this forum: No registered users and 4 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]