More cleanups and testing work

pull/91/head
George Sexton 1 year ago
parent 98dbd48829
commit 4242fd7315

@ -36,8 +36,9 @@ MatrixOrbital LK2047T, the AdaFruit USB+Serial Backpack etc.
The driver package is designed to use the gpio.Group interface. This allows
the LCD driver to be agnostic about the physical connection between the display
and the host device. Any host/expander that supports the GPIO group can be used
to easily drive the LCD display.
and the host device. Any host/expander that supports the
periph.io/x/conn/v3/gpio.Group interface can be used to easily drive the LCD
display.
## Hardware Notes
@ -52,5 +53,8 @@ transistor (2N2222 or equivalent).
If nothing displays at all, check the contrast. Adjust the contrast control
until the 5x7 dot grid on the display is visible.
If the first row contains blocks of dots, and the other rows are blank, then
the initialization of the device failed. Check IO pins are connected properly.
If the text is garbled, verify the gpio.Group is configured and the IO Pins
are connected to the right pins of the LCD display.

@ -49,12 +49,14 @@ func NewAdafruitI2CBackpack(bus i2c.Bus, address uint16, rows, cols int) (*HD447
// This function returns a display configured to use the SPI side of the Adafruit
// I2c/SPI backpack. The SPI side uses a 74HC595 Serial->Parallel shift register.
func NewAdafruitSPIBackpack(conn spi.Conn, rows, cols int) (*HD44780, error) {
chip := nxp74hc595.New(conn)
chip, err := nxp74hc595.New(conn)
if err != nil {
return nil, err
}
// The SPI side has the same pins but in reverse order from the I2C side.
gr, _ := chip.Group(d7, d6, d5, d4)
rs := &chip.Pins[rsPin]
e := &chip.Pins[enablePin]
bl := &chip.Pins[backlightPin]
bl := chip.Pins[backlightPin]
return NewHD44780(gr, rs, e, NewBacklight(bl), rows, cols)
}

@ -5,6 +5,8 @@
package hd44780
import (
"fmt"
"periph.io/x/conn/v3/display"
"periph.io/x/conn/v3/gpio"
)
@ -31,4 +33,8 @@ func (bl *GPIOMonoBacklight) Backlight(intensity display.Intensity) (err error)
return err
}
func (bl *GPIOMonoBacklight) String() string {
return fmt.Sprintf("%#v", bl)
}
var _ display.DisplayBacklight = &GPIOMonoBacklight{}

@ -10,14 +10,15 @@ import (
"log"
"time"
"golang.org/x/exp/io/spi"
"periph.io/x/conn/v3/display"
"periph.io/x/conn/v3/display/displaytest"
"periph.io/x/conn/v3/gpio"
"periph.io/x/conn/v3/i2c/i2creg"
"periph.io/x/conn/v3/physic"
"periph.io/x/conn/v3/spi"
"periph.io/x/conn/v3/spi/spireg"
"periph.io/x/devices/v3/hd44780"
"periph.io/x/devices/v3/pcf857x"
"periph.io/x/host/v3"
"periph.io/x/host/v3/gpioioctl"
)
@ -54,13 +55,13 @@ func Example() {
fmt.Printf("n=%d, err=%s\n", n, err)
fmt.Println("lcd=", lcd.String())
lcd.Home()
lcd.MoveTo(1, 1)
lcd.WriteString("Line 1")
lcd.MoveTo(2, 2)
lcd.WriteString("Line 2")
_ = lcd.Home()
_ = lcd.MoveTo(1, 1)
_, _ = lcd.WriteString("Line 1")
_ = lcd.MoveTo(2, 2)
_, _ = lcd.WriteString("Line 2")
time.Sleep(5 * time.Second)
lcd.Clear()
_ = lcd.Clear()
fmt.Println("calling TestTextDisplay")
@ -91,8 +92,8 @@ func ExampleNewAdafruitI2CBackpack() {
if err != nil {
log.Fatal(err)
}
dev.Clear()
dev.WriteString("Hello")
_ = dev.Clear()
_, _ = dev.WriteString("Hello")
fmt.Println("wrote hello")
time.Sleep(5 * time.Second)
fmt.Println("calling test text display")
@ -144,14 +145,14 @@ func ExampleNewPCF857xBackpack() {
}
for range 5 {
fmt.Println("toggling backlight")
dev.Backlight(0)
_ = dev.Backlight(0)
time.Sleep(500 * time.Millisecond)
dev.Backlight(255)
_ = dev.Backlight(255)
time.Sleep(500 * time.Millisecond)
}
dev.Clear()
dev.WriteString("Hello")
_ = dev.Clear()
_, _ = dev.WriteString("Hello")
fmt.Println("wrote hello")
time.Sleep(5 * time.Second)
fmt.Println("calling test text display")

@ -41,7 +41,8 @@ type HD44780 struct {
dataPins gpio.Group
resetPin gpio.PinOut
enablePin gpio.PinOut
bl interface{}
blMono display.DisplayBacklight
blRGB display.DisplayRGBBacklight
mode ifMode
rows int
cols int
@ -70,18 +71,20 @@ func getRowConstant(row, maxcols int) byte {
return rowConstants[offset][row]
}
// NewHD44780 takes a GPIO group, and gpio.PinOut for reset, enable, and
// backlight. It returns a the HD44780 device in an initialized state and
// ready for use.
// NewHD44780 takes a GPIO group, and gpio.PinOut for reset and enable. It
// returns an HD44780 device in an initialized state and ready for use.
//
// The first 4 or 8 pins of the data group must be connected to the data lines
// To use 4 bit mode, you would connect lines D4-D7 on the display, and for
// 8 bit mode, D0-D7. If dataPinGroup is 8 or more pins, then it's assumed the display is
// connected using all 8 pins.
// To use 4 bit mode, you would connect lines D4-D7 on the display, and for 8
// bit mode, D0-D7. If dataPinGroup is 8 or more pins, then it's assumed the
// display is connected using all 8 pins.
//
// backlight should implement either display.DisplayBacklight or
// display.DisplayRGBBacklight. See GPIOMonoBacklight.
func NewHD44780(
dataPinGroup gpio.Group,
resetPin, enablePin *gpio.PinOut,
backlight interface{},
backlight any,
rows, cols int) (*HD44780, error) {
mode := mode4Bit
@ -89,17 +92,22 @@ func NewHD44780(
mode = mode8Bit
}
display := &HD44780{
lcd := &HD44780{
dataPins: dataPinGroup,
resetPin: *resetPin,
enablePin: *enablePin,
bl: backlight,
mode: mode,
rows: rows,
cols: cols,
on: true,
}
return display, display.init()
switch bl := backlight.(type) {
case display.DisplayBacklight:
lcd.blMono = bl
case display.DisplayRGBBacklight:
lcd.blRGB = bl
}
return lcd, lcd.init()
}
// Not supported by this device. Returns display.ErrNotImplemented
@ -206,7 +214,7 @@ func (lcd *HD44780) Rows() int {
// Return info about the dsiplay.
func (lcd *HD44780) String() string {
return fmt.Sprintf("HD44780::%s - Rows: %d, Cols: %d", lcd.dataPins.String(), lcd.rows, lcd.cols)
return fmt.Sprintf("HD44780 - Rows: %d, Cols: %d", lcd.rows, lcd.cols)
}
// Turn the display on / off
@ -280,39 +288,35 @@ func (lcd *HD44780) Halt() error {
// Set the backlight intensity.
func (lcd *HD44780) Backlight(intensity display.Intensity) error {
switch bl := lcd.bl.(type) {
case display.DisplayBacklight:
return bl.Backlight(intensity)
case display.DisplayRGBBacklight:
return bl.RGBBacklight(intensity, intensity, intensity)
default:
return display.ErrNotImplemented
if lcd.blMono != nil {
return lcd.blMono.Backlight(intensity)
} else if lcd.blRGB != nil {
return lcd.blRGB.RGBBacklight(intensity, intensity, intensity)
}
return display.ErrNotImplemented
}
// For units that have an RGB Backlight, set the backlight color/intensity.
// The range of the values is 0-255.
func (lcd *HD44780) RGBBacklight(red, green, blue display.Intensity) error {
switch bl := lcd.bl.(type) {
case display.DisplayRGBBacklight:
return bl.RGBBacklight(red, green, blue)
case display.DisplayBacklight:
return bl.Backlight(red | green | blue)
default:
return display.ErrNotImplemented
if lcd.blRGB != nil {
return lcd.blRGB.RGBBacklight(red, green, blue)
} else if lcd.blMono != nil {
return lcd.blMono.Backlight(red | green | blue)
}
return display.ErrNotImplemented
}
// delayWrite looks at the time of the last LCD write and if
// the specified microseconds period has not elapsed, it
// invokes time.Sleep() with the difference.
// delayWrite looks at the time of the last LCD write and if the specified
// microseconds period has not elapsed, it invokes time.Sleep() with the
// difference.
//
// Some I/O methods, like direct GPIO on a Pi are very fast, while other methods
// like i2c take longer. Without delays, on very fast I/O paths, the LCD will
// display garbage. The correct way to handle this would be to read the Busy flag
// on the LCD display. However, some backpacks don't have the capability to
// check the Busy flag because the R/W pin isn't connected. So, we can't correctly
// handle io delays. This handles the very fast interfaces, while not
// display garbage. The correct way to handle this would be to read the Busy
// flag on the LCD display. However, some backpacks don't have the capability to
// check the Busy flag because the R/W pin isn't connected. So, we can't
// correctly handle io delays. This handles the very fast interfaces, while not
// penalizing the slower ones with unnecessary delays.
//
// The value of lcd.lastWrite is updated to the current time by the call.
@ -380,8 +384,9 @@ func (lcd *HD44780) init() error {
_ = lcd.Display(true)
_ = lcd.Clear()
_ = lcd.Home()
return lcd.Backlight(0xff)
// If there's not a backlight, ignore the error.
_ = lcd.Backlight(0xff)
return nil
}
func (lcd *HD44780) sendCommand(commands []byte) error {
@ -431,4 +436,5 @@ func (lcd *HD44780) writeBits(value, mask gpio.GPIOValue) error {
var _ display.TextDisplay = &HD44780{}
var _ display.DisplayBacklight = &HD44780{}
var _ display.DisplayRGBBacklight = &HD44780{}
var _ conn.Resource = &HD44780{}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save