I started playing with my Orangutan today. As it shipped, both lines of the LCD worked, all switches, the whole works. So I tried out some LCD code I got off of Jim Remington’s site. Initially it worked somewhat (line 2 never came on), but eventually I managed to make it so the LCD won’t talk at all.
As a test I tried to get something similar to what my Orangutan came with. This is pulled off the forum from an earlier post:
#define F_CPU 20000000
#include <avr/io.h>
#include <util/delay.h>
//#include "serial.h"
/*
** Programming
** Buzzer
** Reset
** Power Switch
** Power LED
Trimmer Pot
** LED
I/O pins
** Motors
Push buttons
** LCD
*/
/*
** Delays
*/
#define Delay( x ) _delay_loop_2( x )
void Big_Delay( void )
{
Delay( 60000 );
Delay( 60000 );
Delay( 60000 );
Delay( 60000 );
}
/*
**
*/
void Speaker( void )
{
DDRB = 1;
DDRD = 2;
while ( 1 ) {
PORTD = 0;
if ( PINB & _BV(3) ) {
PORTD = 2;
PORTB = PORTB ^ 1;
Delay( 50 );
}
/* if ( PINB & _BV(4) ) {
PORTB = PORTB ^ 1;
Delay( 100 );
}*/
if ( PINB & _BV(5) ) {
PORTB = PORTB ^ 1;
Delay( 200 );
}
}
}
void Motors( void )
{
DDRB = _BV(1) | _BV(2);
DDRD = _BV(5) | _BV(6);
while ( 1 ) {
PORTB |= _BV(1);
PORTD &= ~_BV(5);
Big_Delay();
PORTB |= _BV(2);
PORTD &= ~_BV(6);
Big_Delay();
PORTB &= ~_BV(1);
PORTD |= _BV(5);
Big_Delay();
PORTB &= ~_BV(2);
PORTD |= _BV(6);
Big_Delay();
}
}
/*
** LCD
*/
#define LCD_COMMAND_CLEAR 0x01
#define LCD_COMMAND_LINE1 0x02
#define LCD_COMMAND_LINE2 0xC0
#define LCDDelay _delay_loop_2
void LCDSendNibble( unsigned char data )
{
data &= 0x0F;
data <<= 3;
PORTB &= ~0x38;
PORTB |= (data & 0x38);
data <<= 1;
PORTD &= ~0x80;
PORTD |= (data & 0x80);
PORTD |= _BV(4); // LCD_STROBE = 1;
_delay_loop_1( 200 );
PORTD &= ~_BV(4); // LCD_STROBE = 0;
_delay_loop_1( 200 );
}
void LCDData( unsigned char data )
{
PORTD |= _BV(2); // LCD_RS = 1;
LCDSendNibble( data >> 4 );
LCDSendNibble( data );
}
void LCDString( const unsigned char *str )
{
while (*str != 0) {
LCDData( *str++ );
}
}
void LCDCommand( unsigned char data )
{
PORTD &= ~_BV(2); // LCD_RS = 0;
LCDSendNibble( data >> 4 );
LCDSendNibble( data );
LCDDelay( 100 );
}
void LCDHexNibble( unsigned char data )
{
data &= 0x0F;
if ( data > 9 ) {
data += ('A' - '9' - 1);
}
LCDData( data + '0' );
}
void LCDHex( unsigned char data )
{
LCDHexNibble( data >> 4 );
LCDHexNibble( data );
}
void LCDInit( void )
{
DDRB |= _BV( 3 ) | _BV( 4 ) | _BV( 5 );
DDRD |= _BV( 7 ) | _BV( 4 ) | _BV( 3 ) | _BV( 2 );
PORTD &= ~_BV(4); // LCD_STROBE = 0;
PORTD &= ~_BV(3); // r/w = 0
LCDDelay( 200 );
LCDCommand( 0x32 );
LCDCommand( 0x20 );
LCDCommand( 0x1C );
LCDCommand( LCD_COMMAND_CLEAR );
LCDCommand( 0x28 );
LCDCommand( 0x06 );
LCDCommand( 0x0C );
}
/*
**
*/
int main(void)
{
// Serial_Init();
LCDInit();
LCDString( "Orangutan" );
DDRB = 0;
DDRD |= _BV(1);
PORTB = 0;
//PORTB &= ~_BV(5);
/* while (1) {
if (PINB & _BV(5)){
PORTD &= ~_BV(1); // LCD_STROBE = 0;
//Delay( 20000 );
} else {
PORTD |= _BV(1); // LCD_STROBE = 1;
//Delay( 20000 );
}
}
*/
// ADCSR |= (1 << ADPS2);
// ADCSR |= (1 << ADFR);
// ADMUX = 7;
// ADCSR |= (1 << ADEN);
// ADCSR |= (1 << ADSC);
LCDInit();
LCDString( "Orangutan" );
while ( 1 ) {
static int i = 0;
LCDCommand( LCD_COMMAND_LINE2 );
i++;
LCDHex( ADC >>8 );
LCDHex( ADC );
if (PINB & _BV(5)){
PORTD &= ~_BV(1); // LCD_STROBE = 0;
//Delay( 20000 );
} else {
PORTD |= _BV(1); // LCD_STROBE = 1;
//Delay( 20000 );
}
}
// Motors();
return 0;
}
I think it was for an earlier version of WinAVR because a couple of tweaks were required in order to get it to compile with no warnings:
1 - BV() -> _BV()
2 - #include <avr/delay.h> -> #include <util/delay.h>
3 - Add the F_CPU #define
It’s enough to make me not trust it as a sanity check (I’ve had delay.h stuff come back and bite me on the Baby-O, even with F_CPU set.) Since the LCD relies on the delay.h stuff, and since that’s what I’m having trouble with, this is my first suspect.
Any chance you could post the code that’s initially loaded on the Orangutan these days? I wouldn’t mind getting back to a known setup so I can make sure I didn’t damage anything. (It’s tough to debug software when you’re not sure if you just broke the hardware.)
Thanks,
Tom
P.S. From what I can tell everything else is working great. Switches, LED, buzzer, all good. Just not the LCD.