using a parallel LCD with Arduino Punk Console

Good day,

I'm totally new to Arduino, got interested when I saw awesome projects on the net and tried building many of them. Arduino totally rocks!
Now I want to build a new project on my Arduino Duemilanove called the Arduino Punk Console made by Dano from Beavisaudio.com but bumped onto some problems.
First off, I noticed that the LCD Beavisaudio.com is using is a serial LCD and I have bought a parallel LCD (oops!).
Because the Arduino Punk Console uses a lot of digital pins it's impossible to install the parallel LCD next with it (it uses another 16 pins)
After some research I found the answer to use my pins more efficient by trying the
LCD3Wire tutorial (http://www.arduino.cc/playground/Code/LCD3wires) with the LCD4Bit library (Arduino Playground - LCD4BitLibrary).

My LCD now reacts with text messages I put in the LCD4Bit code like this:

//some messages to display on the LCD
char msgs[6][15] = {"hello", "world", "im", "totally", "serious", "about", "this"};

Messages like this works pretty well, but when I try to use the code from Beavisaudio.com nothing will happen. I fully understand the reason why this will not work because the code from Beavisaudio.com points to the serial port (Rx pin). I think the whole code is based on that.

Now the thing is; I tried to combine the Beaviscode.com code to get it work with the LCD4Bit but it turns into one big mess!
Loads of errors wich I do not understand (fairly enough I'm not a coder) and I'm totally stuck now.

Is it possible to get the Atari Punk Console to work with a parellel LCD?
Can someone help me, or point me to the right direction?

Here's the original code from Beavisaudio.com:

/* ======================================================================
 Arduino Punk Console
 A simple programmable 8 step tone sequencer 
 by dano/beavisaudio.com
 Revs
 -----------------------------------
 15 Sept  djh  initial version
======================================================================*/
// Map all the input and output pins
#define AnalogInFrequency 1
#define AnalogInTempo 2
#define AnalogInDuration 0
#define DigitalOutSignal 11
#define DigitalInSwitch0 2
#define DigitalInSwitch1 3
#define DigitalInSwitch2 4
#define DigitalInSwitch3 5
#define DigitalInSwitch4 6
#define DigitalInSwitch5 7
#define DigitalInSwitch6 8
#define DigitalInSwitch7 9 
#define DigitalInStartStop 10
#define DigitalOutLED 12
// Set up the array for each step
int steps[] = {100,120,140,160,180,200,220,240};
// misc housekeeping
int duration = 50;
int pitchval = 1;
int fPlayMode = true;
int lastPushedStep = -1;
// Initialize the tempo
int tempo = 100;
void setup()
{ 
  // setup pin modes (Digital pins are input by default, but
  // I like to set 'em explicitly just so the code is clear.
  pinMode (DigitalInSwitch0, INPUT);
  pinMode (DigitalInSwitch1, INPUT);
  pinMode (DigitalInSwitch2, INPUT);
  pinMode (DigitalInSwitch3, INPUT);
  pinMode (DigitalInSwitch4, INPUT);
  pinMode (DigitalInSwitch5, INPUT);
  pinMode (DigitalInSwitch6, INPUT);
  pinMode (DigitalInSwitch7, INPUT);                
  pinMode (DigitalInStartStop, INPUT);
  pinMode (DigitalOutSignal, OUTPUT);  
  pinMode (DigitalOutLED, OUTPUT);
  // setup comms for the LCD display
  Serial.begin(9600);

  StartupMessage();
} 
void StartupMessage()
{
  clearLCD();
  Serial.print ("BEAVIS: Arduino");
  delay(300);
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
  Serial.print ("Punk Console!");
  delay (2000);
  clearLCD();
  Serial.print ("Beavis: APC");
}

void clearLCD()
{
  Serial.print(254, BYTE);
  Serial.print(1, BYTE);
}

void loop() 
{
  // Main sequence loop  
  for (int i=0; i<8; i++)
  {   
    // Are we playing or stopping?
    fPlayMode = digitalRead (DigitalInStartStop);
    digitalWrite (DigitalOutLED, HIGH);
    // Check the Hardware
     readSwitches();
     readPots();

    // update the display
    updateDisplay();

    // Make the noise
    if (fPlayMode)
    {
      freqout (steps[i], duration);
    }
    digitalWrite (DigitalOutLED, LOW);

    // Pause between steps
    delay (tempo);       
  }
} 

void updateDisplay()
{
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
  Serial.print ("T:");
  Serial.print (tempo);
  Serial.print (" d:");
  Serial.print (duration);
 if (lastPushedStep != -1)
 {
    Serial.print ("*");
    Serial.print (lastPushedStep);
 }
}
// Read the current values of the pots, called from the loop.
void readPots ()
{
    tempo = (analogRead (AnalogInTempo) * 1.9);
    duration = (analogRead (AnalogInDuration));      
}
// Read the current values of the switches and
// if pressed, replace the switch's slot frequency
// by reading the frequency pot.
void readSwitches()
{
  // reset last pushed button number
  lastPushedStep = -1;

  // check switch 0, if pressed, get the current freq into step 0, etc. etc.
  if (digitalRead (DigitalInSwitch0) == HIGH)
  {
    steps[0] = analogRead(AnalogInFrequency);
    lastPushedStep = 1;
  }

  else if (digitalRead (DigitalInSwitch1) == HIGH)
  {
    steps[1] = analogRead(AnalogInFrequency);
    lastPushedStep = 2;
  }

  else if (digitalRead (DigitalInSwitch2) == HIGH)
  {
    steps[2] = analogRead(AnalogInFrequency);
    lastPushedStep = 3;
  }
  else if (digitalRead (DigitalInSwitch3) == HIGH)
  {
    steps[3] = analogRead(AnalogInFrequency);
    lastPushedStep = 4;
  }
  else if (digitalRead (DigitalInSwitch4) == HIGH)
  {
    steps[4] = analogRead(AnalogInFrequency);
    lastPushedStep = 5;
  }
  else if (digitalRead (DigitalInSwitch5) == HIGH)
  {
    steps[5] = analogRead(AnalogInFrequency);
    lastPushedStep = 6;
  }
  else if (digitalRead (DigitalInSwitch6) == HIGH)
  {
    steps[6] = analogRead(AnalogInFrequency);
    lastPushedStep = 7;
  }
  else if (digitalRead (DigitalInSwitch7) == HIGH)
  { 
    steps[7] = analogRead(AnalogInFrequency);
    lastPushedStep = 8;
  }
}


//freqout code by Paul Badger 
// freq - frequency value
// t - time duration of tone
void freqout(int freq, int t) 
{ 
  int hperiod;     //calculate 1/2 period in us 
  long cycles, i; 

  // subtract 7 us to make up for digitalWrite overhead - determined empirically 
  hperiod = (500000 / ((freq - 7) * pitchval));             

  // calculate cycles 
  cycles = ((long)freq * (long)t) / 1000;    // calculate cycles 
  for (i=0; i<= cycles; i++)
  {              // play note for t ms  
    digitalWrite(DigitalOutSignal, HIGH);  
    delayMicroseconds(hperiod); 
    digitalWrite(DigitalOutSignal, LOW);  
    delayMicroseconds(hperiod - 1);     // - 1 to make up for fractional microsecond in digitaWrite overhead 
  } 
}

And a simple code from the LCD4Bit that works pretty well with my shiftregister 3-wire LCD:

// Example use of LCD3Wire library
// Almost a carbon-copy of LCD4BitExample.pde

#include <LCD3Wire.h> 

// Arduino pins
#define LCD_LINES 1  // number of lines in your display
#define DOUT_PIN  15  // Dout pin
#define STR_PIN   16  // Strobe pin
#define CLK_PIN   14  // Clock pin

#define LED_PIN   13 // we'll use the debug LED to output a heartbeat

//create object to control an LCD.  
LCD3Wire lcd = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN); 

//some messages to display on the LCD
char msgs[6][15] = {"apple", "banana", "pineapple", "mango", "watermelon", "pear"};
int NUM_MSGS = 6;

void setup() { 
  lcd.init();
  
  //optionally, now set up our application-specific display settings, overriding whatever the lcd did in lcd.init()
  //lcd.commandWrite(0x0F);//cursor on, display on, blink on.  (nasty!)
  
  pinMode(LED_PIN, OUTPUT);  
}

void loop() {  
  digitalWrite(LED_PIN, HIGH);  //light the debug LED

  //pick a random message from the array
  int pick = random(NUM_MSGS);
  char* msg = msgs[pick];
  
  lcd.clear();
  lcd.printIn(msg);
  delay(1000);
  digitalWrite(LED_PIN, LOW);
  
  //print some dots individually
  for (int i=0; i<3; i++){
    lcd.print('.');
    delay(100);
  }
  //print something on the display's second line. 
  if(LCD_LINES>1){
    lcd.cursorTo(2, 0);  //line=2, x=0.
    lcd.printIn("Score: 6/7");
    delay(1000);
  }
  
  //scroll entire display 20 chars to left, delaying 50ms each inc
  lcd.leftScroll(20, 50);
}

attrib:
Is it possible to get the Atari Punk Console to work with a parellel LCD?
Can someone help me, or point me to the right direction?

The code you nabbed on the internet is quite modular and clean. To make it work with you LCD display, you need to rewrite the following functions:

void StartupMessage()
void clearLCD()
void updateDisplay()

Also, in setup() you can delete the line

Serial.begin(9600);

but you need add the necessary initialisation code for your display instead.

Once you did that, all should work. If you're unsure what exactly to do, start with adapting the function StartupMessage() with the code you have that works on your display.

Good luck,

Korman

thank you for your reply Korman!

however, now I get tons of errors and I have no clue what it means. maybe you can clearify what went wrong.
I changed the Beavisaudio code (the one I want to work with) and now it's like this:

/* ======================================================================
 Arduino Punk Console
 A simple programmable 8 step tone sequencer 
 by dano/beavisaudio.com

 Revs
 -----------------------------------
 15 Sept  djh  initial version
======================================================================*/
#include <LCD3Wire.h> 

// Map all the input and output pins
#define AnalogInFrequency 1
#define AnalogInTempo 2
#define AnalogInDuration 0
#define DigitalOutSignal 11
#define DigitalInSwitch0 2
#define DigitalInSwitch1 3
#define DigitalInSwitch2 4
#define DigitalInSwitch3 5
#define DigitalInSwitch4 6
#define DigitalInSwitch5 7
#define DigitalInSwitch6 8
#define DigitalInSwitch7 9 
#define DigitalInStartStop 10
#define DigitalOutLED 12
#define LCD_LINES 1  // number of lines in your display
#define DOUT_PIN  15  // Dout pin
#define STR_PIN   16  // Strobe pin
#define CLK_PIN   14  // Clock pin

#define LED_PIN   13 // we'll use the debug LED to output a heartbeat

LCD3Wire lcd = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN); 

// Set up the array for each step
int steps[] = {100,120,140,160,180,200,220,240};

// misc housekeeping
int duration = 50;
int pitchval = 1;
int fPlayMode = true;
int lastPushedStep = -1;

// Initialize the tempo
int tempo = 100;

void setup()
{ 
  // setup pin modes (Digital pins are input by default, but
  // I like to set 'em explicitly just so the code is clear.
  pinMode (DigitalInSwitch0, INPUT);
  pinMode (DigitalInSwitch1, INPUT);
  pinMode (DigitalInSwitch2, INPUT);
  pinMode (DigitalInSwitch3, INPUT);
  pinMode (DigitalInSwitch4, INPUT);
  pinMode (DigitalInSwitch5, INPUT);
  pinMode (DigitalInSwitch6, INPUT);
  pinMode (DigitalInSwitch7, INPUT);                
  pinMode (DigitalInStartStop, INPUT);
  pinMode (DigitalOutSignal, OUTPUT);  
  pinMode (DigitalOutLED, OUTPUT);
  pinMode(LED_PIN, OUTPUT); 
  // setup comms for the LCD display
  lcd.init();

  StartupMessage();

}

void StartupMessage()
{
  clearLCD();
  lcd.print ("BEAVIS: Arduino");
  delay(300);
  lcd.print (254, BYTE);
  lcd.print (192, BYTE);
  lcd.print ("Punk Console!");
  delay (2000);
  clearLCD();
  lcd.print ("Beavis: APC");
}

void clearLCD()
{
  lcd.print(254, BYTE);
  lcd.print(1, BYTE);
}

void loop() 
{
  //  digitalWrite(LED_PIN, HIGH);  //light the debug LED

  // Main sequence loop  
  for (int i=0; i<8; i++)
  {   
    // Are we playing or stopping?
    fPlayMode = digitalRead (DigitalInStartStop);
    digitalWrite (DigitalOutLED, HIGH);

    // Check the Hardware
     readSwitches();
     readPots();

    // update the display
    updateDisplay();

    // Make the noise
    if (fPlayMode)
    {
      freqout (steps[i], duration);
    }
    digitalWrite (DigitalOutLED, LOW);

    // Pause between steps
    delay (tempo);       
  }
} 


void updateDisplay()
{
  lcd.print (254, BYTE);
  lcd.print (192, BYTE);
  lcd.print ("T:");
  lcd.print (tempo);
  lcd.print (" d:");
  lcd.print (duration);

 if (lastPushedStep != -1)
 {
    lcd.print ("*");
    lcd.print (lastPushedStep);
 }
}

// Read the current values of the pots, called from the loop.
void readPots ()
{
    tempo = (analogRead (AnalogInTempo) * 1.9);
    duration = (analogRead (AnalogInDuration));      
}

// Read the current values of the switches and
// if pressed, replace the switch's slot frequency
// by reading the frequency pot.
void readSwitches()
{
  // reset last pushed button number
  lastPushedStep = -1;

  // check switch 0, if pressed, get the current freq into step 0, etc. etc.
  if (digitalRead (DigitalInSwitch0) == HIGH)
  {
    steps[0] = analogRead(AnalogInFrequency);
    lastPushedStep = 1;
  }

  else if (digitalRead (DigitalInSwitch1) == HIGH)
  {
    steps[1] = analogRead(AnalogInFrequency);
    lastPushedStep = 2;
  }

  else if (digitalRead (DigitalInSwitch2) == HIGH)
  {
    steps[2] = analogRead(AnalogInFrequency);
    lastPushedStep = 3;
  }
  else if (digitalRead (DigitalInSwitch3) == HIGH)
  {
    steps[3] = analogRead(AnalogInFrequency);
    lastPushedStep = 4;
  }
  else if (digitalRead (DigitalInSwitch4) == HIGH)
  {
    steps[4] = analogRead(AnalogInFrequency);
    lastPushedStep = 5;
  }
  else if (digitalRead (DigitalInSwitch5) == HIGH)
  {
    steps[5] = analogRead(AnalogInFrequency);
    lastPushedStep = 6;
  }
  else if (digitalRead (DigitalInSwitch6) == HIGH)
  {
    steps[6] = analogRead(AnalogInFrequency);
    lastPushedStep = 7;
  }
  else if (digitalRead (DigitalInSwitch7) == HIGH)
  { 
    steps[7] = analogRead(AnalogInFrequency);
    lastPushedStep = 8;
  }
}


//freqout code by Paul Badger 
// freq - frequency value
// t - time duration of tone
void freqout(int freq, int t) 
{ 
  int hperiod;     //calculate 1/2 period in us 
  long cycles, i; 

  // subtract 7 us to make up for digitalWrite overhead - determined empirically 
  hperiod = (500000 / ((freq - 7) * pitchval));             

  // calculate cycles 
  cycles = ((long)freq * (long)t) / 1000;    // calculate cycles 

  for (i=0; i<= cycles; i++)
  {              // play note for t ms  
    digitalWrite(DigitalOutSignal, HIGH);  
    delayMicroseconds(hperiod); 
    digitalWrite(DigitalOutSignal, LOW);  
    delayMicroseconds(hperiod - 1);     // - 1 to make up for fractional microsecond in digitaWrite overhead 
  } 
  //print something on the display's second line. 
  if(LCD_LINES>1){
    lcd.cursorTo(2, 0);  //line=2, x=0.
    lcd.printIn("A Banana");
    delay(1000);
  }
}

and this is the error message what I've got when verifying:

BeavisPunkConsole.cpp: In function 'void StartupMessage()':
BeavisPunkConsole:73: error: invalid conversion from 'const char*' to 'int'
BeavisPunkConsole:73: error: initializing argument 1 of 'void LCD3Wire::print(int)'
BeavisPunkConsole:75: error: no matching function for call to 'LCD3Wire::print(int, int)'
/Users/Cesar/Documents/Arduino/libraries/LCD3Wire/LCD3Wire.h:11: note: candidates are: void LCD3Wire::print(int)
BeavisPunkConsole:76: error: no matching function for call to 'LCD3Wire::print(int, int)'
/Users/Cesar/Documents/Arduino/libraries/LCD3Wire/LCD3Wire.h:11: note: candidates are: void LCD3Wire::print(int)
BeavisPunkConsole:77: error: invalid conversion from 'const char*' to 'int'
BeavisPunkConsole:77: error: initializing argument 1 of 'void LCD3Wire::print(int)'
BeavisPunkConsole:80: error: invalid conversion from 'const char*' to 'int'
BeavisPunkConsole:80: error: initializing argument 1 of 'void LCD3Wire::print(int)'
BeavisPunkConsole.cpp: In function 'void clearLCD()':
BeavisPunkConsole:85: error: no matching function for call to 'LCD3Wire::print(int, int)'
/Users/Cesar/Documents/Arduino/libraries/LCD3Wire/LCD3Wire.h:11: note: candidates are: void LCD3Wire::print(int)
BeavisPunkConsole:86: error: no matching function for call to 'LCD3Wire::print(int, int)'
/Users/Cesar/Documents/Arduino/libraries/LCD3Wire/LCD3Wire.h:11: note: candidates are: void LCD3Wire::print(int)
BeavisPunkConsole.cpp: In function 'void updateDisplay()':
BeavisPunkConsole:122: error: no matching function for call to 'LCD3Wire::print(int, int)'
/Users/Cesar/Documents/Arduino/libraries/LCD3Wire/LCD3Wire.h:11: note: candidates are: void LCD3Wire::print(int)
BeavisPunkConsole:123: error: no matching function for call to 'LCD3Wire::print(int, int)'
/Users/Cesar/Documents/Arduino/libraries/LCD3Wire/LCD3Wire.h:11: note: candidates are: void LCD3Wire::print(int)
BeavisPunkConsole:124: error: invalid conversion from 'const char*' to 'int'
BeavisPunkConsole:124: error: initializing argument 1 of 'void LCD3Wire::print(int)'
BeavisPunkConsole:126: error: invalid conversion from 'const char*' to 'int'
BeavisPunkConsole:126: error: initializing argument 1 of 'void LCD3Wire::print(int)'
BeavisPunkConsole:131: error: invalid conversion from 'const char*' to 'int'
BeavisPunkConsole:131: error: initializing argument 1 of 'void LCD3Wire::print(int)'

what i'm trying to understand from this, is that it has problems with number formatting?
the code on the LCD3Wire website (Arduino Playground - LCD3wires) below seems to be working with numbers but I have no idea how to convert that code into mine because that code seems to be totally different.

by the way, in my first post I pasted the wrong code for what seemed to work for my LCD but it wasn't. this is the correct code (I corrected this in my first post, to avoid confusion):

// Example use of LCD3Wire library
// Almost a carbon-copy of LCD4BitExample.pde

#include <LCD3Wire.h> 

// Arduino pins
#define LCD_LINES 1  // number of lines in your display
#define DOUT_PIN  15  // Dout pin
#define STR_PIN   16  // Strobe pin
#define CLK_PIN   14  // Clock pin

#define LED_PIN   13 // we'll use the debug LED to output a heartbeat

//create object to control an LCD.  
LCD3Wire lcd = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN); 

//some messages to display on the LCD
char msgs[6][15] = {"apple", "banana", "pineapple", "mango", "watermelon", "pear"};
int NUM_MSGS = 6;

void setup() { 
  lcd.init();
  
  //optionally, now set up our application-specific display settings, overriding whatever the lcd did in lcd.init()
  //lcd.commandWrite(0x0F);//cursor on, display on, blink on.  (nasty!)
  
  pinMode(LED_PIN, OUTPUT);  
}

void loop() {  
  digitalWrite(LED_PIN, HIGH);  //light the debug LED

  //pick a random message from the array
  int pick = random(NUM_MSGS);
  char* msg = msgs[pick];
  
  lcd.clear();
  lcd.printIn(msg);
  delay(1000);
  digitalWrite(LED_PIN, LOW);
  
  //print some dots individually
  for (int i=0; i<3; i++){
    lcd.print('.');
    delay(100);
  }
  //print something on the display's second line. 
  if(LCD_LINES>1){
    lcd.cursorTo(2, 0);  //line=2, x=0.
    lcd.printIn("Score: 6/7");
    delay(1000);
  }
  
  //scroll entire display 20 chars to left, delaying 50ms each inc
  lcd.leftScroll(20, 50);
}

The problem lies in you not reading the documentation of the the libraries you're using and the libraries doing surprising things for seemingly harmless requests. In the case here, the function print() LCD3Wire library doesn't print strings, it just prints numbers. To print strings, you need to replace lcd.print() with lcd.printIn() and also add some cursor positioning to the right location first with lcd.cursorTo(). In the same vein, to print numbers, you can't use the function print with two parameters where you tell it how to display the number, you can only choose to between printing a number and printIn for strings.

If you were more experienced, I would have suggested to get rid of the LCD3Wire, which is of rather poor quality, and make a new one based on the LiquidCrystal library, which behaves as expected, but that's beyond your scope at this point. So you'll probably have to work with the two available functions as well as possible.

Korman