LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
JasJones
User
Beiträge: 7
Registriert: Mittwoch 18. September 2019, 11:44

Hallo, ich bin neu hier und möchte eine Lösung für mein 16x2 LCD Programmierung finden.

Ich möchte einen string - Loop von insgesamt 4 Zeilen laufen lassen und es sollen klarerweise immer nur je 2 Zeilen angezeigt werden. Wie codiere ich, dass er mir zu erst Zeile1+2 anzeigt, dann Wechsel zu Zeile 3+4, dann wieder Zeile 1+2....
Bitte helft mir, wenn/ob/falls das möglich ist.

Danke & LG
JasJones

___________________________________
hier mein code:
___________________________________
import lcddriver
from time import*

lcd = lcddriver.lcd()

lcd.lcd_clear()

lcd.lcd_display_string("Zeile1")
lcd.lcd_display_string("Zeile2")

lcd.lcd_display_string("Zeile3")
lcd.lcd_display_string("Zeile4")
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du schreibst ja schon selbst von einem loop. Du musst einen einbauen. zB einen while-loop. Und entsprechende Wartezeiten mit time.sleep zB.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Fragt sich halt, wo genau die Problematik besteht. Also zwei Zeilen in einem Rutsch kann man so anzeigen:

Code: Alles auswählen

TEST_LINES = list('abcdefghijklmnopqrstuvwxyz')

def print_lines(lines, chunk_size=2):
    for i in range(0, len(lines), chunk_size):
        for j in range(chunk_size):
            try:
                print(lines[i + j])
            except IndexError:
                break
        print('### End of chunk ###')

print_lines(TEST_LINES)
Da dann einfach den passenden Aufruf aus deiner LCD-Bibliothek einbauen. Und anstatt dem "End of chunk" nimmst du eine Pause (time.sleep).

EDIT: Geht mit entsprechender Python-Magie alles auch noch kürzer:

Code: Alles auswählen

from itertools import zip_longest

def print_lines(lines, chunk_size=2):
    for chunk in zip_longest(*[iter(lines)] * chunk_size):
        for line in chunk:
            if line is not None:
                print(line)
        print('### End of chunk ###')
... ist übrigens vom grouper()-Beispiel aus der itertools-Doku abgekupfert. :)
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Als Nachtrag hier noch die Index-basierte Variante in kürzerer Form:

Code: Alles auswählen

def print_lines(lines, chunk_size=2):
    for i in range(0, len(lines), chunk_size):
        for line in lines[i:(i + chunk_size)]:
            print(line)
        print('### End of chunk ###')
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das `grouper()`-Rezept gibt's in `more_itertools`, und ich habe da noch ein `cycle()` reingeworfen, damit das auch wirklich wiederholt wird.

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import cycle
from time import sleep

import lcddriver
from more_itertools import grouper


def main():
    lcd = lcddriver.lsd()
    lines = ["line 1", "line 2", "line 3", "line 4"]
    for group in cycle(grouper(2, lines, "")):
        for line in group:
            lcd.lcd_display_string(line)
        sleep(1)


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

__blackjack__ hat geschrieben: Mittwoch 18. September 2019, 23:58 Das `grouper()`-Rezept gibt's in `more_itertools`, und ich habe da noch ein `cycle()` reingeworfen, damit das auch wirklich wiederholt wird.

Code: Alles auswählen

lcd = lcddriver.lsd()
Hast du neben cycle() evtl noch was anderes "reingeworfen"...? :shock: :lol:
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich weiss nicht was Du meinen könntest… 😇
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
JasJones
User
Beiträge: 7
Registriert: Mittwoch 18. September 2019, 11:44

Vielen Dank!!! :D
JasJones
User
Beiträge: 7
Registriert: Mittwoch 18. September 2019, 11:44

__blackjack__ hat geschrieben: Mittwoch 18. September 2019, 23:58 Das `grouper()`-Rezept gibt's in `more_itertools`, und ich habe da noch ein `cycle()` reingeworfen, damit das auch wirklich wiederholt wird.

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import cycle
from time import sleep

import lcddriver
from more_itertools import grouper


____

from more_itertools import grouper


____

Vielen Dank:) Das wäre genau, was ich suche, allerdings, wieso findet Python more_itertools nicht bzw. die Eingabe from more_itertools import grouper ?  :?:   
Sry vorab, falls es ganz was einfaches ist, aber aller Anfang....
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Weil das ein externes Paket ist. Du musst es via pip installieren oder die grouper()-Funktion nachbauen, falls du nichts zusätzlich installieren kannst oder willst.
JasJones
User
Beiträge: 7
Registriert: Mittwoch 18. September 2019, 11:44

Hallo nachmals,
habe die Tage alles versucht, über pip installiert und auch nachgebaut, aber leider funktioniert es nicht. Obwohl ich beides probiert habe trotzdem die Frage: wenn über pip installiert, muss ich den 'grouper' dann nochmals definieren, wenn ich den zuletzt angegebenen Code von __blackjack__ verwende?
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Was meinst du mit "definieren"? Du musst die Funktion nur importieren - so wie BlackJack das in seinem Code tut.

Wenn du Probleme hast, da etwas zu installieren, solltest du uns vielleicht zeigen, wie du das versuchst, welche Fehlermeldungen es gibt und was nicht geht.
Bitte mit direkten Kopien aus der Konsole - sowohl von den Kommandos als auch von den Fehlermeldungen.
JasJones
User
Beiträge: 7
Registriert: Mittwoch 18. September 2019, 11:44

Alles klar/Danke, Danke! :)
Jetzt ein paar Probleme gelöst, da ich mittlerweilenahezu alle Python - Versionen drauf habe und die sich offenbar in die Quere gekommen sind...jedoch:
______________________________________________________________________
from itertools import cycle
from time import sleep


import lcddriver
from more_itertools import grouper


def main():
lcd = lcddriver.lcd()
lines = [" ATTENTION1 "," ATTENTION2 "," ATTENTION3 "," ATTENTION4 "]
for group in cycle (grouper(2, lines, "")):
for line in group:
lcd.lcd_display_string(line)
sleep(1)


if __name__ =="__main__": main()
_______________________________________________________________
pi@raspberrypi:~/Desktop/lcd_display $ python anzeige.py
Traceback (most recent call last):
File "anzeige.py", line 18, in <module>
if __name__ =="__main__": main()
File "anzeige.py", line 14, in main
lcd.lcd_display_string(line)
TypeError: lcd_display_string() takes exactly 3 arguments (2 given)
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@JasJones: Tja, dann schau mal in der Dokumentation zu dem `lcddriver`-Modul nach was Du da vergessen hast zu übergeben. Ich hätte da eine Vermutung, aber da ich nicht weiss wo das Modul herkommt und was in dessen Dokumentation steht, kannst das wohl nur Du selbst nachsehen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
JasJones
User
Beiträge: 7
Registriert: Mittwoch 18. September 2019, 11:44

hier das lcddriver-Modul:
___________________________________

import sys
sys.path.append("./lib")

import i2c_lib
from time import *

# LCD Address
ADDRESS = 0x27

# commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80

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

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

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

# flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00

# flags for backlight control
LCD_BACKLIGHT = 0x08
LCD_NOBACKLIGHT = 0x00

En = 0b00000100 # Enable bit
Rw = 0b00000010 # Read/Write bit
Rs = 0b00000001 # Register select bit

class lcd:
#initializes objects and lcd
def __init__(self):
self.lcd_device = i2c_lib.i2c_device(ADDRESS)

self.lcd_write(0x03)
self.lcd_write(0x03)
self.lcd_write(0x03)
self.lcd_write(0x02)

self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE)
self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON)
self.lcd_write(LCD_CLEARDISPLAY)
self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT)
sleep(0.2)

# clocks EN to latch command
def lcd_strobe(self, data):
self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT)
sleep(.0005)
self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT))
sleep(.0001)

def lcd_write_four_bits(self, data):
self.lcd_device.write_cmd(data | LCD_BACKLIGHT)
self.lcd_strobe(data)

# write a command to lcd
def lcd_write(self, cmd, mode=0):
self.lcd_write_four_bits(mode | (cmd & 0xF0))
self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0))

#turn on/off the lcd backlight
def lcd_backlight(self, state):
if state in ("on","On","ON"):
self.lcd_device.write_cmd(LCD_BACKLIGHT)
elif state in ("off","Off","OFF"):
self.lcd_device.write_cmd(LCD_NOBACKLIGHT)
else:
print ("Unknown State!")

# put string function
def lcd_display_string(self, string, line):
if line == 1:
self.lcd_write(0x80)
if line == 2:
self.lcd_write(0xC0)
if line == 3:
self.lcd_write(0x94)
if line == 4:
self.lcd_write(0xD4)

for char in string:
self.lcd_write(ord(char), Rs)

# clear lcd and set to home
def lcd_clear(self):
self.lcd_write(LCD_CLEARDISPLAY)
self.lcd_write(LCD_RETURNHOME)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@JasJones: das ist nun nicht gerade die Dokumentation, aber auch hier kannst Du ablesen, was lcd_display_string für Parameter erwartet.
JasJones
User
Beiträge: 7
Registriert: Mittwoch 18. September 2019, 11:44

und die i2c_lib :
_____________________

import sys
sys.path.append("./lib")
import smbus
from time import *

class i2c_device:
def __init__(self, addr, port=1):
self.addr = addr
self.bus = smbus.SMBus(port)

# Write a single command
def write_cmd(self, cmd):
self.bus.write_byte(self.addr, cmd)
sleep(0.0001)

# Write a command and argument
def write_cmd_arg(self, cmd, data):
self.bus.write_byte_data(self.addr, cmd, data)
sleep(0.0001)

# Write a block of data
def write_block_data(self, cmd, data):
self.bus.write_block_data(self.addr, cmd, data)
sleep(0.0001)

# Read a single byte
def read(self):
return self.bus.read_byte(self.addr)

# Read
def read_data(self, cmd):
return self.bus.read_byte_data(self.addr, cmd)

# Read a block of data
def read_block_data(self, cmd):
return self.bus.read_block_data(self.addr, cmd)
Antworten