Seite 1 von 1
LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Mittwoch 18. September 2019, 11:56
von JasJones
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")
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Mittwoch 18. September 2019, 16:28
von __deets__
Du schreibst ja schon selbst von einem loop. Du musst einen einbauen. zB einen while-loop. Und entsprechende Wartezeiten mit time.sleep zB.
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Mittwoch 18. September 2019, 18:13
von snafu
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.

Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Mittwoch 18. September 2019, 23:13
von snafu
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 ###')
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Mittwoch 18. September 2019, 23:58
von __blackjack__
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()
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Donnerstag 19. September 2019, 00:09
von snafu
__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.
Hast du neben cycle() evtl noch was anderes "reingeworfen"...?

Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Donnerstag 19. September 2019, 00:14
von __blackjack__
Ich weiss nicht was Du meinen könntest…

Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Donnerstag 19. September 2019, 09:12
von JasJones
Vielen Dank!!!

Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Donnerstag 19. September 2019, 14:55
von JasJones
__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....
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Donnerstag 19. September 2019, 15:16
von snafu
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.
Re: LCD 16x2 - Loopwechsel von insg. 4 Zeilen möglich?
Verfasst: Samstag 28. September 2019, 14:02
von JasJones
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?
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Samstag 28. September 2019, 14:31
von sparrow
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.
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Samstag 28. September 2019, 16:07
von JasJones
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)
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Samstag 28. September 2019, 18:05
von __blackjack__
@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.
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Samstag 28. September 2019, 19:12
von JasJones
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)
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Samstag 28. September 2019, 19:15
von Sirius3
@JasJones: das ist nun nicht gerade die Dokumentation, aber auch hier kannst Du ablesen, was lcd_display_string für Parameter erwartet.
Re: LCD 16x2 - Loopechsel von insg. 4 Zeilen möglich?
Verfasst: Samstag 28. September 2019, 19:36
von JasJones
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)