Our new official repo is on github
LCD Smartie version 5.6 is released!
Download it now: https://github.com/LCD-Smartie/LCDSmartie/releases

x64 without LPT onboard

General discussion about LCD Smartie.

Moderators: _X7JAY7X_, caesar, IFR, mattcro, limbo, Fast351

Post Reply
dafaithz
Posts: 1
Joined: February 17th, 2014, 10:30 am

x64 without LPT onboard

Post by dafaithz »

Hi everyone !

Sorry for my bad english in advance :)

I would love to have an LCD screen, so i read several forums and guides to get into it.
After a day of researching i came to the conclussion, that its not possible for me to get it to run, so i wanna get sure that i havent missed something...

you need a driver to "talk" to the LCD. ive found 2 of those "portnt" which is 32bit only and "inpout" with 64 bit support, but limited to onboard parallel ports (eg. no pci-e lpt or usb to ltp support).

so is there another solution to run my parallel lcd with lcd smartie within win 8 x64 and a pci-e parallel card or usb to lpt adapter ?

hurley
Posts: 46
Joined: May 26th, 2011, 8:03 am

Re: x64 without LPT onboard

Post by hurley »

There is 'official' usb adapter hardware available here:

http://www.lcdsmartie.org/
LCD SMARTIE OFFICIAL HARDWARE: http://forums.lcdsmartie.org/viewtopic.php?f=11&t=3414

I'm not sure of the status of this hardware but there are other usb-parallel 'backpacks' out there, maybe search on eBay or similar.

Alternatively, something like Arduino might be viable but more complicated.
I've just ordered a new OLED display and Arduino which I'll have to figure out to use with LCD Smartie when it gets here, so if you go that route, hopefully I could help with setting it up by then.

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

I have an Arduino UNO driving a 40x4 LCD on the front of my Media centre and happy to share the code which emulates a matrix orbital display (without buttons) so is easy to drive from LCDSmartie via the USB interface. I have also compiled and loaded the code on an Arduino Pro Micro and it works fine. These are very small and can be picked up for under 4 quid on ebay.

limbo
Plugin Author
Posts: 1604
Joined: February 13th, 2005, 7:38 pm
Location: Athens - Greece
Contact:

Re: x64 without LPT onboard

Post by limbo »

Can you please upload the sketch here?

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

No problem, feel free to modify/distribute/mangle or whatever :-)

Code: Select all

/*
  serial_lcd_smartie - an ethernet or serial based LCD Smartie sketch
  
  Dave Perrow January 2014
 
  Based on a simple HD44780 based LCD Display driver

  Feel free to share and modify

The Circuit:

LCD  n Symbol	Function 	        connection
Pin
1	Vss	Display power ground	ground (either black wire)
2	Vdd	Display power +5V	+5v (red wire)
3	Vo	Contrast Adjust.        ground (either black wire)
4	RS	Register select	        Arduino digital pin 7
5	R/W	Data read/write         ground (either black wire)
6	E	Enable strobe	        Arduino digital pin 6
7	DB0	Data Bus 0	        N/C
8	DB1	Data Bus 1	        N/C
9	DB2	Data Bus 2	        N/C
10	DB3	Data Bus 3	        N/C
11	DB4	Data Bus 4	        Arduino digital pin 5
12	DB5	Data Bus 5	        Arduino digital pin 4
13	DB6	Data Bus 6	        Arduino digital pin 3
14	DB7	Data Bus 7	        Arduino digital pin 2
15	A	LED backlight +5v	+5v (red wire)
16	K	LED backlight ground	ground (either black wire)

*/

// include the library code:
#include <Arduino.h>
#include <LiquidCrystal.h>

#define VERSION 1

#define LCD_D0       5
#define LCD_D1       4
#define LCD_D2       3
#define LCD_D3       2
#define LCD_EN       6                //PWM pin
#define LCD_RS       7
#define led13       10

#define DISPLAY_WIDTH 16
#define DISPLAY_HEIGHT 2

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D0,LCD_D1,LCD_D2,LCD_D3);


uint8_t inascii=0;                     // set to 1 if reading ascii data

// Mapping table maps incoming characters - this needs work and verifying
#define MAP_SIZE 62
PROGMEM prog_uchar cmap[MAP_SIZE*2] = {
   		0x67, 0xE7,             0x6A, 0xEA,		0x70, 0xF0,		0x71, 0xF1,		0x79, 0xF9,
		0xE4, 0xE1,		0xF1, 0xEE,		0xF6, 0xEF,		0xFC, 0xF5,
		//accented -> plain equivalent and misc symbol translation
		0xA3, 0xED,		0xB0, 0xDF,		0xB5, 0xE4,		0xC0, 0x41,		0xC1, 0x41,
		0xC2, 0x41,		0xC3, 0x41,		0xC4, 0x41,		0xC5, 0x41,		0xC8, 0x45,
		0xC9, 0x45,		0xCA, 0x45,		0xCB, 0x45,		0xCC, 0x49,		0xCD, 0x49,
		0xCE, 0x49,		0xCF, 0x49,		0xD1, 0x43,		0xD2, 0x4F,		0xD3, 0x4F,
		0xD4, 0x4F,		0xD5, 0x4F,		0xD6, 0x4F,		0xD8, 0x4F,		0xD9, 0x55,
		0xDA, 0x55,		0xDB, 0x55,		0xDC, 0x55,		0xDD, 0x59,		0xDF, 0xE2,
		0xE0, 0x61,		0xE1, 0x61,		0xE2, 0x61,		0xE3, 0x61,		0xE5, 0x61,
		0xE7, 0x63,		0xE8, 0x65,		0xE9, 0x65,		0xEA, 0x65,		0xEB, 0x65,
		0xEC, 0x69,		0xED, 0x69,		0xEE, 0x69,		0xEF, 0x69,		0xF2, 0x6F,
		0xF3, 0x6F,		0xF4, 0x6F,		0xF5, 0x6F,		0xF8, 0x6F,		0xF7, 0xFD,
		0xF9, 0x75,		0xFA, 0x75,		0xFB, 0x75
};



//=============================================================================================
// setup code called at power up or reset
//=============================================================================================
void setup() 
{ int i;

  // Set up serial devices
  Serial.begin(9600);                       // Open serial communications for debug messages
  // ---------------- Set up the LCD ---------------------------------------
  lcd.begin(DISPLAY_WIDTH, DISPLAY_HEIGHT);  // set up the LCD's number of columns and rows 16x2
  lcd.clear();                               // clear the LCD
  lcd.print(F("**LCD  SMARTIE**"));          // Print a message to the LCD
  lcd.setCursor(3,1);
  lcd.print(F("on Arduino"));                // Print a message to the LCD
  
  Serial.println(F("----------- Setup Complete -------------"));
}



//=============================================================================================
// Main program continually called till power off
// note: an http request ends with a blank line
//=============================================================================================
void loop() 
{  
  // ------------------ Check for commands from the serial port -------------------------------------
  if (Serial.available()>0) 
    { uint8_t c = 0;
      c = Serial.read();
      digitalWrite(led13,1);
      emulate_matrix_orbital(c);
      digitalWrite(led13,0);
    }

  delay(5);
}  



//=======================================================================================================
// routine to wait and get the next character
//=======================================================================================================
byte nextch()
{ while (Serial.available()==0) delay(5);       // Wait for the next character
      return (byte) (Serial.read() & 0xff);     // read the incoming byte
}


//=======================================================================================================
// routine to wait and get the next byte
// You can maunally type in characters on the console using the format [FE 47 01 00]
//
//=======================================================================================================
byte nextb()
{ byte c,d;

  if (inascii==0) return nextch();           // read the next byte as a byte if we are not in ascii mode
  
  c=nextch()-'0'; if (c>9) c=c+'0'-'A'+10;  // read 2 digit hex as the byte
  d=nextch()-'0'; if (d>9) d=d+'0'-'A'+10;  //
  nextch();                                 // ignore , or ], or \n
  return (((c*16)+d) & 0xff); 
}


//=======================================================================================================
// routine to emulate the matrix orbital commands
//=======================================================================================================
void emulate_matrix_orbital(uint8_t c)
{ uint8_t rxbyte=c;
  uint8_t i;
  uint8_t chars[8];
  uint8_t num;

#define CASE break; case 

// Uncomment the following for debugging
//  if (rxbyte == '[')                                             // Ascii commands sent
//    { inascii=1;                                                 // set ascii mode
//      rxbyte=nextb();                                            // read the next byte
//    }
//  else inascii=0;                                                // else we are in binary mode
    
  if (rxbyte == 0xFE)                                            // Matrix Orbital uses 254 prefix for commands
    { while (rxbyte == 0xFE) { rxbyte = nextb(); }               // ignore multiple 0xFE's
      switch (rxbyte)
        { case 0:                                                // ignore nulls
          CASE 0x23:                                             // Read serial number (or place large number)
          CASE 0X24:                                             // Read version number
          CASE 0X26:                                             // Poll key presses
          CASE 0X33:                                             // Change I2C slave address (1 parameter, address)
          CASE 0X36: Serial.print(VERSION);                      // Read version number
          CASE 0X37: Serial.print(9);                            // Read module type (9 for LK204-25)
          CASE 0X39:                                             // Change baud rate (1 parameter, baud rate)
          CASE 0X3B:                                             // Exit flow-control mode
          CASE 0X3D: nextb(); nextb();                           // Place vertical bar (2 parameters, column, length)
          CASE 0X40:                                             // Change the startup screen (followed by 32 or whatever chars)
          CASE 0X41:                                             // Auto transmit keypresses on
          CASE 0x42: nextb();                                    // ignore time character
//                     analogWrite(backlight_pin, 180);            // Set the backlight on (at previously set brightness)
          CASE 0X43:                                             // Auto line wrap on
          CASE 0X44:                                             // Auto line wrap off
          CASE 0X45:                                             // Clear key buffer
	  CASE 0x46: //analogWrite(backlight_pin, 255);            // Set the backlight off
	  CASE 0x47: lcd.setCursor(nextb()-1,nextb()-1);         // set cursor position
	  CASE 0x48: lcd.home();                                 // cursor home (reset display position)
	  CASE 0x4A: lcd.cursor();                               // show underline cursor
	  CASE 0x4B: lcd.noCursor();                             // underline cursor off
	  CASE 0x4C: lcd.command(16);                            // move cursor left
	  CASE 0x4D: lcd.command(20);                            // move cursor right
	  CASE 0x4E: num=nextb();                                // define custom char num
                     for (i=0; i<8; i++) chars[i]=nextb();       // Bit patterns
                     lcd.createChar(num,chars);
          CASE 0X4F:                                             // Auto transmit keypress off
	  CASE 0x50: nextb(); //analogWrite(contrast_pin, 256-nextb());     // Set the contrast value (0-255) from the variable (0-100)
          CASE 0X51: lcd.autoscroll();                           // Auto scroll on
          CASE 0X52: lcd.noAutoscroll();                         // Auto scroll off
	  CASE 0x53: lcd.blink();                                // show blinking block cursor
	  CASE 0x54: lcd.noBlink();                              // hide blinking block cursor
          CASE 0X55:                                             // Set debounce time (1 paramater, time)
          CASE 0X56: nextb(); // if (nextb() == 1) digitalWrite(GPO1, LOW);  // General Purpose Output off (1 parameter, number)
          CASE 0X57: nextb(); // if (nextb() == 0) digitalWrite(GPO1, HIGH); // General Purpose Output on (1 parameter, number)
	  CASE 0x58: lcd.clear();                                // clear display, cursor home
 	  CASE 0x5B: lcd.noCursor();                             // cursor off
          CASE 0X60:                                             // Auto repeat mode off
          CASE 0X68:                                             // Initialize horizontal bar
          CASE 0X6D:                                             // Initialize medium number
          CASE 0X6E:                                             // Initialize lange numbers
          CASE 0X6F:                                             // Place medium numbers
          CASE 0X73:                                             // Initialize narrow vertical bar
          CASE 0X76:                                             // Initialize wide vertical bar
          CASE 0X7C:                                             // Place horizontal bar graph (4 parameters, column, row, direction, length)
          CASE 0X7E:                                             // Set auto repeat mode (1 parameter, mode)
	  CASE 0x91: nextb(); // analogWrite(contrast_pin, 256-nextb());     // Set the contrast value (0-255) and remember from the variable (0-100)
 	  CASE 0x98: nextb(); // analogWrite(backlight_pin, nextb());        // Set the backlight value (0-255)and remember (doesn't save value, though)
  	  CASE 0x99: nextb(); // analogWrite(backlight_pin, nextb());        // Set the backlight value (0-255) from the variable (0-100)
          CASE 0XA0:                                             // Transmission protocol select (1 parameter, protocol)
          CASE 0XA4:                                             // Setting a non-standart baudrate (1 parameter, speed)
          CASE 0XC0:                                             // Load custom characters (1 parameter, bank)
          CASE 0XC1:                                             // Save custom character (3 parameters, bank, id, data)
          CASE 0XC2:                                             // Save startup screen custom characters (2 parameters, id, data)
          CASE 0XC3:                                             // Set startup GPO state (2 parameters, number, state)
          CASE 0XC8: switch (nextb())                            // Dallas 1-Wire
                        {  case 1:                               // Dallas 1-Wire transaction (6 parameters, flags, send, bits, receive, bits, data)
                           case 2:                               // Search for a 1-Wire device
                           default: break;
                         }
          CASE 0XD5: break;                                      // Assign keypad codes
  	  default:   break;                                      // all other commands ignored and parameter byte discarded
	}
    } 
  else if (rxbyte!='\n')                                         // ignore newline characters
    { // change accented char to plain, detect and change descenders
      for (i=0; i<MAP_SIZE;i++)
        { if (rxbyte==pgm_read_byte_near(cmap + (i*2))) 
           { rxbyte=pgm_read_byte_near(cmap + (i*2+1)); break; }  // if we find it change it 
        } 
      lcd.print((char)rxbyte);                                    // print the character on the lcd 
    }
}


limbo
Plugin Author
Posts: 1604
Joined: February 13th, 2005, 7:38 pm
Location: Athens - Greece
Contact:

Re: x64 without LPT onboard

Post by limbo »

Oh thanks !
I will give it a try ASAP... :P

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

Limbo,
the code is for a normal LCD but won't work for the 4x40 since it has 2 controllers. If you specifically need that code let me know.

limbo
Plugin Author
Posts: 1604
Joined: February 13th, 2005, 7:38 pm
Location: Athens - Greece
Contact:

Re: x64 without LPT onboard

Post by limbo »

dperrow wrote:Limbo,
the code is for a normal LCD but won't work for the 4x40 since it has 2 controllers. If you specifically need that code let me know.
i would be grateful if you could upload this code as well (or send it by PM if don't like to do it in public)

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

Hi Limbo,
I've included the code below. It's a bit of a hack but it does work and I use it on my Media PC. If you find any bugs 9and i'm sure there are some) or make any mods please let me know.

Code: Select all

/*
  serial_lcd_4x40_smartie - an ethernet or serial based LCD Smartie sketch
  Note that the ethernet code has been ommitted from this version
 
 Based on a simple HD44780 based LCD Display driver
 Lots of code copied from the LiquidCrystal library
 
 Dave Perrow January 2014
 
 Connections:
 * On UNO (these pins used so that the ethernet shield and the LCD can co-exist and are my choice and cable colours of a ribbon)
 * LCD RW(GREEN) is connected to gnd, RS (BLUE) is on pin 19(A5), EN (Enable)(YELLOW) on 18(A4),
 *                 D4 (ORANGE)on 17 (A03), D5 (RED) on 16(A2), D6 (BROWN)on 15(A1), D7 (BLACK) on 14(A0)
 * LCD CONTRAST (V0 OR VEE)(PURPLE) CONNECTED TO PIN 5 (PWM) WITH 100uF cap between pin 5 and gnd or not
 * VSS (WHITE)to gnd, VDD(VCC)(GREY) to +5v, L+ (WHITE)to +Vin (**** only if usb powered)
 * LCD (L-)(GREY) Backlight on pin 6 (PWM) via transistor amp (BC639) or not
 *
 * Note this only works with a USB power source because i'm using Vin to the backlight. 
 * It'll probably blow up if you use an external power source.
 *
 * JMD 162A
LCM	Color	Signal	Arduino
1	White	VSS	Gnd
2	Grey	VCC	+5v
3	Purple	VEE	D5
4	Blue	RS	A5
5	Green	R/W	Gnd
6	Yellow	E	A4
7	nc	DB0	nc
8	nc	DB1	nc
9	nc	DB2	nc
10	nc	DB3	nc
11	Orange	DB4	A3
12	Red	DB5	A2
13	Brown	DB6	A1
14	Black	DB7	A0
15	White	LED+	Vin
16	Grey	LED-	D6
			
40x4	Signal	Color	Arduino
1	DB7	Black	A3
2	DB6	Brown	A2
3	DB5	Red	A1
4	DB4	Orange	A0
5	DB3	nc	nc
6	DB2	nc	nc
7	DB1	nc	nc
8	DB0	nc	nc
9	E1	Yellow	A4
10	R/W	Green	Gnd
11	RS	Blue	A5
12	V0	Purple	D5
13	VSS	White	Gnd
14	VDD	Grey	+5v
15	E2	purple	D7
16	nc	nc	nc
17	LED+	White	Vin
18	LED-	Grey	D6

*/


#include <Arduino.h>

#define VERSION "1.01"

//---------------------------------------------------------------------------------------------
// LCDdetailed stuff
//---------------------------------------------------------------------------------------------
// commands
#define LCD_CLEARDISPLAY        0x01
#define LCD_RETURNHOME          0x02
#define LCD_ENTRYMODESET        0x04
#define LCD_DISPLAYCONTROL      0x08
#define LCD_CURSORSHIFT         0x10
#define LCD_FUNCTIONSET         0x20
#define LCD_SETCGRAMADDR        0x40
#define LCD_SETDDRAMADDR        0x80

// flags for display entry mode
#define LCD_ENTRYRIGHT          0x00
#define LCD_ENTRYLEFT           0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00

// flags for display on/off control
#define LCD_DISPLAYON           0x04
#define LCD_DISPLAYOFF          0x00
#define LCD_CURSORON            0x02
#define LCD_CURSOROFF           0x00
#define LCD_BLINKON             0x01
#define LCD_BLINKOFF            0x00

// flags for display/cursor shift
#define LCD_DISPLAYMOVE         0x08
#define LCD_CURSORMOVE          0x00
#define LCD_MOVERIGHT           0x04
#define LCD_MOVELEFT            0x00

// flags for function set
#define LCD_4BITMODE            0x00
#define LCD_2LINE               0x08
#define LCD_5x10DOTS            0x04
#define LCD_5x8DOTS             0x00

//---------------------------------------------------------------------------------------------
// LCD & LED pin configs
//---------------------------------------------------------------------------------------------
#define LCDPORT                 PORTC
#define LCDDDR                  DDRC
#define LCDBITS                 B00111111
#define DATAMASK                B11110000 
#define RSBITS                  B00100000
#define RSMASK                  B11011111
#define ENBITS                  B00010000 
#define ENMASK                  B11101111
#define E2                      7            // Enable pin for bottom 2 lines of display

#define backlight_pin           6            // LCD Backlight pin (PWM)
#define contrast_pin            5            // LCD Contrast pin (PWM)
#define led13                   13           // Pin 13 has an LED connected on most Arduino boards. So give it a name:
#define GPO1                    12           // GPO pin

#define DISPLAY_WIDTH           40
#define DISPLAY_HEIGHT          4

// Mapping table maps incoming characters - this needs work and verifying
unsigned char cmap[] = {
   		0x67, 0xE7,             0x6A, 0xEA,		0x70, 0xF0,		0x71, 0xF1,		0x79, 0xF9,
		0xE4, 0xE1,		0xF1, 0xEE,		0xF6, 0xEF,		0xFC, 0xF5,
		//accented -> plain equivalent and misc symbol translation
		0xA3, 0xED,		0xB0, 0xDF,		0xB5, 0xE4,		0xC0, 0x41,		0xC1, 0x41,
		0xC2, 0x41,		0xC3, 0x41,		0xC4, 0x41,		0xC5, 0x41,		0xC8, 0x45,
		0xC9, 0x45,		0xCA, 0x45,		0xCB, 0x45,		0xCC, 0x49,		0xCD, 0x49,
		0xCE, 0x49,		0xCF, 0x49,		0xD1, 0x43,		0xD2, 0x4F,		0xD3, 0x4F,
		0xD4, 0x4F,		0xD5, 0x4F,		0xD6, 0x4F,		0xD8, 0x4F,		0xD9, 0x55,
		0xDA, 0x55,		0xDB, 0x55,		0xDC, 0x55,		0xDD, 0x59,		0xDF, 0xE2,
		0xE0, 0x61,		0xE1, 0x61,		0xE2, 0x61,		0xE3, 0x61,		0xE5, 0x61,
		0xE7, 0x63,		0xE8, 0x65,		0xE9, 0x65,		0xEA, 0x65,		0xEB, 0x65,
		0xEC, 0x69,		0xED, 0x69,		0xEE, 0x69,		0xEF, 0x69,		0xF2, 0x6F,
		0xF3, 0x6F,		0xF4, 0x6F,		0xF5, 0x6F,		0xF8, 0x6F,		0xF7, 0xFD,
		0xF9, 0x75,		0xFA, 0x75,		0xFB, 0x75
};

uint8_t _displayfunction;
uint8_t _displaycontrol;
uint8_t _displaymode;
uint8_t _initialized;
uint8_t _numlines;
uint8_t _currline;
uint8_t _currcol;
uint8_t _epin;


//=============================================================================================
// setup code called at power up or reset
//=============================================================================================
void setup() 
{ int i;

  // Set up serial devices
  Serial.begin(9600);                        // Open serial communications for debug messages
  pinMode(contrast_pin, OUTPUT);             // Set the contrast pin to an output
  analogWrite(contrast_pin, 0);              // set the contrast value (0-255) from the variable (0-100)
  pinMode(backlight_pin, OUTPUT);            // Set the backlight pin to an output
  analogWrite(backlight_pin, 0);             // Set the backlight value (0-255) from the variable (0-100)

  // ---------------- Set up the LED's and other outputs --------------------
  pinMode(led13,OUTPUT);                     // initialize the digital pin for the on-board led as an output.
  pinMode(GPO1, OUTPUT);                     // initialize the digital pin for the on-board led as an output.
  
  // ---------------- Set up the LCD ---------------------------------------
  LCD_init();                                // set up the LCD
  LCD_setCursor(23,1);
  LCD_print("**LCD  SMARTIE**");             // Print a message to the LCD
  LCD_setCursor(22,2);
  LCD_print("on Arduino Uno v");             // Print a message to the LCD
  LCD_print(VERSION);                        // Print a message to the LCD
}



//=============================================================================================
// Main program continually called till power off
// Check for commands from the serial port
//=============================================================================================
void loop() 
{  if (Serial.available()>0) { digitalWrite(led13,1); emulate(Serial.read()); digitalWrite(led13,0); } }  

//=======================================================================================================
// routine to wait and get the next character
//=======================================================================================================
byte nextb()
{  while (Serial.available()==0) delay(2);   // Wait for the next character
   return (byte) (Serial.read() & 0xff);     // read the incoming byte
}

//=======================================================================================================
// routine to emulate the matrix orbital commands
//=======================================================================================================
void emulate(uint8_t c)
{ uint8_t rxbyte=c;
  uint8_t i;
  uint8_t chars[8];
  uint8_t num;

#define CASE break; case 

  if (rxbyte == 0xFE)                                            // Matrix Orbital uses 254 prefix for commands
    { while (rxbyte == 0xFE) { rxbyte = nextb(); }               // ignore multiple 0xFE's
      switch (rxbyte)
        { case 0:                                                // ignore nulls
          CASE 0x23:                                             // Read serial number (or place large number)
          CASE 0X24:                                             // Read version number
          CASE 0X26:                                             // Poll key presses
          CASE 0X33:                                             // Change I2C slave address (1 parameter, address)
          CASE 0X36: Serial.print(VERSION);                      // Read version number
          CASE 0X37: Serial.print(9);                            // Read module type (9 for LK204-25)
          CASE 0X39:                                             // Change baud rate (1 parameter, baud rate)
          CASE 0X3B:                                             // Exit flow-control mode
          CASE 0X3D: nextb(); nextb();                           // Place vertical bar (2 parameters, column, length)
          CASE 0X40:                                             // Change the startup screen (followed by 32 or whatever chars)
          CASE 0X41:                                             // Auto transmit keypresses on
          CASE 0x42: nextb();                                    // ignore time character
                     analogWrite(backlight_pin, 180);            // Set the backlight on (at previously set brightness)
          CASE 0X43:                                             // Auto line wrap on
          CASE 0X44:                                             // Auto line wrap off
          CASE 0X45:                                             // Clear key buffer
	  CASE 0x46: analogWrite(backlight_pin, 255);            // Set the backlight off
	  CASE 0x47: LCD_setCursor(nextb()-1,nextb()-1);         // set cursor position
	  CASE 0x48: LCD_home();                                 // cursor home (reset display position)
	  CASE 0x4A: LCD_cursor();                               // show underline cursor
	  CASE 0x4B: LCD_noCursor();                             // underline cursor off
	  CASE 0x4C: LCD_command(16);                            // move cursor left
	  CASE 0x4D: LCD_command(20);                            // move cursor right
	  CASE 0x4E: num=nextb();                                // define custom char num
                     for (i=0; i<8; i++) chars[i]=nextb();       // Bit patterns
                     LCD_createChar(num,chars);
          CASE 0X4F:                                             // Auto transmit keypress off
	  CASE 0x50: analogWrite(contrast_pin, 256-nextb());     // Set the contrast value (0-255) from the variable (0-100)
          CASE 0X51: LCD_autoscroll();                           // Auto scroll on
          CASE 0X52: LCD_noAutoscroll();                         // Auto scroll off
	  CASE 0x53: LCD_blink();                                // show blinking block cursor
	  CASE 0x54: LCD_noBlink();                              // hide blinking block cursor
          CASE 0X55:                                             // Set debounce time (1 paramater, time)
          CASE 0X56: if (nextb() == 1) digitalWrite(GPO1, LOW);  // General Purpose Output off (1 parameter, number)
          CASE 0X57: if (nextb() == 0) digitalWrite(GPO1, HIGH); // General Purpose Output on (1 parameter, number)
	  CASE 0x58: LCD_clear();                                // clear display, cursor home
 	  CASE 0x5B: LCD_noCursor();                             // cursor off
          CASE 0X60:                                             // Auto repeat mode off
          CASE 0X68:                                             // Initialize horizontal bar
          CASE 0X6D:                                             // Initialize medium number
          CASE 0X6E:                                             // Initialize lange numbers
          CASE 0X6F:                                             // Place medium numbers
          CASE 0X73:                                             // Initialize narrow vertical bar
          CASE 0X76:                                             // Initialize wide vertical bar
          CASE 0X7C:                                             // Place horizontal bar graph (4 parameters, column, row, direction, length)
          CASE 0X7E:                                             // Set auto repeat mode (1 parameter, mode)
	  CASE 0x91: analogWrite(contrast_pin, 256-nextb());     // Set the contrast value (0-255) and remember from the variable (0-100)
 	  CASE 0x98: analogWrite(backlight_pin, nextb());        // Set the backlight value (0-255)and remember (doesn't save value, though)
  	  CASE 0x99: analogWrite(backlight_pin, nextb());        // Set the backlight value (0-255) from the variable (0-100)
          CASE 0XA0:                                             // Transmission protocol select (1 parameter, protocol)
          CASE 0XA4:                                             // Setting a non-standart baudrate (1 parameter, speed)
          CASE 0XC0:                                             // Load custom characters (1 parameter, bank)
          CASE 0XC1:                                             // Save custom character (3 parameters, bank, id, data)
          CASE 0XC2:                                             // Save startup screen custom characters (2 parameters, id, data)
          CASE 0XC3:                                             // Set startup GPO state (2 parameters, number, state)
          CASE 0XC8: switch (nextb())                            // Dallas 1-Wire
                        {  case 1:                               // Dallas 1-Wire transaction (6 parameters, flags, send, bits, receive, bits, data)
                           case 2:                               // Search for a 1-Wire device
                           default: break;
                         }
          CASE 0XD5: break;                                      // Assign keypad codes
  	  default:   break;                                      // all other commands ignored and parameter byte discarded
	}
    } 
  else if ((rxbyte!='\n') && (rxbyte!=0))                         // ignore newline and null characters
    { // do any character mapping required.
      for (i=0; i<(sizeof(cmap)/2); i++)
        { if (rxbyte==cmap[i*2]) { rxbyte=cmap[i*2+1]; break; } }  // if we find it change it 
      LCD_write((char)rxbyte);                                     // print the character on the lcd 
    }
}




// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set: 
//    DL = 1; 8-bit interface data 
//    N = 0; 1-line display 
//    F = 0; 5x8 dot character font 
// 3. Display on/off control: 
//    D = 0; Display off 
//    C = 0; Cursor off 
//    B = 0; Blinking off 
// 4. Entry mode set: 
//    I/D = 1; Increment by 1 
//    S = 0; No shift 
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts.
//
void LCD_init(void)
{
  LCDDDR = LCDDDR | LCDBITS;            //  set all bits as outputs
  _displayfunction = LCD_4BITMODE | LCD_5x8DOTS;
  _epin=0;
  pinMode(E2, OUTPUT);       
  digitalWrite(E2, LOW);        

  _displayfunction |= LCD_2LINE;
  _numlines = 4;
  _currline = 0; _currcol=0;

  // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
  // according to datasheet, we need at least 40ms after power rises above 2.7V
  // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
  delayMicroseconds(50000); 
  // Now we pull both RS and R/W low to begin commands
  LCDPORT = LCDPORT & RSMASK;      // digitalWrite(_rs_pin, LOW);
  LCDPORT = LCDPORT & ENMASK;      // digitalWrite(_enable_pin, LOW);
  
  // put the LCD into 4 bit mode according to the hitachi HD44780 datasheet 
  // figure 24, pg 46 we start in 8bit mode, try to set 4 bit mode
  for (uint8_t i=0; i<2; i++)
    { _epin=i;
      LCD_write4bits(0x03);
      delayMicroseconds(4500);        // wait min 4.1ms
      LCD_write4bits(0x03);           // second try
      delayMicroseconds(4500);        // wait min 4.1ms
      LCD_write4bits(0x03);           // third go!
      delayMicroseconds(150);
      LCD_write4bits(0x02);           // finally, set to 4-bit interface
      LCD_command(LCD_FUNCTIONSET | _displayfunction);   // finally, set # lines, font size, etc.

      // turn the display on with no cursor or blinking default
      _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
      LCD_display();
      LCD_clear();                    // clear it off

      // Initialize to default text direction (for romance languages)
      _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
      LCD_command(LCD_ENTRYMODESET | _displaymode);    // set the entry mode
    }
  _epin=0;
}



/********** high level commands, for the user! */
// Clear the display
void LCD_clear()
{ _epin=0; LCD_command(LCD_CLEARDISPLAY);  delayMicroseconds(2000); // clear display, set cursor position to zero. note this command takes a long time!
  _epin=1; LCD_command(LCD_CLEARDISPLAY);  delayMicroseconds(2000); // clear display, set cursor position to zero. note this command takes a long time!
  _epin=0; _currline=0; _currcol=0;
}

// Home
void LCD_home()
{ _epin=0; LCD_command(LCD_RETURNHOME);  delayMicroseconds(2000);  // set cursor position to zero. note this command takes a long time!
  _currline=0; _currcol=0;
}

// Set cursor position
void LCD_setCursor(uint8_t col, uint8_t row)
{ int row_offsets[] = { 0, 0x40, 0, 0x40 };

  if ( row >= _numlines ) row = _numlines-1;                       // we count rows starting w/0
  _epin=0; if (row>1) _epin=1;
  LCD_command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
  _currline=row; _currcol=col;
}


void LCD_command_both(uint8_t value) {uint8_t e=_epin;  for (_epin=0; _epin<2; _epin++) LCD_command(value); _epin=e; }         // Send command to both chips
void LCD_noDisplay() { _displaycontrol &= ~LCD_DISPLAYON; LCD_command_both(LCD_DISPLAYCONTROL | _displaycontrol); }            // Turn the display off (quickly)
void LCD_display()   { _displaycontrol |= LCD_DISPLAYON;  LCD_command_both(LCD_DISPLAYCONTROL | _displaycontrol); }            // Turn the display on (quickly)
void LCD_noCursor() { _displaycontrol &= ~LCD_CURSORON;   LCD_command_both(LCD_DISPLAYCONTROL | _displaycontrol); }            // Turns the underline cursor off
void LCD_cursor()   { _displaycontrol |= LCD_CURSORON;    LCD_command_both(LCD_DISPLAYCONTROL | _displaycontrol); }            // Turns the underline cursor on
void LCD_noBlink()  { _displaycontrol &= ~LCD_BLINKON;    LCD_command_both(LCD_DISPLAYCONTROL | _displaycontrol); }            // Turn off the blinking cursor
void LCD_blink()    { _displaycontrol |= LCD_BLINKON;     LCD_command_both(LCD_DISPLAYCONTROL | _displaycontrol); }            // Turn on the blinking cursor
void LCD_scrollDisplayLeft(void)  { LCD_command_both(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); }                      // Scroll the display left without changing the RAM
void LCD_scrollDisplayRight(void) { LCD_command_both(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); }                     // Scroll the display right without changing the RAM
void LCD_leftToRight(void)  { _displaymode |= LCD_ENTRYLEFT;  LCD_command_both(LCD_ENTRYMODESET | _displaymode); }             // This is for text that flows Left to Right
void LCD_rightToLeft(void)  { _displaymode &= ~LCD_ENTRYLEFT; LCD_command_both(LCD_ENTRYMODESET | _displaymode); }             // This is for text that flows Right to Left
void LCD_autoscroll(void)   { _displaymode |= LCD_ENTRYSHIFTINCREMENT;  LCD_command_both(LCD_ENTRYMODESET | _displaymode); }   // This will 'right justify' text from the cursor
void LCD_noAutoscroll(void) { _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; LCD_command_both(LCD_ENTRYMODESET | _displaymode); }   // This will 'left justify' text from the cursor

// This allows us to fill the first 8 CGRAM locations with custom characters
void LCD_createChar(uint8_t location, uint8_t charmap[]) 
{ uint8_t e=_epin;
  for (_epin=0; _epin<2; _epin++) { LCD_command(LCD_SETCGRAMADDR | ((location &0x7) << 3)); for (int i=0; i<8; i++) LCD_write(charmap[i]); }
  _epin=e;
}

/*********** mid level commands, for sending data/cmds */
inline void LCD_command(uint8_t value) { LCD_send(value, LOW); }
inline size_t LCD_write(uint8_t value) { LCD_send(value, HIGH); return 1; }  // assume sucess

void LCD_print(char *s) 
{ uint8_t lc=_currline;
  for (uint8_t i=0; s[i]!=0; i++) 
    { LCD_write((uint8_t)s[i]); 
      _currcol++; 
      if (_currcol>39) 
        { _currcol=0; _currline++; 
          if (_currline>=_numlines) _currline=0;
            { if (_currline>1) _epin=1; else _epin=0;
              if (lc!=_currline) LCD_setCursor(_currcol,_currline);
            }
        }
    }
}

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

// write either command or data, with automatic 4/8-bit selection
void LCD_send(uint8_t value, uint8_t mode) 
{ if (mode==0) LCDPORT = LCDPORT & RSMASK; else LCDPORT = LCDPORT | RSBITS;
  LCD_write4bits(value>>4);
  LCD_write4bits(value);
}

void LCD_write4bits(uint8_t value) 
{ LCDPORT = LCDPORT & DATAMASK;
  LCDPORT = LCDPORT | (value & 0x0F);
  delayMicroseconds(1);    

  if (_epin==0)
    {  LCDPORT = LCDPORT & ENMASK; delayMicroseconds(1);   // digitalWrite(_enable_pin, LOW);
       LCDPORT = LCDPORT | ENBITS; delayMicroseconds(1);   // digitalWrite(_enable_pin, HIGH); // enable pulse must be >450ns
       LCDPORT = LCDPORT & ENMASK; delayMicroseconds(200); // digitalWrite(_enable_pin, LOW);  // commands need > 37us to settle
    }
  else
    {  digitalWrite(E2,LOW);  delayMicroseconds(1);        // digitalWrite(_enable_pin, LOW);
       digitalWrite(E2,HIGH); delayMicroseconds(1);        // digitalWrite(_enable_pin, HIGH); // enable pulse must be >450ns
       digitalWrite(E2,LOW);  delayMicroseconds(200);      // digitalWrite(_enable_pin, LOW);  // commands need > 37us to settle
    }
}


limbo
Plugin Author
Posts: 1604
Joined: February 13th, 2005, 7:38 pm
Location: Athens - Greece
Contact:

Re: x64 without LPT onboard

Post by limbo »

Thank you! :smt023

hurley
Posts: 46
Joined: May 26th, 2011, 8:03 am

Re: x64 without LPT onboard

Post by hurley »

Thanks for this code Dave. !!
I managed to revive my old busted LCD and run it from Arduino (Nano) with your code, which enabled me to properly debug some plugin code I'm working on.
I commented out the re-mapping though because it gave me un-expected results.
Is it common for drivers/intermediate code to do remapping like this or was it just for your application?
My plugin depends in part on being able to display the expected character for any given $Chr(xxx) 'address' in the users CGROM Table.

With a few tweaks the Matrix Orbital code should be able to run my new OLED, I'm looking forward to that moment!
Arduino's not so daunting anymore. :)
Cheers.

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

Hi Hurley,
Glad I managed to make the Arduino less daunting for you :D

The mapping code came from the original HD44780 code. It's quite common to do remapping like this but if you don't need it then it's right to comment it out or delete it.

Good luck,
Dave

chan nyein

Re: x64 without LPT onboard

Post by chan nyein »

Hello dperrow

I am newbies on arduino and Lcd smarties. I have SAMSUNG UC-40401 40x4 Lcd and try to connect to arduino. The pinout are confuse to me. When I connect A0 to A5, the board cannot power up. Do you have a schematic for connection? I know this topic is 4 years old and my chances are very slim. Thanks.

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

Had a look at a datasheet for this LCD and it looks like it has a non-standard pinout. I've mapped what I think the pins are and come up with this:

Code: Select all

Arduino Pin    LCD  	Symbol	Function
GND	               1	Vss 	Ground               
+5V	               2	Vdd 	+5V                  
D5	               3	Vo  	LCD contrast adjust  
A5	               4	RS  	Register-select      
Gnd	               5	R/W 	Read/write           
A4	               6	E1  	U1-Enable            
D7	               7	E2  	U2-Enable            
nc	               8	DB0 	Data bit 0           
nc	               9	DB1 	Data bit 1           
nc	             10	DB2 	Data bit 2           
nc	             11	DB3 	Data bit 3           
A0	             12	DB4 	Data bit 4           
A1	             13	DB5 	Data bit 5           
A2	             14	DB6 	Data bit 6           
A3	             15	DB7 	Data bit 7           
nc	             16	NC  	                     
Vin	             17/+	BL+ 	Power Supply for BL+ 
D6	             18/-	BL- 	Power Supply for BL- 

I found the datasheet in a PDF here: http://www.manmullsang.com/bbs/board.ph ... wr_id=1692

Hope this helps.

chan nyein

Re: x64 without LPT onboard

Post by chan nyein »

Thanks, the pins are ok. I can see welcome screen. But when I open Lcd Smarties program, only first row work, the rest 3 rows show unknown characters and freeze.

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

What do you mean by the welcome screen? Is this just the LCD's own welcome screen or is Smartie driving the top line only?

chan nyein

Re: x64 without LPT onboard

Post by chan nyein »

When the arduino power up, it clear the screen. And the message " **LCD SMARTIE** " appears at line 2 and "on Arduino Uno v1.1" at line 3, I think it is like a welcome screen.

LCD_init(); // set up the LCD
LCD_setCursor(10,1);
LCD_print("**LCD SMARTIE**"); // Print a message to the LCD
LCD_setCursor(10,2);
LCD_print("on Arduino Uno v"); // Print a message to the LCD
LCD_print(VERSION);


If I open Lcd Smarties program, first line of the program appears at line 1 of lcd. The rest 3 lines show unknown characters and freeze.
Image
Image

chan nyein

Re: x64 without LPT onboard

Post by chan nyein »

I can't post the photos.

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

I think you need to check the settings in LCD Smartie. You could send me a copy of your config.ini file.

Things to check on the setup screen are:

startup parameters (yours might be a different com port): COM3,9600,8,N,1
LCD Size is set correctly.
whats the display plugin set to?

channyein
Posts: 1
Joined: December 15th, 2018, 1:47 am

Re: x64 without LPT onboard

Post by channyein »

Hello dperrow

I send my .ini file in your pm box as txt file.

My parameters are: COM5,9600,8,N,1
LCD : 40x4
plugins: Perf Plugin

StaxCz

Re: x64 without LPT onboard

Post by StaxCz »

Works perfect..... but need programed on Arduino version 1.0

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

Can you explain further please.

StaxCZ

Re: x64 without LPT onboard

Post by StaxCZ »

The new Arduino 1.5.7 BETA has a few differences.

previous: prog_uchar
now: const unsigned char

dperrow
Plugin Author
Posts: 276
Joined: May 27th, 2011, 2:13 pm
Location: Stirling, Scotland

Re: x64 without LPT onboard

Post by dperrow »

Okay, thanks mate. I'm on Arduino ide v 1.8.9 but i have never needed to recompile this since posting it and it's been running in my media center ever since!

I changed what you suggested and it re-compiles okay now. Are there any other differences you think I should be aware of?

Did you have any other problem or were you just being helpful (and thanks BTW).

hydrolisk1792
Site Admin
Posts: 305
Joined: July 23rd, 2010, 8:32 pm
Location: Las Vegas, NV USA
Contact:

Re: x64 without LPT onboard

Post by hydrolisk1792 »

I tried to get this to work on a 20 pin 4x20 lcd and it only displays information on the first line of the display. I have been through all the run of the mill troubleshooting already and can not seem to get this to work correctly. Is there maybe something I am missing inside the arduino code? As others have stated on this thread before, I can see the **LCD SMARTIE** on Arduino displayed on line 1 and line 2 at the startup of the arduino. I'm using the Uno for this experiment.

Post Reply