ECE 110/Equipment/Serial LCD

From PrattWiki
Jump to navigation Jump to search

Introduction

There are several multi-character LCD displays available. For ECE 110, we will specifically be using a 16x2 display that has a Parallax Serial LCD module attached to it. Among other things, this makes the display a three-pin device versus a 16-pin device! It also allows for brightness control and sound on board.


Leads

  • 1 (left): RX (receive)
  • 2 (middle): 5 V
  • 3 (right): Ground

The CX-Bot has a header for the three-pin serial version; the RX pin is connected to Serial3 Rx (pin 15).

Operation

The serial version of the LCD receives characters through a serial bus; for the CX-Bot, these are linked to Serial3 which has pin 14 as its Tx line and pin 15 as its Rx line. The header will allow you to connect Serial3's transmit line to the LCD's receive line. You will create a connection to the display using the SoftwareSerial library, which provides an object type of the same name:

#include <SoftwareSerial.h>

#define TxPin 14

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

You can then use mySerial.write(VAL) to send a single raw byte to the display or mySerial.print(STRING) to send a collection of characters. The codes are given on pp. 8-13 of Product Guide; here are some of the more used ones (codes given in decimal):

  • 12: clear the display and move cursor to top left (line 0 position 0). There needs to be at least a 5 ms delay after this.
  • 22-25: turn the display on set the cursor (line or not under current location) and blink (blink or not at current location):
    • 22 cursor off, blink off
    • 23 cursor off, blink on
    • 24 cursor on, blink off (default)
    • 25 cursor on, blink on
  • 17, 18: turn the backlight on, off
  • 128-143: move cursor directly to line 0 positions 0-15
  • 148-163: move cursor directly to line 1 positions 0-15

Music

The Parallax Serial LCD also has a piezoelectric speaker you can use. If you want to play a note, you basically need to send three codes: duration, octave, and note within octave.

  • 208-214: duration from 1/64th to a whole note. Whole notes are 2 seconds long
  • 215-219: octave; 215 starts at middle A (440 Hz), each octave doubles the frequency after that. Note - in music, typically an octave starts with C; C4 or "middle C" (262 Hz) is just above B3 and just below Dflat4. For this device, however, the scales start at A, meaning "middle A" (440 Hz) is scale 4 note A and middle C, which is a few steps below middle A, is scale 3 note C. The bottom of p. 7 of the PDF guide shows the table of frequencies.
  • 220-231: note; 220 is A, 221 is A#, etc.
  • 232: no note; play silence for the duration specified.

Sample Code

Simple

The following example will use the Serial Monitor to receive input from the user; the input will be displayed on the LCD starting with the first character on the top left row (line 0, position 0). If the input has more than 16 characters, the input will wrap to the second line. If the input has more than 32 characters, the 33rd will overwrite the 1st and any more will overwrite other ones that were there before. The LCD starts at the first character every time due to the

mySerial.write(12);

line.

#include <SoftwareSerial.h>

#define TxPin 14

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  delay(100);
  mySerial.write(12); // clear
  delay(10);
  mySerial.write(22); // no cursor no blink
  delay(10);
  mySerial.write(17); // backlight
  delay(10);
}

void loop() {
  if (Serial.available() > 0){
    mySerial.write(12); delay(5);
    String myInput = Serial.readString();
    myInput.trim();
    mySerial.print(myInput);
  }  
}

Turn Off

When you are done using the display for the day, you should turn it off before disconnecting it. Here is some code that will do that:

#include <SoftwareSerial.h>

#define TxPin 14

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

void setup() {
  mySerial.begin(9600);
  delay(100);
  mySerial.write(12); // clear
  delay(10);
  mySerial.write(21); // display off
  delay(10);
  mySerial.write(18); // backlight off
  delay(10);
}

void loop() {
}

Music and Text

Here is code that uses both lines of the display and plays a short song; the delay is to make sure a note has finished playing before sending the next note over serial - without this, the memory buffer for the LCD may fill up and miss signals that come later. The only hardware you need is the Parallax LCD connected to the LCD Serial 3 header on the CX-Bot.

#include <SoftwareSerial.h>

#define TxPin 14

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

#define num 9

int durs[num]  = {211, 212, 212, 211, 212, 
                212, 212, 212, 212
};
int octs[num]  = {216, 216, 216, 216, 216, 
                216, 216, 215, 216
};
int notes[num] = {227, 227, 227, 223, 227,
                230, 232, 230, 232
};

void setup() {
  mySerial.begin(9600);
  delay(100);
  mySerial.write(12); // clear
  delay(10);
  mySerial.write(22); // no cursor no blink
  delay(10);
  mySerial.write(17); // backlight
  delay(10);
  mySerial.print("Super Mario");
  mySerial.write(13);
  mySerial.print("Brothers!");
  for(long k=0; k<num; k++){
    
    mySerial.write(durs[k]); mySerial.write(octs[k]); mySerial.write(notes[k]);
    int len = 214 - durs[k];
    float del = 2000 / pow(2, len);
    delay(int(del*1.1));
  }

}

void loop() {

}


Music and Text with Functions

This is effectively the same code as above, only the musical part is in a function.

#include <SoftwareSerial.h>

#define TxPin 14

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

#define num 9

int durs[num]  = {211, 212, 212, 211, 212, 
                212, 212, 212, 212
};
int octs[num]  = {216, 216, 216, 216, 216, 
                216, 216, 215, 216
};
int notes[num] = {227, 227, 227, 223, 227,
                230, 232, 230, 232
};

void setup() {
  mySerial.begin(9600);
  delay(100);
  mySerial.write(12); // clear
  delay(10);
  mySerial.write(22); // no cursor no blink
  delay(10);
  mySerial.write(17); // backlight
  delay(10);
  mySerial.print("Super Mario");
  mySerial.write(13);
  mySerial.print("Brothers!");
  play_song();

}

void loop() {

}

void play_song() {
 for(long k=0; k<num; k++){
    
    mySerial.write(durs[k]); mySerial.write(octs[k]); mySerial.write(notes[k]);
    int len = 214 - durs[k];
    float del = 2000 / pow(2, len);
    delay(int(del*1.1));
  }
}

Formatted Text and Music

Here is a code that shows how to use buffers and sprintf to create formatted text and how to play music. Note - this gets very annoying very fast, so be sure to have the BareMinimum script prepared for loading...

#include <SoftwareSerial.h>

#define TxPin 14

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  delay(100);
  mySerial.write(12); // clear
  delay(10);
  mySerial.write(22); // no cursor no blink
  delay(10);
  mySerial.write(17); // backlight
  delay(10);
}

void loop() {
  int x = random(0, 10);
  int y = random(0, 10);
  char buffer[16];
  sprintf(buffer, "%d + %d = %2d", x, y, x+y);
  mySerial.write(12); // clear
  delay(10);
  mySerial.write(buffer);
  mySerial.write(13); // cr
  int note = (x+y)%12; // get a number between 0 and 11
  note = note + 220; // map [0-11] to [220-231] for note
  sprintf(buffer, "%d * %d %% 12 = %2d", x, y, (x+y) % 12);
  mySerial.write(buffer);
  mySerial.write(211); mySerial.write(216); mySerial.write(note);
  delay(500);
}

Notes

References