Library for Grove LCD RGB Display on Electric Imp Board Imp003


#1

Is there a library to use a Grove LCD RGB (from seed studio) Display on an imp003 board?

I got this LCD Display --> http://wiki.seeedstudio.com/Grove-LCD_RGB_Backlight/ and i want to make it works on the Imp 003 --> https://store.electricimp.com/products/imp003-breakout-board?variant=31162918482

I connect the SDA and SCL on i2cAB Pins and i`m using an external source for the 5v for the VCC because the imp only got 3.3v.

I allready test the Display on a raspberry (works with python library), but for the Imp (Squirrel Code) i cant find any library to use it or an example code to test it.

anyone have some code that helps?

regards


#2

There isn’t an official library for that display, but here’s a driver I wrote for it quite some time ago. It should work, but I make no promises as I haven’t used the library for a long while. Nor is it feature-complete. But it should help get you started.

class GroveLCD {

	// I2C Addresses
	static LCD_ADDRESS = 0x7C;
	static RGB_ADDRESS = 0xC4;

	static LCD_COMMAND = "\x80";
	static LCD_DATA = "\x40";

	// Colors
	static REG_RED = 0x04;        // pwm2
	static REG_GREEN = 0x03;        // pwm1
	static REG_BLUE = 0x02;       // pwm0

	static REG_MODE1 = 0x00;
	static REG_MODE2 = 0x01;
	static REG_OUTPUT = 0x08;

	// Commands
	static LCD_CLEARDISPLAY = 0x01;
	static LCD_RETURNHOME = 0x02;
	static LCD_ENTRYMODESET = 0x04;
	static LCD_DISPLAYCONTROL = 0x08;
	static LCD_CURSORSHIFT = 0x10;
	static LCD_FUNCTIONSET = 0x20;
	static LCD_SETCGRAMADDR = 0x40;
	static LCD_SETDDRAMADDR = 0x80;

	// Flags for display entry mode
	static LCD_ENTRYRIGHT = 0x00;
	static LCD_ENTRYLEFT = 0x02;
	static LCD_ENTRYSHIFTINCREMENT = 0x01;
	static LCD_ENTRYSHIFTDECREMENT = 0x00;

	// Flags for display on/off control
	static LCD_DISPLAYON = 0x04;
	static LCD_DISPLAYOFF = 0x00;
	static LCD_CURSORON = 0x02;
	static LCD_CURSOROFF = 0x00;
	static LCD_BLINKON = 0x01;
	static LCD_BLINKOFF = 0x00;

	// Flags for display/cursor shift
	static LCD_DISPLAYMOVE = 0x08;
	static LCD_CURSORMOVE = 0x00;
	static LCD_MOVERIGHT = 0x04;
	static LCD_MOVELEFT = 0x00;

	// Flags for function set
	static LCD_8BITMODE = 0x10;
	static LCD_4BITMODE = 0x00;
	static LCD_2LINE = 0x08;
	static LCD_1LINE = 0x00;
	static LCD_5x10DOTS = 0x04;
	static LCD_5x8DOTS = 0x00;

	// Private properties
	_i2c = null;
	_currentLine = 0;
	_numLines = 0;
	_displayFunction = 0;
	_displayControl = 0;
	_displayMode = 0;

	constructor(impBus = null) {
		if (impBus == null) throw "Grove LCD class cannot function without a non-null I2C object";
		_i2c = impBus;
	}

	function init(dotsize = 0) {
		local rows = 2;
		local cols = 16;

		_displayFunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS;

    	// According to datasheet, we need at least 40ms after power rises above 2.7V
		_delay(50);

		// Send function set command sequence
		_command(LCD_FUNCTIONSET | _displayFunction);
		_delay(5);
		_command(LCD_FUNCTIONSET | _displayFunction);
		_delay(5);
		_command(LCD_FUNCTIONSET | _displayFunction);

    	// Turn the display on with no cursor or blinking as default
    	_displayControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
    	displayon();

    	// Clear the screen
    	clear();

		// Initialize to default text direction (L-R)
		_displayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
		// Set the entry mode
		_command(LCD_ENTRYMODESET | _displayMode);

		// Initialise backlight
		_setReg(REG_MODE1, 0);
		// Set LEDs controllable by both PWM and GRPPWM registers
		_setReg(REG_OUTPUT, 0xFF);
		// Set MODE2 values
		// 0010 0000 -> 0x20  (DMBLNK to 1, ie blinky mode)
		_setReg(REG_MODE2, 0x20);

		// Set the backlight colour
		setRGB(16,16,16);
	}

	function clear() {
		_command(LCD_CLEARDISPLAY);
    	_delay(2);
    }

    function home() {
    	_command(LCD_RETURNHOME);
    	_delay(2);
	}

	function setCursor(col, row) {
		col = (row == 0 ? col | 0x80 : col | 0xc0);
		_command(col);
	}

	function printString(string) {
		if (string.len() > 0) {
			server.log(string);
			for (local i = 0 ; i < string.len() ; ++i) {
            	_data(string[i]);
            }
		}
	}

	function printCharacter(ascii) {
		local a = _i2c.write(LCD_ADDRESS, LCD_DATA + ascii.tochar());
		if (a != 0) server.error(a);
	}

	function displayon() {
    	// Power up and activate the display
        _displayControl = _displayControl | LCD_DISPLAYON;
        _command(LCD_DISPLAYCONTROL | _displayControl);
	}

	function displayoff() {
    	// Power down the display
        _displayControl = _displayControl | LCD_DISPLAYOFF;
        _command(LCD_DISPLAYCONTROL | _displayControl);
	}

	function setColourWhite() {
		setRGB(255, 255, 255);
	}

	function setColourRed() {
		setRGB(255, 0, 0);
	}

	function setColourGreen() {
		setRGB(0, 255, 0);
	}

	function setColourBlue() {
		setRGB(0, 0, 255);
	}

	function setRGB(red, green, blue) {
		_setReg(REG_RED, red);
    	_setReg(REG_GREEN, green);
    	_setReg(REG_BLUE, blue);
	}

	// Private Methods

	function _setReg(register, value) {
		_i2c.write(RGB_ADDRESS, register.tochar() + value.tochar());
	}

	function _command(value) {
		_i2c.write(LCD_ADDRESS, LCD_COMMAND + value.tochar());
	}

	function _data(value) {
		_i2c.write(LCD_ADDRESS, LCD_DATA + value.tochar());
	}

	function _delay(value) {
        // Blocking delay for ‘value’ milliseconds
        local a = hardware.millis() + value;
        while (hardware.millis() < a) {}
    }
}

#3

Thanks in advance for your help.

in my imp003, i connected the pins A (for SCL) and B (for SDA) and using 5v from an USB cable, then i`m using your class and with this code

lcd <- GroveLCD(hardware.i2cAB);
lcd.init();

local color = true;

function change(){
    if (color){
        lcd.setColourGreen();
        color = false;
    }else{
        lcd.setColourRed();
        color = true;
    }

    imp.wakeup(5, change);
}

change();

i should get the LCD turning colors between red and green, but doesnt work.

Am I doing something wrong???

thanks


#4

Your code looks right. Unfortunately, I’ve misplaced my own LCD, so I can’t run a check on the driver code.

One thing that occurs to me: the LCD is designed to work at 5V, the imp at 3.3V. You’re powering the LCD externally, but don’t forget that the SCL and SDA lines work at 3.3V too. Changes on the 3.3V might not be being detected by the LCD. So you may need to use a level adjuster to boost the I2C voltage from 3.3V to 5V, but you could try running the LCD off 3.3V first and see how that works out.