Pages: 1 [2] 3   Go Down
Author Topic: LCD3Wire: a 3-wire driver for HD44780-based LCDs  (Read 5061 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the calling convention is almost identical except the declaration:

Code:
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 10);  //mosi = r/c filter, sck = pin8, enable = pin10

mosi is no longer declared as it is tied to the sck line.

One perameter that you need to watch is this line in lcd2wire.h:

Code:
#define LCD2WIRE_DLY    50      //lcd2wire's delay. Much be 5x or more of the rc's time constant to ensure reliable operations

It determines how long, in us, the code will wait to bring up / down the sck line to send a '1'/'0'. The code, as written, takes about 4us to send a '1' - and the sck line dips to about 3.5v on a 100k/110p filter (time constant of 11us), below my comfort for a logic '1'.

I didn't adjust the code as it worked on my first try. But you really want the rc filter's constant to be at least 5x that required to send a logic '1' (aka you want a r/c filter in this case similar to 100k/220p). And you want LCD2WIRE_DLY to be another 5x of that -> 100us.

Again, it works with all shift registers.

Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Again, some performance data using bill's code:

[all deleted]
« Last Edit: November 24, 2012, 04:15:10 pm by dhenry » Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use the same technique to reduce it to 1-wire. But you will find quickly that the transmission slows down exponentially.

Here is the demo code that I used to run bill's benchmark.

[all deleted]
« Last Edit: November 24, 2012, 04:15:35 pm by dhenry » Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19306
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@dhenry:

You can have two attachments in a single post.

Alternatively, the attachment can be a .zip file, so related files can be logically grouped. Then you could include a readme.txt file as well to help explain how to use the files.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2762
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dhenry,
The demo code you published is clearly from the LCDispeed sketch I posted.
You did give a slight attribution in the post; however,
LCDispeed is an open source copyrighted and licensed work under creative commons license 3.0
( CC BY-NC-SA 3.0 )

It was not intended to be freeware.
As such, please remove the posting, or at a minimum
restore the original copyright message from the original work.
(Restoring the entire leadin comment would be better)

I will also update the code to more clearly indicate the licensing and attribution requirements
which requires preserving the original copyright and attribution messages in derivative versions of the code.

--- bill
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not a problem, Bill. I have the post deleted, as well as the performance data generated by the code: I do not like including any copyright statement in my code, and don't like to publish performance data if I cannot publish the code.
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2762
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not a problem, Bill. I have the post deleted, as well as the performance data generated by the code: I do not like including any copyright statement in my code, and don't like to publish performance data if I cannot publish the code.

In this case it is not *your* code.
And while the license does have some restrictions, it does not restrict you from modifying or publishing the code.
It merely prevents you from removing or modifying the original licensing agreement and attribution
that comes with the code.

When the lead in header comment was removed,
the license agreement was removed, and essentially changed the code to "free ware"
with no attribution to the original author which is not permitted under the licensing terms.

While many people often violate these types of licensing terms,
these type of restrictions exist in pretty much all open source code.

--- bill
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That's why I cannot afford to use those "free" stuff, smiley
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19306
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Which library did you base it on? The one on this page:

http://arduino.cc/en/Reference/LiquidCrystal

... has this license:

Quote
The text of the Arduino reference is licensed under a Creative Commons Attribution-ShareAlike 3.0 License. Code samples in the reference are released into the public domain.

Here is that license: http://creativecommons.org/licenses/by-sa/3.0/

What is onerous about it? You can copy, adapt and make commercial use of it. You just have to attribute the original author, and if you redistribute, keep the terms of the license on the copies.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2762
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nick,
The licensing comments were actually with respect to a sketch not the library code.

With respect to the LiquidCrystal library, it is one of the worst examples in the Arduino libraries
with respect to copyright/licensing/attribution.
Yes there is a small notice on the Arduino LiquidCrystal site referring to Creative Commons licensing,
But there is nothing in the actual source files, not even a reference in the source back to the
Arduino LiquidCrystal web page.

So as far as the actual LiquidCrystal library source goes, the LiquidCrystal code and examples
appear to be distributed as free-ware since there are no copyright or licensing notices.
i.e. someone receiving the library source code in its original form, would have no idea
of any sort of associated copyrights or licensing or even who the author is
from looking at the source code which all they would have.

The authors have failed to take even basic steps to preserve their copyrights
by not including the necessary information in the source code itself
or some sort of readme or license file that is distributed with the source.

Nearly all the other libraries have properly properly delt with this.
wifi and stepper are close runners up to LiquidCrystal in that they don't have
proper copyright and licensing notices.

Most of the others are LGPL 2.1 but SD may be a bit of a surprise for many people in that
it is GPL v3 which requires that any source that use it be open source.
This means that the SD library cannot be used in closed source projects/products.
While I like this, many folks do not.

--- bill
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The authors have failed to ...

Or maybe they just don't care: if I were to release something into the public, I don't want to put any restrictions on anyone using it - or I wouldn't have released to the public.

If I cannot use a piece of code in a way that I see fit, I have no use for it: I am not in the business of furthering someone's claims on anything.
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19306
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The stuff I release states that you can use it as you see fit. You just can't claim that you wrote it, nor apply extra restrictions on it that I didn't have.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2762
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The authors have failed to ...

Or maybe they just don't care:
That is my guess as well. But that would be in conflict with the Creative Commons licensing mentioned
on the Arduino LiquidCrystal page.

Quote
If I cannot use a piece of code in a way that I see fit, I have no use for it: I am not in the business of furthering someone's claims on anything.
Hmmm. I guess that means you have no use for Arduino or any open source tools like gcc and its associated tools.  smiley-grin
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I guess that means you have no use for Arduino or any open source tools like gcc and its associated tools.

True, if I cannot use a piece of code in a way that I see fit.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is probably an extreme implementation of a 2-wire interface. I wrote this to really show the limitations of such a concept in a multi-pin environment.

Here is the code.

Code:
/*
Demo code to run lcd1602 with two io pins
Code runs on 1MIPS avr / gcc-avr

Parts required:
 - 1 mcu (avr for now but portable to ther chips) running at 1MIPS. Need adjustments to other frequencies
 - two pins (digital outs)
 - 4 rc filters: 2 x 1k resistors, 1 x 10k resistor, 1 x 100k resistor and 4x 110n capacitors
 - supports hd44780-compatible lcds, up to 4 lines. lcd in 4-bit mode, no reading of busy flag

Connection:
 - RC filters: from a mcu pin to a resistor and then capacitor to ground. a lcd pin is connected to the joint of the capacitor + resistor.
 - RS: connected to the ENABLE pin via a 1k/110n filter.
 - RW: tied to ground
 - ENABLE: connected to the mcu pin designated as LCD_EN. No rc filter
 - D0..3: not connected
 - D4: connected to the mcu pin designated as LCD_Ds
 - D5: connected to D4 via a 1k/110n filter
 - D6: connected to D4 via a 10k/110n filter
 - D7: connected to D4 via a 100k/110n filter

Disclaimer: no warranty of any kind made. Use at your own risk.
 */

#include <avr/io.h> //gcc-avr

//pin configuration
#define LCD_EN D8 //defined to D8
#define LCD_Ds D9 //defined to D9
#define DLY_min 1 //delays to send D4/en. determined by your rc time constant
#define DLY_x 10ul //delay multipliers. "ul" for possible overflow. 10x to match the 10x ratio for rc constants

#define LCD_RS LCD_EN //en / rs the same pin
#define DLY_D4 (DLY_min) //delays to send D7. In cycles
#define DLY_D5 (DLY_D4 * DLY_x) //delays to send D7. In cycles
#define DLY_D6 (DLY_D5 * DLY_x) //delays to send D7. In cycles
#define DLY_D7 (DLY_D6 * DLY_x) //delays to send D7. In cycles

typedef struct {
unsigned char B0: 1;
unsigned char B1: 1;
unsigned char B2: 1;
unsigned char B3: 1;
unsigned char B4: 1;
unsigned char B5: 1;
unsigned char B6: 1;
unsigned char B7: 1;
} BIT8_T;

//extend bit fields
#if defined (PORTA)
#define PORTAbits (*(volatile BIT8_T *)&PORTA)
#define DDRAbits (*(volatile BIT8_T *)&DDRA)
#define PINAbits (*(volatile BIT8_T *)&PINA)
#endif

#if defined (PORTB)
#define PORTBbits (*(volatile BIT8_T *)&PORTB)
#define DDRBbits (*(volatile BIT8_T *)&DDRB)
#define PINBbits (*(volatile BIT8_T *)&PINB)
#endif

#if defined (PORTC)
#define PORTCbits (*(volatile BIT8_T *)&PORTC)
#define DDRCbits (*(volatile BIT8_T *)&DDRC)
#define PINCbits (*(volatile BIT8_T *)&PINC)
#endif

//helper functions. don't call directly
#define _DDR(id, pin) DDR ## id ## bits.B ## pin
#define _PORT(id, pin) PORT ## id ## bits.B ## pin

//port functions
#define DDR(pin) _DDR(pin)
#define PORT(pin) _PORT(pin)

//arduino compatibility
#define OUTPUT 1 //set a pin to output
#define INPUT 0 //set a pin to input
#define HIGH 1 //set a pin
#define LOW 0 //clear a pin
//pin macros
#define pinMode(pin, mode) _DDR(pin) = (mode)
#define digitalWrite(pin, val) _PORT(pin) = (val)
//pin definitions
#define D8 B, 0 //pin D8 on B.0
#define D9 B, 1 //pin D9 on B.1

#define NOP() asm("NOP")

//set cursor to row/col
#define lcd_goto(row, col) lcd_write(0, 0x80 | (row) | (col));
#define LCD_LINE0 0x00 //lcd display line0
#define LCD_LINE1 0x40 //lcd display line1
#define LCD_LINE3 0x14 //lcd display line2
#define LCD_LINE4 0x54 //lcd display line3

//delay routines
void lcd_delay(unsigned long cycles) {
while (cycles--) NOP();
}

//write 8-bits to the lcd in 4-bit mode
void lcd_write(unsigned char rs, unsigned char dat) {
//send the highest 4 bits. RS has the same rc filter as D6
if (dat & 0x80) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW); lcd_delay(DLY_D7);
if (dat & 0x40) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW); lcd_delay(DLY_D6);
if (rs)         digitalWrite(LCD_RS, HIGH); else digitalWrite(LCD_EN, LOW);
if (dat & 0x20) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW); lcd_delay(DLY_D5);
//like D4, EN has no rc filter
if (dat & 0x10) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW);
digitalWrite(LCD_EN, HIGH);
//lcd_delay(DLY_D4); in case you need it
digitalWrite(LCD_EN, LOW); //strobe out data

//send the lowest 4 bits
//send the highest 4 bits. RS has the same rc filter as D6
if (dat & 0x08) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW); lcd_delay(DLY_D7);
if (dat & 0x04) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW); lcd_delay(DLY_D6);
if (rs)         digitalWrite(LCD_RS, HIGH); else digitalWrite(LCD_EN, LOW);
if (dat & 0x02) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW); lcd_delay(DLY_D5);
//like D4, EN has no rc filter
if (dat & 0x01) digitalWrite(LCD_Ds, HIGH); else digitalWrite(LCD_Ds, LOW);
digitalWrite(LCD_EN, HIGH);
//lcd_delay(DLY_D4); in case you need it
digitalWrite(LCD_EN, LOW); //strobe out data
}

//initialize the lcd
void lcd_init(void) {
//set the pin modes
pinMode(LCD_EN, OUTPUT);
pinMode(LCD_Ds, OUTPUT);

//initialize the pins
digitalWrite(LCD_EN, LOW);
digitalWrite(LCD_Ds, LOW);

//send the initialize sequence
lcd_write(0, 0x33); //send 1 of 3 0b0011
lcd_write(0, 0x32); //send 2+3 of 3 0b0011, 4-bit mode
lcd_write(0, 0x28); //4bit 2 lines
lcd_write(0, 0x01); //clear display
lcd_delay(1000); //wait for 2ms - need additional work
lcd_write(0, 0x0c); //display on, cursor off, no blinking
}

//send string
void lcd_str(unsigned char *str) {
while (*str) lcd_write(1, *str++); //send display data
}

//ends lcd2wire driver

//demo code starts here
void setup(void) {
lcd_init();
}

void loop(void) {
//display 1st line
lcd_goto(LCD_LINE0, 0); //start in col 0
lcd_str("abcdefg");

//display 2nd line
lcd_goto(LCD_LINE1, 2); //start in col 2
lcd_str("0123456");
}

//stylized main
int main(void)
{

    // Insert code

setup(); //reset the mcu
while(1) {
loop(); //looping around
}

return 0;
}
Logged

Pages: 1 [2] 3   Go Up
Jump to: