Hi guys.
Just picked up an odd bag of display components, a few LED displays and sorts, I don't usually buy these crappy bags of junk, but one thing attracted me and at the price, an AMPY 2001-11 LCD. I though this LCD display was worth the money itself, but it seems I may have been wrong as I cant find any information or data sheets on this device,The so called supplied datasheet was about as useful as a fork in a sugar bowl.
I'm experimenting with AVR micro's and wanted to take my projects a little further with LCD's.
Maybe some of you guys have seen or know about this or even have a datasheet.
A pretty extensive Google search came up with nothing??
Help please.
Thanks.
Yes, it's a Hitachi HD44780 clone. Anything chinese is almost always a copy of some existing western standard, just renamed.
You can find more variations of LCDs with this controller at Allelectronics.
40x2 (80 chars) is the maximum one controller can address. 40x4 screens exist and just use two controllers.
You can pull these screens out of many electronics from the 80s to 90s... desk phones, alarm consoles, ind. automation displays, etc
The pinout will be similar to the ones on these:
http://uk.farnell.com/midas/mc21605b6w-fptlw/lcd-2x16-fstn-white-led-b-l-5v/dp/2063169http://uk.farnell.com/midas/mc21605b6w-spr/lcd-2x16-stn-reflective-5mm/dp/2063239http://uk.farnell.com/midas/mc21605a6wd-sptly/lcd-2x16-stn-ylw-green-b-l-5mm/dp/2063233http://ro.farnell.com/midas/mc21605ab6w-gptly/lcd-2x16-grey-stn-g-b-l-5mm/dp/2063119The controllers are all hd44780 clones or using the same protocol with some added features. You can check the datasheets in the links above.
This is the datasheet of one of those controllers, with additional information that may not be found in the datasheets from the links above (but the datasheets above have all you need to make it work) :
http://savedonthe.net/download/440/SPLC780D-sunplus-lcd-controller.htmlYou'll find ready made libraries for these screens.
I've coded my own very simple routines, and they're somewhat optimized for 16mhz clock (i mean in some places i use a number of instructions that i know they'll take a microsecond or something like that to be processed at 16 mhz clock) :
(RS, RW and EN are on PORTE on a 40 pin pic, 8 bit data to lcd on porta)
newlcd.h
#ifndef __LCDH_INIT
#define __LCDH_INIT
#define LCD_RS PORTEbits.RE0
#define LCD_RW PORTEbits.RE1
#define LCD_EN PORTEbits.RE2
#define LCD_DATA PORTA
#define LCD_TRIS TRISA
#define LCD_MASK_OFF 0x00; // all pins on PORT A set to output
#define LCD_MASK_ON 0x80; // pin 7/LCD_DATA3 set to input
// keep LCD_EN =1 for 500ns when clock is 16Mhz
#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN = 1), (LCD_EN=0))
#define lcd_clear() lcd_control(1);
#define lcd_home() lcd_control(2);
#define lcd_display(screen, cursor, blink) lcd_control(8+4*screen+2*cursor+blink)
#define lcd_shift(cursor,screen) lcd_control(16+8*cursor+4*screen)
#define lcd_goto(position) lcd_control(0x80 | position)
#endif
extern void lcd_start();
extern void lcd_control(unsigned char command);
extern void lcd_data(unsigned char data);
extern void lcd_busy();
extern void lcd_string(const char *s);
newlcd.c
#include "htc.h"
#include "newlcd.h"
#include "delay.h"
void lcd_busy() {
delay_ms(2);
return;
LCD_TRIS = 0x80;
LCD_DATA = 0;
LCD_RS = 0;
LCD_RW = 1;
do {
LCD_STROBE();
delay_1us();
} while ((LCD_DATA>>7)==1);
LCD_TRIS = 0;
LCD_DATA = 0;
LCD_RW = 0;
LCD_RS = 0;
}
void lcd_control(unsigned char command){
lcd_busy();
LCD_RS = 0;
LCD_RW = 0;
LCD_DATA = command;
LCD_STROBE();
}
void lcd_data(unsigned char data){
lcd_busy();
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA = data;
LCD_STROBE();
LCD_RS = 0;
}
void lcd_reset(){
delay_ms(20);
LCD_DATA = 0b00110000; // function set (8 bits)
LCD_STROBE();
delay_ms(5);
LCD_STROBE(); // function set (8 bits)
delay_1ms();
LCD_STROBE(); // function set (8 bits)
}
void lcd_start(){
lcd_reset();
lcd_control(0b00111000); // 0011NFxx
lcd_control(0b00001000); // 00001DCB
lcd_control(0b00000001); // clear
lcd_control(0b00000110); // 000001IS
}
void lcd_string(const char *s) {
while(*s) {
lcd_data(*s++);
}
}
delay.h - delay routines that assume the clock is set at 16 mhz, they can be changed to another value or you can use the internal delays of your compiler
// Delay routines for 16 Mhz clock.
//
// 16 Mhz = 4 Hz per cycle = 4 operations/cycles per uS
//
#ifndef __DELAYH_INIT
#define __DELAYH_INIT
#define delay_1tcy() asm("nop")
#define delay_2tcy() asm("goto $+1")
#define delay_4tcy() asm("goto $+1");asm("goto $+1");
#define delay_10tcy() delay_2tcy();delay_4tcy();delay_4tcy();
#define delay_500ns() delay_2tcy()
#define delay_1us() delay_4tcy()
#define delay_4us() delay_1us();delay_1us();delay_1us();delay_1us();
#define delay_5us() delay_4us();delay_1us();
#define delay_10us() delay_5us();delay_5us();
#define delay_5ms() delay_ms(5);
#define delay_10ms() delay_ms(10);
#define delay_25ms() delay_ms(25);
#define delay_50ms() delay_ms(50);
#endif
extern void delay_25us();
extern void delay_50us();
extern void delay_100us();
extern void delay_1ms();
extern void delay_ms(unsigned char ms);
delay.c
#include "delay.h"
void delay_25us(){
// function call and return is 4 cycles, on 16Mhz that's 1us
// so delay for 24us here
delay_10us();
delay_10us();
delay_4us();
}
void delay_50us(){
delay_10us();
delay_10us();
delay_10us();
delay_10us();
delay_5us();
delay_4us();
}
void delay_100us(){
delay_50us();
delay_10us();
delay_10us();
delay_10us();
delay_10us();
delay_5us();
delay_4us();
}
void delay_1ms(){
unsigned char n = 248;
do {
asm("goto $+1"); asm("goto $+1"); asm("goto $+1");
asm("goto $+1"); asm("goto $+1"); asm("goto $+1");
asm("nop");
// decrease if not zero - decfsz (1 cycle if !=0, 2 cycles otherwise)
// goto loop start = 2 cycles
} while(--n);
// = 16 cycles x [n+1] + 1 (from last decfsz) - 2 (last goto is skipped)
// 249x16+1-2 = 3983 cycles (1 = decfsz ), -2 for last goto
// + 1 = 3984 cycles (assignment of 248 to n)
// + 4 = 3988 cycles (function call and return)
delay_2tcy(); // = 3990 cycles
delay_10tcy(); // = 4000 cycles
}
// Delay up to 255 milliseconds - approximately (ms + 19 cycles so a few microseconds over the actual value).
void delay_ms(unsigned char ms) {
unsigned char n;
while(ms--) { // time in cycles for the inner loop including
n = 249; // cycles = 19+16*ms*[1+n]
// cycles = 4000*ms + 19 for 16MHz clock
// cycles = 2000*ms + 19 for 8MHz clock
delay_4tcy();
do {
asm("goto $+1");
asm("goto $+1");
asm("goto $+1");
asm("goto $+1");
asm("goto $+1");
asm("goto $+1");
asm("nop");
// decrease if not zero - decfsz (1 cycle if !=0, 2 cycles otherwise)
// goto loop start - 2 cycles
} while(--n);
// = 16 cycles x [n+1] + 1 (from last decfsz)
}
}
I picked-up one of these party-packs too - Maplin, by any chance? (called RadioShack if you're in the US)
I thought it looked like a 16x2 5v display. Anyhow, I plugged it into a project I'm working on ATM, and hey-presto! it ISN'T 16x2, its 16x1 large characters, and another line, much smaller, of some "other stuff". Check out
http://www.tgsolarsystems.com/downloads/5224-ampy-meters-user-manual-and-technical-specfication.pdf as an example of this kind of display. Maybe the same one, I don't know. I'm getting some characters displayed on the bottom, but I haven't figured-out yet what they are/how to drive them correctly. I think some are single-use characters, e.g. at the mo I have a single "h" in the lower portion, just left of centre. It isn't bitmapped though, its really quite clear. It looks to me like you can either have an "h" there, or not - nothing else. Over to the right I can get some funny graphics characters which presumably have a meaning in the product for which this LCD panel has obviously been specifically produced.
Anyhow - as guessed before, the first line behaves according to the HD44780 standard for a 1x16 display.
If I get any further with a definitive description of the second line I'll post it here.
Best regards
Well, I wouldn't call this definitive but here goes...
I've used these 2 tables on a PIC to define the address and data for the 2nd line graphics:
posntab
addwf PCL, f
dt 0xc1,0xc1,0xc3,0xc3,0xc5,0xc5,0xc7,0xc7,0xc8,0xc8,0xca,0xca,0xcc,0xcc,0xce ;
chrtab
addwf PCL, f
dt 0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00 ;
where you'd use the same index into both. The values in chrtab are just some that I found to work. Possibly there are individual bits to control the graphic characters, but I doubt it because writing zero also causes many (but not all) of them to appear. It doesn't seem to be as simple as some bit having 1=off 0=on though. Or maybe it is - I'm pretty tired now.
Here's a little video I just made:
http://youtu.be/PQXrQS4AeZAEnjoy.
Information from my work last night. I can now address the 16*1 using a standard LCD driver. Cursor position and all the normal LCD codes work ok. The first line is adddress from 128, this is the same as normal LCD driver.
I am using a Picaxe to interface to the LCD, in 8-bit mode. (I think I code you could use 4-bit mode by pulling D0-D3 to ground which I failed to do yesterday - but, it ho hum).
I believe the symbols are in two pairs, addressed as pairs of characters. The DRAM addressing is as shown in the routines below.
Example, the first two symbols on line two are addressed at position 193 with "D"|"J"|"E"|" " chosing the left, right, both or clear respectively, the space clears the chars. They run in two step until 199 then 1, then back to two step... odd. But, this code does seems to work.
Please examine the code as the example is a general rule. There is one adapation to the rule.
Works OK for me.
Anobium
#picaxe 08m2
#no_data
pause 2000
' clear LCD
serout C.2,N2400,(254,1)
pause 100
' pos 1 line 1
serout C.2,N2400,(254,128)
pause 100
' display string
serout C.2,N2400,(#b1, ": Testing")
pause 100
' Table of information!! i.e. printing a "D" at position 193 with show the L1 symbol only.
' First two chars
' L1
'serout C.2,N2400,(254,193,"D")
' L2
' serout C.2,N2400,(254,193,"J")
' both
' serout C.2,N2400,(254,193,"E")
' Second two chars
' L3
' serout C.2,N2400,(254,195,"D")
' kw
' serout C.2,N2400,(254,195,"J")
' both
' serout C.2,N2400,(254,195,"E")
' Third two chars
' h
' serout C.2,N2400,(254,197,"D")
' kvar
' serout C.2,N2400,(254,197,"J")
' both
' serout C.2,N2400,(254,197,"E")
' Forth two chars
' h
' serout C.2,N2400,(254,199,"D")
' (Down chevron)!
' serout C.2,N2400,(254,199,"J")
' both
' serout C.2,N2400,(254,199,"E")
' Fifth two chars
' Circle
' serout C.2,N2400,(254,200,"D")
' Square
' serout C.2,N2400,(254,200,"J")
' both
' serout C.2,N2400,(254,200,"E")
' sixth two chars
' NE Quad
' serout C.2,N2400,(254,202,"D")
' NW Quad
' serout C.2,N2400,(254,202,"J")
' both
' serout C.2,N2400,(254,202,"E")
' seventh two chars
' SW Quad
' serout C.2,N2400,(254,204,"I")
' SE Quad
' serout C.2,N2400,(254,204,"H")
' both
' serout C.2,N2400,(254,204,"E")
' last two chars
' both = house
' serout C.2,N2400,(254,206,"E")
' example code. this shows the quadrants by cycling thru the symbols.
do
' show NE Quad
serout C.2,N2400,(254,202,"D")
pause 250
' show NW Quad
serout C.2,N2400,(254,202,"J")
pause 250
' blank NE quad
serout C.2,N2400,(254,202," ")
' SW Quad
serout C.2,N2400,(254,204,"I")
pause 250
' SE Quad
serout C.2,N2400,(254,204,"H")
pause 250
' blank SW quad
serout C.2,N2400,(254,204," ")
loop
Anobium,
Maybe we have subtly different versions of the display. Anyway, if its working for you then its all good, and we've given others a couple of things to try. Personally I'd say that I'd rather put a non-zero value in to mean display something (your version) - I just used zero 'cos it was the first value which worked (for me).
If you can figure-out the picaxe necessary to set the display to 4-bit then I think you'd make some people happy. I use a raw PIC16F688 not picaxe, so I can't help. What I can say is that it works a/p my previous post on my setup, which I hope is legible enough to rewrite in picaxe.
Note to self - I just noticed that in my code I'm writing to all of LCD_PORT in parts of this routine, but I'm only using 4 bits of that for the LCD. the LCDIns routine masks these off, and so should this initialise routine. Here's LCDIns:
LCDIns ;Send the Instruction to the LCD
; #ifdef __DEBUG
; return ;
; #endif
movwf LCDTemp ;Save the Value
movf LCD_PORT,W ;
andlw 0x0F ;these are bits we're NOT using
movwf LCDHoldPort ;so retain them
movf LCDTemp,W ;
andlw 0xF0 ;Most Significant Nibble first
iorwf LCDHoldPort,W ;Restore the bits we're not using
movwf LCD_PORT ;
bcf LCD_CPORT, LCD_RS ;
call Pulse_e ;
swapf LCDTemp, W ;Least Significant Nibble Second
andlw 0xF0 ;
iorwf LCDHoldPort,W ;Restore the bits we're not using
movwf LCD_PORT ;
bcf LCD_CPORT, LCD_RS ;
call Pulse_e ;
call Del01 ;wait 1 ms
movf LCDTemp, W ;
andlw 0xFC ;Have to Delay 5 msecs?
btfsc STATUS, Z ;
call Del01 ;1ms
return
Its annoying how my nicely tabbed code gets all squirly when I paste it into this edit box

Telbee,
My first YouTube post, so cheers.
jeroen74,
Thanks very much - edited per your instruction.
Hi Guys,
I also picked one of these AMPY 2011-11 up and am trying to run it from an Arduino.
I'm getting power to the LCD fine, and using the Arduino Hitachi Library.
Using any 4 or 8 of the data pins and will not make the LCD show data, and I have no way to know if it is even receiving the instructions.
All I get is a row or boxes when i hit the power, as as if it is not driven at all. If this is a Hitachi clone, I would have expected to be able to drive it this way.
--Any Ideas?
What i'm wondering as well is what do i do with pins 11-13? They seem to be powering LEDs and then is that a timer, but i'm not an electronics expert so I must be missing something. There also seems to be NO backlight functionality on these.
Can someone simply give a numbered pinout list and a code example to use the arduino LCD library to drive this thing?
and explain what the timers are doing.
Sorry for demanding it spoonfed to me, I'm pretty useless with this LCD - it has me stumped!
Thanks in advance.
philthetechie,
Do you still have the datasheet? if not, its at
http://www.kemo-electronic.de/datasheets/s043.pdfYou definitely need pin 11 because its the R/W pin (I notice on the datasheet its labelled as RW, but it should properly be R/W where the W has a bar over, meaning "not W")
I also notice that there is a pin marked as R/S, but this should read RS because it means "Register Select"
Anyway, the connections you need are:
pin 01 is D0
pin 02 is D1
pin 03 is D2
pin 04 is D3
pin 05 is D4
pin 06 is D5
pin 07 is D6
pin 08 is D7
pin 09 is RS (Register Select)
pin 10 is EN (Enable)
pin 11 is R/(not W) (Read/not Write)
pin 16 to GND
pin 17 to +5V
The others you don't need, and pin 01 to 04 you don't need if you manage to get the 4-bit interface working. I'd get the 8-bit working first, then decide.
Looking at the datasheet be careful how you read it - the pin numbers are ABOVE the pin, so where the number 11 it is above a pin which it doesn't show connected to anything, but the pin above the number 11 (which is pin 13) is connected to a transistor used to drive LED2. Don't bother trying to get the LEDs lit just yet.
The Arduino Hitachi library should have a document describing the pins D0-D7, RS, EN and R/(not W), and where to connect them.
A quick note about R(not W) (and if you already "get" this then I apologise) if this pin is high then you are reading, i.e. not writing. If this pin is low then you are not reading, and you are not not-writing, i.e. you ARE writing. I'm not reading from this board, so I've got pin 11 connected to GND.
There aren't any timers I'm aware of. There are a couple of transistors on the board labelled T1 and T2.
Interesting that this board doesn't have a VO (Operating Voltage) pin. This is usually used to set the display contrast. I guess they use a fixed resistor on-board.
I think you're right that there is no backlight.
If you also put a constant 5v onto pin 15 then you can get the LEDs lit by raising pins 11 and/or 13 to 5v. Also, you can read the push-button on pin 14. So you can connect pins 11 & 13 to outputs on the Arduino and it'll light the LEDs when you like, and you can connect pin 14 to an input on the Arduino and you can see if the push-button is pressed.
How well do you know the Arduino? you'll either have to poll the button (check very regularly) or connect it to an interrupting input and write the interrupt handler. (much better way)
Best regards
I'm pretty sure i have a faulty board now.
I've wired up as you have mentioned, using R/W as not-not-write (i.e. to ground), and using the code:
LiquidCrystal lcd(12,10, 0, 1, 2, 3, 4, 5, 6, 7); // RS/Enable/d0-d7
void setup() {
lcd.begin(16,1); // or 16,2 - tested both ways as this board has a 2nd line of symbols.
lcd.print("test");
}
I get a out-of-sync error when uploading the file if the power is going to the LCD-
avrdude: stk500_cmd(): programmer is out of sync
Have to unplug +5v from the LCD to upload. This makes me wonder about the state of the LCD.
When i connect the power, there are just 16 black boxes instead of 4 characters.
The layout i'm using I had tried before using the datasheet but im apt to blame my own ineptitude rather than components - but now...
Have tried 4 and 8bit, tried connecting R/W to pin 13 and using the format
LiquidCrystal lcd(12, 13, 10, 0, 1, 2, 3, 4, 5, 6, 7);
Nothing is getting any data to display.
Bit of a bummer... Wonder if they will do an RMA on a lucky bag? Worth a shot.
You probably didn't connect it properly.

If this is the display,
pin 1 to 8 is data
pin 9 is rs
pin 10 is en
pin 11 is rw
pin 12 and 13 are the leds (send 5v or a digital 1 and led lights up)
pin 14 is the button ( put a 1-10k resistor between that and your controller pin, set the pin to input and when button is pressed you get 1 on controller pin)
pin 15 is voltage to make the leds work and the button (if there's no 3.3v-5v on this pin, button and leds won't work)
pin 16 is ground
pin 17 is 5v
pin 18 is not connected
So I think you should have LiquidCrystal lcd(8,9, 0, 1, 2, 3, 4, 5, 6, 7); - i'm saying 8 and 9 because you've used 0 to 7 for data, so I assume you used consecutive numbers for the rest.