mrmorphic / hwio

Go library for hardware I/O control, in the programming style of Arduino
BSD 3-Clause "New" or "Revised" License
328 stars 40 forks source link

HD44780 backlight problem #46

Open Cruiser79 opened 7 years ago

Cruiser79 commented 7 years ago

I got the following code:

package main

// import the require modules
import (
    "github.com/mrmorphic/hwio"
    "github.com/mrmorphic/hwio/devices/hd44780"
    "time"
    "fmt"
)

func main() {
    // Get the i2c module from the driver. i2c is the canonical name. On the BeagleBone, it can also
    // be referred to as i2c2.
    m, _ := hwio.GetModule("i2c")

    // Assert that it is an I2C module
    i2c := m.(hwio.I2CModule)
    i2c.Enable()
    defer i2c.Disable()

    // Get a display device on this i2c bus. You need to provide it a device profile. Two profiles
    // are currently implemented, PROFILE_MJKDZ and PROFILE_PCF8574, corresponding to two commonly found
    // port extenders used to interface to LCD displays.
    display := hd44780.NewHD44780(i2c, 0x3f, hd44780.PROFILE_PCF8574)

    // Initialise the display with the size of display you have.
    display.Init(16, 2)

    // The display may not show anything if the backlight is turned off
    display.SetBacklight(true)

    // clear the display
    display.Clear()

    // Set cursor to a specific column and row (both zero based)
    display.SetCursor(0, 0) // second line

    for {
        time.Sleep(1*time.Second)
        t := time.Now()
        display.SetCursor(0, 1)
        fmt.Fprint(display, t.Format("15:04:05 2006"))
    }

}

Data is comming to the display, but the backlight only turns on, while the data is written to display. Some milliseconds the display is bright, then it turns off. Then, the second, the code is waiting, display is dark. I tested my display with arduino code and with python code on raspberry, and i got not this strange behavior. So, what can it be? It must be something in this library wrong for my display.

bkize commented 7 years ago

You could try replacing the following line with the Extended device creation format farther below.

display := hd44780.NewHD44780(i2c, 0x3f, hd44780.PROFILE_PCF8574)

The Extended initialization format allows defining the specific pin that controls the backlight as well as the polarity of the backlight pin. The sample below is from the bottom of the HD44780 Usage section, right above Notes. You'll likely need to adjust the pin assignments to match your device.

display := NewHD44780Extended(i2c, 0x27,
    0, // en
    1, // rw
    2, // rs
    4, // d4
    5, // d5
    6, // d6
    7, // d7polarity int) *HD44780 {
    3, // backlight,
    hd44780.POSITIVE) // polarity

Also, it would helpful to identify the exact make and model of the display you're using so someone could possibly review the spec sheet for it. Or just post a link to it. There are hundreds of LCD products that use the HD44780 controller and the Notes state this code was tested on just a few devices.

Cruiser79 commented 7 years ago

The following code was working with my display on arduino.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define BACKLIGHT_PIN     3

LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD

int initialMins = 59;//variable to initiate minutes
int initialSecs = 44;//variable to initiate seconds
void setup()
{
  lcd.begin(16,2);               // initialize the lcd 

  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);

  lcd.home (); 
 }

void printDigits(byte digits){
 // utility function for digital clock display: prints preceding colon and leading 0
 if(digits < 10)
   lcd.print('0');
 lcd.print(digits,DEC);
}
//this method is for seconds
int seconds()
{
    int s = s+(initialMins*60);
    s = s+initialSecs;
    s = s+(millis()/1000);
    return s;
}
int mins()
{
    int minutes = seconds();
    minutes = minutes/60;
    minutes = minutes%60;
    return minutes;
}
int secs()
{
    int sec = seconds();
    sec = sec%60;
    return sec;
}
void digitalClockDisplay(){
 lcd.setCursor(0, 1);
 // digital clock display of current time
 printDigits(mins());
 lcd.print(":");
 printDigits(secs());   
}

void loop()
{
   digitalClockDisplay( );   // update digital clock  
}

When i see it right in the hwio code, the profile hd44780.PROFILE_PCF8574 is exactly the right one for my display. So the test with NewHD44780Extended will gave the same result. Am i right?

Another example. With the embd library my display is working correct

package main

import (
    "flag"
    "time"

    "github.com/kidoman/embd"
    "github.com/kidoman/embd/controller/hd44780"

    _ "github.com/kidoman/embd/host/all"
)

func main() {
    flag.Parse()

    if err := embd.InitI2C(); err != nil {
        panic(err)
    }
    defer embd.CloseI2C()

    bus := embd.NewI2CBus(1)

    hd, err := hd44780.NewI2C(
        bus,
        0x3f,
        hd44780.PCF8574PinMap,
        hd44780.RowAddress16Col,
        hd44780.TwoLine,
        hd44780.BlinkOn,
    )
    if err != nil {
        panic(err)
    }
    defer hd.Close()

    hd.Clear()
    hd.BacklightOn()

    message := "Hello, world!"
    bytes := []byte(message)
    for _, b := range bytes {
        hd.WriteChar(b)
    }
    hd.SetCursor(0, 1)

    message = "@embd | hd44780"
    bytes = []byte(message)
    for _, b := range bytes {
        hd.WriteChar(b)
    }
    time.Sleep(10 * time.Second)
    hd.BacklightOff()
}

My display is this one https://de.aliexpress.com/item/1602-16x2-HD44780-Character-LCD-w-IIC-I2C-Serial-Interface-Adapter-Module/32546958584.html?spm=2114.13010608.0.0.g9VSGX I can only see the name QAPASS on the display. Here are two photos. May they help? https://drive.google.com/file/d/0B_8BgRvDVaBpdzhTTDhDV0tYZmM/view?usp=sharing https://drive.google.com/file/d/0B_8BgRvDVaBpNVRWRmZtQ1c5Nm8/view?usp=sharing