Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
LCD proof of concept for johnny-five
// Wire up LCD as described here:
// http://learn.adafruit.com/character-lcds/overview
var five = require("johnny-five"),
board, lcd;
board = new five.Board();
board.on("ready", function() {
lcd = {
rsPin: 7, // LCD pin 4
// rwPin:, // LCD pin 5, only needed when reading from display
enPin: 8, // LCD pin 6
dataPins: [12, 11, 10, 9] // D7 to D4. LCD pins 14, 13, 12, 11
};
var sleep = function(milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
};
var highLowFromBinary = function(number) {
return number === 1 ? board.firmata.HIGH : board.firmata.LOW;
};
var sendCommand = function(command) {
board.digitalWrite(lcd.dataPins[0], highLowFromBinary(command[0]));
board.digitalWrite(lcd.dataPins[1], highLowFromBinary(command[1]));
board.digitalWrite(lcd.dataPins[2], highLowFromBinary(command[2]));
board.digitalWrite(lcd.dataPins[3], highLowFromBinary(command[3]));
// Pulse the EN pin to send first nibble
board.digitalWrite(lcd.enPin, board.firmata.HIGH);
board.digitalWrite(lcd.enPin, board.firmata.LOW);
board.digitalWrite(lcd.dataPins[0], highLowFromBinary(command[4]));
board.digitalWrite(lcd.dataPins[1], highLowFromBinary(command[5]));
board.digitalWrite(lcd.dataPins[2], highLowFromBinary(command[6]));
board.digitalWrite(lcd.dataPins[3], highLowFromBinary(command[7]));
// Pulse the EN pin to send second nibble
board.digitalWrite(lcd.enPin, board.firmata.HIGH);
board.digitalWrite(lcd.enPin, board.firmata.LOW);
};
var writeMessage = function() {
board.digitalWrite(lcd.rsPin, board.firmata.LOW);
sendCommand([0,0,0,0,0,0,0,1]);
board.digitalWrite(lcd.rsPin, board.firmata.HIGH);
sendCommand([0,1,0,0,1,0,1,0]);
sleep(200);
sendCommand([0,1,1,0,1,1,1,1]);
sleep(200);
sendCommand([0,1,1,0,1,0,0,0]);
sleep(200);
sendCommand([0,1,1,0,1,1,1,0]);
sleep(200);
sendCommand([0,1,1,0,1,1,1,0]);
sleep(200);
sendCommand([0,1,1,1,1,0,0,1]);
sleep(200);
sendCommand([0,0,1,0,1,1,0,1]);
sleep(200);
sendCommand([0,1,1,0,0,1,1,0]);
sleep(200);
sendCommand([0,1,1,0,1,0,0,1]);
sleep(200);
sendCommand([0,1,1,1,0,1,1,0]);
sleep(200);
sendCommand([0,1,1,0,0,1,0,1]);
board.digitalWrite(lcd.rsPin, board.firmata.LOW);
};
// RS to low (for command mode), EN to low to start
board.digitalWrite(lcd.rsPin, board.firmata.LOW);
board.digitalWrite(lcd.enPin, board.firmata.LOW);
// Switch to 4-bit mode
board.digitalWrite(lcd.dataPins[0], board.firmata.LOW);
board.digitalWrite(lcd.dataPins[1], board.firmata.LOW);
board.digitalWrite(lcd.dataPins[2], board.firmata.HIGH);
board.digitalWrite(lcd.dataPins[3], board.firmata.LOW);
board.digitalWrite(lcd.enPin, board.firmata.HIGH);
board.digitalWrite(lcd.enPin, board.firmata.LOW);
// Set to two-line mode
sendCommand([0,0,1,0,1,0,0,0]);
// Clear display and turn it on
sendCommand([0,0,0,0,0,0,0,1]);
sendCommand([0,0,0,0,1,1,1,1]);
// Write some text
writeMessage();
});
@haugstrup

This comment has been minimized.

Copy link
Owner Author

@haugstrup haugstrup commented Jul 29, 2012

johnny-five: https://github.com/rwldrn/johnny-five

Video: https://vimeo.com/46577266

Next steps:

  • Figure out how to properly clear the display
  • Make a nice little LCD package for johnny-five so no-one have to learn these commands, ever
@rwaldron

This comment has been minimized.

Copy link

@rwaldron rwaldron commented Jul 29, 2012

Wow, this looks exciting - I'll take it for a spin this evening. As for API wrapper stuff... you might consider using the LiquidCrystal API as a starting point http://arduino.cc/en/Reference/LiquidCrystal/

:)

@rmurphey

This comment has been minimized.

Copy link

@rmurphey rmurphey commented Jul 29, 2012

Super excited to see this -- was just talking to @rwldrn the other day about LCD stuff with johnny-five. I might have to buy that LCD after all :) Which LCD is this?

@rwaldron

This comment has been minimized.

Copy link

@rwaldron rwaldron commented Jul 29, 2012

I've been trying to figure that out based on the video — I have two LCD's one requires Software Serial to work and the other is I2C

@rmurphey

This comment has been minimized.

Copy link

@rmurphey rmurphey commented Jul 29, 2012

I couldn't tell from my reading whether software serial was something that could be "faked" with enough code ... it seemed that the way it worked wasn't dissimilar to the way I sent messages to a shift register. I wonder if that's what's happening here? Hopefully @haugstrup will shed some light :)

@haugstrup

This comment has been minimized.

Copy link
Owner Author

@haugstrup haugstrup commented Jul 30, 2012

I knew I shouldn't have dumped this right before leaving for the day!

I know next to nothing about arduino/microcontrollers and electronic parts. This may all be total n00b information, but I had to start from scratch. :)

The LCD I'm using is a part of the Arduino starter kit that Rick told me to buy: http://www.makershed.com/Ultimate_Microcontroller_Pack_p/msump.htm

But that's not that important. What's important is that the driver is one of these guys: http://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller -- as far as I can tell most cheap 'character' LCDs use this driver. There are 16 pins (14 if the LCD doesn't have a backlight). A software serial lcd looks like it would be easier to interface with, but they's also twice as expensive...

So far so good. I thought I had to convert my cheap LCD to one that runs on the I2C bus. That would include wiring up one of these http://www.makershed.com/Positive_RGB_LCD_Shield_Kit_w_16x2_Character_Disp_p/mkad44.htm but I didn't have the parts and I live in downtown San Francisco so I have to mail order everything. And it would be rather silly to have to require that much wiring to control an lcd with javascript...

Fortunately these two PDFs explain in very simple terms how the LCD driver works:

Compared to the specs us webdevs usually have to deal with this is refreshingly simple. You set the data pins to high/low to match the command you want to send and then pulse the EN pin to high to actually send the command. The RS pin goes to LOW when sending commands and to HIGH when writing characters to the screen.

I'm still having trouble clearing the display so I have to power off the arduino before I can run the script again.

I had seen the Liquid Crystal arduino api, this would be a javascript implementation of the same thing so it'll make a ton of sense to use a similar format. Do either of you know where I can find the source code for that library? I tried searching but no luck...

I'll see if I can't wrap this up nicely really soon. It's very exciting to toy with :)

@haugstrup

This comment has been minimized.

Copy link
Owner Author

@haugstrup haugstrup commented Jul 30, 2012

Oh, and the big advantage of the I2C solution is that you can get away with only using 2 pins on the arduino. The straight connection I'm using requires 6 digital pins. But again: So much extra soldering with I2C...

@rmurphey

This comment has been minimized.

Copy link

@rmurphey rmurphey commented Jul 30, 2012

I think this is the LiquidCrystal API source: https://github.com/arduino/Arduino/tree/master/libraries/LiquidCrystal. Thanks so much for the writeup! This is hugely helpful and I'll be adding an LCD to my next order :)

@rwaldron

This comment has been minimized.

Copy link

@rwaldron rwaldron commented Jul 30, 2012

This is brilliant — I must have this LCD somewhere as well...

Also, I wrote a little function for converting chars to their full binary sequence.

@haugstrup

This comment has been minimized.

Copy link
Owner Author

@haugstrup haugstrup commented Jul 30, 2012

@rmurphy, Thanks for the link, I'm certain it will come in handy even though I don't speak C at all. You should definitely add an lcd to your next order. If you look in the PDFs you will see that you can create your own 5x8 pixel graphics to use as characters. I want to make bar charts/sparklines and whatnot (or an equalizer?)

@rwaldron, Can I see your function? I don't wan't to write any code I don't have to. :)

@rmurphey

This comment has been minimized.

Copy link

@rmurphey rmurphey commented Jul 30, 2012

@haugstrup I opened an issue on johnny-five related to this, maybe we can move the implementation discussion there for easier collaboration?

@haugstrup

This comment has been minimized.

Copy link
Owner Author

@haugstrup haugstrup commented Jul 30, 2012

Sounds good :)

@rmurphey

This comment has been minimized.

Copy link

@rmurphey rmurphey commented Jul 30, 2012

Also, see https://gist.github.com/3185390#L34 for turning an integer into a sequence of binary digits, which may be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment