Go Down

Topic: Arduino library for Mitsubishi 50530 LCD displays ( 40x3 ) (Read 3507 times) previous topic - next topic


Mar 28, 2012, 10:45 am Last Edit: Mar 31, 2012, 07:20 pm by sponnet Reason: 1

Here's a first version of a library for LCD displays based on the Mitsubishi 50530 chip.


We have tested it on an Optrex DMC-50652N display , but it should also work on a Seiko/IIS C456002A

We'll add cleaner wiring diagram later, but the data pins should be at :

digital 0 -> DB7 (databit 7)
digital 1 ->  DB6 (databit 6)
digital 2 ->  DB5 (databit 5)
digital 3 ->  DB4 (databit 4)
digital 4 ->  EX (Execute)   
digital 5 ->  R/W (Read/Write)
digital 6 ->  I/OC1 (IO Control 1)
digital 7 ->  I/OC2 (IO Control 2)

5V -> VSS (GND)
Gnd -> Vdd (logic power)

VLCD (LCD power) should get a voltage of 12v in our tests , or the LCD display shows no characters ( in our test ), so you need an external power source for that...

Remarks are welcome !

Created by Jeroen van Beirendonck & Stefaan Ponnet - inspired on the work of these guys : http://www.weethet.nl/dutch/basicstamp2_optrexdmc50652n_lcd.php


Mar 28, 2012, 05:13 pm Last Edit: Mar 28, 2012, 05:18 pm by floresta Reason: 1
Here's a first version of a library for LCD displays based on the Mitsubishi 50530 chip.

It looks like something (the library) is missing.

Try it again - there are limits on what you can do on your first post.



Sorry for that , the link is right here :

Remarks / patches are welcome !


i'm trying to use your lib but 2 problems i need do use things like :
lcd.print ("   Controler");
is this possible ???

Best Regards
Jaime Branco


ok i have change your libs now we can use lcd.print()
Code: [Select]
#include "LCD50530.h"

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"

LCD50530::LCD50530(uint8_t ioc1, uint8_t ioc2, uint8_t rw, uint8_t ex, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
init(ioc1, ioc2, rw, ex, d4, d5, d6, d7);

void LCD50530::init(uint8_t ioc1, uint8_t ioc2, uint8_t rw, uint8_t ex, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
 _ioc1_pin = ioc1;
 _ioc2_pin = ioc2;
 _rw_pin = rw;
 _ex_pin = ex;
 _data_pins[0] = d4;
 _data_pins[1] = d5;
 _data_pins[2] = d6;
 _data_pins[3] = d7;

 DDRD = B11111111; // Default: Set all ports to output (Atmel shortcut)    

void LCD50530::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {  
 int totalChar = cols*lines;

 uint8_t displaySize = 0x00;
 if(lines <= 1)
displaySize |= LCD_1LINE;
 else if (lines == 2)
displaySize |= LCD_2LINE;
displaySize |= LCD_4LINE;
 if(totalChar <= 160) {
displaySize |= LCD_160CHAR;
_cols = 160/lines;
 else if(totalChar <= 192) {
displaySize |= LCD_192CHAR;
_cols = 192/lines;
 else if(totalChar <= 224) {
displaySize |= LCD_224CHAR;
_cols = 224/lines;
 else{ // 256 characters -
displaySize |= LCD_256CHAR;
_cols = 256/lines;
 _functionmode = LCD_4BITMODE | LCD_5x8DOTS | displaySize;
 command(LCD_FUNCTIONMODESET | _functionmode);
 _displaymode = LCD_DISPLAYON;
 command(LCD_DISPLAYMODESET | _displaymode);

 command(LCD_ENTRYMODESET | _entrymode);

/********** high level commands, for the user! */
void LCD50530::clear()
 command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero

void LCD50530::home()
 command(LCD_RETURNHOME);  // set cursor position to zero

void LCD50530::setCursor(uint8_t col, uint8_t row)
 uint8_t instruction = row*_cols+col;
 send(instruction, 1<<_ioc1_pin | 1<<_ioc2_pin);

// Turn the display on/off (quickly)
void LCD50530::noDisplay() {
 _displaymode &= ~LCD_DISPLAYON;
 command(LCD_DISPLAYMODESET | _displaymode);
void LCD50530::display() {
 _displaymode |= LCD_DISPLAYON;
 command(LCD_DISPLAYMODESET | _displaymode);

// Turns the underline cursor on/off
void LCD50530::noCursor() {
 _displaymode &= ~LCD_CURSORON;
 command(LCD_DISPLAYMODESET | _displaymode);
void LCD50530::cursor() {
 _displaymode |= LCD_CURSORON;
 command(LCD_DISPLAYMODESET | _displaymode);

// Turns the underline cursor on/off
void LCD50530::noUnderline() {
 _displaymode &= ~LCD_UNDERLINEON;
 command(LCD_DISPLAYMODESET | _displaymode);
void LCD50530::underline() {
 _displaymode |= LCD_UNDERLINEON;
 command(LCD_DISPLAYMODESET | _displaymode);
// Turn on and off the blinking cursor
void LCD50530::noCursorBlink() {
 _displaymode &= ~LCD_CURSORBLINKON;
 command(LCD_DISPLAYMODESET | _displaymode);
void LCD50530::cursorBlink() {
 _displaymode |= LCD_CURSORBLINKON;
 command(LCD_DISPLAYMODESET | _displaymode);

// Turn on and off the blinking cursor
void LCD50530::noCharBlink() {
 _displaymode &= ~LCD_CHRBLINKON;
 command(LCD_DISPLAYMODESET | _displaymode);
void LCD50530::charBlink() {
 _displaymode |= LCD_CHRBLINKON;
 command(LCD_DISPLAYMODESET | _displaymode);

// These commands moves the cursor one space in the directopn without changing the RAM
void LCD50530::shiftCursor(uint8_t direction) {    
 command(LCD_SHIFTCOMMAND | LCD_CURSORSHIFT | (direction<<2));

// These commands moves the display one space in the directopn without changing the RAM
void LCD50530::shiftDisplay(uint8_t direction) {
// This is for text that flows Left to Right
void LCD50530::moveCursorAfterInstruction(uint8_t direction, uint8_t instruction) {
 _entrymode &= B01000111;
 _entrymode |= ((instruction | direction) <<3);
 command(LCD_ENTRYMODESET | _entrymode);

void LCD50530::moveDisplayAfterInstruction(uint8_t direction, uint8_t instruction) {
 _entrymode &= B01111000;
 _entrymode |= instruction | direction;
 command(LCD_ENTRYMODESET | _entrymode);

void LCD50530::holdCursor(void) {
command(LCD_ENTRYMODESET & B01000111);

void LCD50530::holdDisplay(void) {
command(LCD_ENTRYMODESET & B01111000);

// This is for text that flows Left to Right
void LCD50530::leftToRight(void) {
 moveCursorAfterInstruction(LCD_WRITE, LCD_RIGHT);

// This is for text that flows Right to Left
void LCD50530::rightToLeft(void) {
moveCursorAfterInstruction(LCD_WRITE, LCD_LEFT);

// This will 'right justify' text from the cursor
void LCD50530::autoscroll(void) {
 moveDisplayAfterInstruction(LCD_WRITE, LCD_RIGHT);

// This will 'left justify' text from the cursor
void LCD50530::noAutoscroll(void) {
 moveDisplayAfterInstruction(LCD_WRITE, LCD_LEFT);

/*********** mid level commands, for sending data/cmds */

inline void LCD50530::command(uint8_t value) {
 send(value, 0);

void LCD50530::writechar(uint8_t value) {
 send(value, 1<<_ioc2_pin);  
inline size_t LCD50530::write(uint8_t value) {
 send(value, HIGH);
 return 1; // assume sucess

/************ low level data pushing commands **********/

// write either command or data, with automatic 4/8-bit selection
void LCD50530::send(uint8_t value, uint8_t controlpins) {
 while(busyState()); // Wait while the lcd controller is still busy      
 write4bits(value, controlpins);
 write4bits(value<<4, controlpins);

void LCD50530::pulseExecute(void) {
 digitalWrite(_ex_pin, HIGH);
 digitalWrite(_ex_pin, LOW);

void LCD50530::write4bits(uint8_t value, uint8_t controlpins) {
 PORTD = (value & B11110000) | controlpins;

Returns the state of the lcd controller
When 0 is returned, the controller is ready for a new instruction
uint8_t LCD50530::busyState() {
 uint8_t state = 0;
 DDRD = B00001111; // Set data pins to input
 PORTD = 1<<_rw_pin;
 digitalWrite(_ex_pin, HIGH);
 state = digitalRead(_data_pins[3]);
 digitalWrite(_ex_pin, LOW);
 PORTD = 1<<_rw_pin;
 digitalWrite(_ex_pin, HIGH);
 state |= digitalRead(_data_pins[3]);
 digitalWrite(_ex_pin, LOW);
 DDRD = B11111111; // Reset pins to output
 return state;



Code: [Select]
LCD driver for Mitsubishi 50530 compatible displays


#ifndef LCD50530_h
#define LCD50530_h

#include <inttypes.h>
#include "Print.h"

// Full commands
#define LCD_NOOP 0x00
#define LCD_RETURNHOME 0x03

// Partial commands (with flags)
#define LCD_BLINKFREQSET 0x04 // with flags
#define LCD_WRITERAMULINESET 0x08 // with flags
#define LCD_UNDERLINEMODESET 0x0C // with flags
#define LCD_SHIFTCOMMAND 0x10 // with flags
#define LCD_DISPLAYMODESET 0x20 // with flags
#define LCD_ENTRYMODESET 0x40 // with flags
#define LCD_FUNCTIONMODESET 0xC0 // with flags

//#define LCD_SETCGRAMADDR 0x40
//#define LCD_SETDDRAMADDR 0x80

// flags for function mode set
#define LCD_8BITMODE 0x20
#define LCD_4BITMODE 0x00
#define LCD_4LINE 0x08
#define LCD_2LINE 0x04
#define LCD_1LINE 0x00
#define LCD_5x12DOTS 0x00
#define LCD_5x8DOTS 0x10
#define LCD_160CHAR 0x03
#define LCD_192CHAR 0x02
#define LCD_224CHAR 0x01
#define LCD_256CHAR 0x00

// TODO: RAM -- setting region (page 28/29 of datasheet)

// flags for display set entry mode
#define LCD_DISPLAYMOVEREAD 0x01 // Update display address after reading RAM data
#define LCD_DISPLAYMOVEWRITE 0x02 // Update display address after writing RAM data
#define LCD_CURSORMOVEREAD 0x08 // Update cursor address after reading RAM data
#define LCD_CURSORMOVEWRITE 0x10 // Update cursor address after writing RAM data
#define LCD_DISPLAYMOVERIGHT 0x00 // Display address decremented after instruction
#define LCD_DISPLAYMOVELEFT 0x04 // Display address incremented after instruction
#define LCD_CURSORMOVELEFT 0x20 // Cursor address decremented after instruction
#define LCD_CURSORMOVERIGHT 0x00 // Cursor address incremented after instruction

#define LCD_LEFT 0x04
#define LCD_RIGHT 0x00
#define LCD_READ 0x01
#define LCD_WRITE 0x02

// flags for display on/off control
#define LCD_DISPLAYON 0x10 // Turn all displays on
#define LCD_DISPLAYOFF 0x00 // Turn all displays off
#define LCD_CURSORON 0x08 // Turn on cursor display
#define LCD_CURSOROFF 0x00 // Turn off cursor display
#define LCD_UNDERLINEON 0x04 // Turn on underline display
#define LCD_UNDERLINEOFF 0x00 // Turn off underline display
#define LCD_CURSORBLINKON 0x02 // Blinking cursor display
#define LCD_CURSORBLINKOFF 0x00 // Cursor display without blinking
#define LCD_CHRBLINKON 0x01 // Blinking Character display of cursor position
#define LCD_CHRBLINKOFF 0x00 // Character display without blinking

// flags for display/cursor shift command
#define LCD_CURSORSHIFT 0x08
#define LCD_SHIFTLEFT 0x01
#define LCD_SHIFTRIGHT 0x00

// TODO: flags for underline mode instruction (SU)
// TODO: flags for Write underline bit instruction (WU)
// TODO: flags for Set blink frequency instruction (SB)

class LCD50530 : public Print {
 LCD50530(uint8_t ioc1, uint8_t ioc2, uint8_t rw, uint8_t ex, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);

 void init(uint8_t ioc1, uint8_t ioc2, uint8_t rw, uint8_t ex, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
 void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);

 void clear();
 void home();

 void noDisplay();
 void display();
 void noCursor();
 void cursor();
 void noUnderline();
 void underline();
 void noCursorBlink();
 void cursorBlink();
 void noCharBlink();
 void charBlink();

 void moveCursorAfterInstruction(uint8_t direction, uint8_t instruction);
 void moveDisplayAfterInstruction(uint8_t direction, uint8_t instruction);
 void holdCursor();
 void holdDisplay();

 void shiftCursor(uint8_t direction);
 void shiftDisplay(uint8_t direction);
 void leftToRight();
 void rightToLeft();
 void autoscroll();
 void noAutoscroll();

 //void createChar(uint8_t, uint8_t[]);
 void setCursor(uint8_t, uint8_t);
 void command(uint8_t);
 void writechar(uint8_t);
 virtual size_t write(uint8_t);
 using Print::write;
 void send(uint8_t, uint8_t);
 void write4bits(uint8_t, uint8_t);
 void pulseExecute();
 uint8_t busyState();

 uint8_t _ioc1_pin; // LOW: command.  HIGH: character.
 uint8_t _ioc2_pin; // LOW: command.  HIGH: character.
 uint8_t _rw_pin; // LOW: write to LCD.  HIGH: read from LCD.
 uint8_t _ex_pin; // activated by a HIGH pulse.
 uint8_t _data_pins[4];

 uint8_t _functionmode;
 uint8_t _displaymode;
 uint8_t _entrymode;

 uint8_t _initialized;

 uint8_t _numlines, _currline;
 uint8_t _cols;


Go Up