varik123

Некорректный Вывод Символов На Дисплей Hd44780 C Raspberry

5 сообщений в этой теме

varik123    0

Нужно с помощью Raspberry выводить на текстовый дисплей список файлов из определенной директории. И листать этот список с помощью тактовых кнопок. Дисплей Winstar WH1602A-YGH-CTK на контроллере S6B0066U (аналог HD44780). Дисплей подключил по этой схеме (в 4-х битном режиме):

b746e4bec022.jpg

Тактовые кнопки подключал так:

rpck_1101.png

Написал пробную версию программы: при нажатии на одну кнопку на дисплей выводятся первые два файла, при нажатии на вторую - следующие два. Это должно выглядеть так:

885ef4dedede.jpg

Но правильный список выводится не всегда. Почему-то иногда экран выводит чушь, типа этой 1361a1c9f68c.jpg

В коде поигрался со значениями sleep и добился того, чтобы глюк появлялся как можно реже - примерно на каждом втором-третьем нажатии это выскакивает. Подозреваю, что проблема в том, что S6B0066U все-таки не полный аналог HD44780 вопреки документации (в интернете видел упоминания этой проблемы при подключении S6B0066U в 4-битном режиме.

Код программы:

#!/usr/bin/python

import RPi.GPIO as GPIO
import os
from time import sleep
directory = '/media/TRANSCEND'
files = os.listdir(directory)
images = filter(lambda x: x.endswith('.jpg'), files)
class HD44780:

def __init__(self, pin_rs=7, pin_e=8, pins_db=[25, 24, 23, 18]):

 self.pin_rs=pin_rs
 self.pin_e=pin_e
 self.pins_db=pins_db

 GPIO.setmode(GPIO.BCM)
 GPIO.setup(self.pin_e, GPIO.OUT)
 GPIO.setup(self.pin_rs, GPIO.OUT)
 for pin in self.pins_db:
	 GPIO.setup(pin, GPIO.OUT)

 self.clear()

def clear(self):
 """ Blank / Reset LCD """

 self.cmd(0x33) # $33 8-bit mode
 self.cmd(0x32) # $32 8-bit mode
 self.cmd(0x28) # $28 8-bit mode
 self.cmd(0x0C) # $0C 8-bit mode
 self.cmd(0x06) # $06 8-bit mode
 self.cmd(0x01) # $01 8-bit mode

def cmd(self, bits, char_mode=False):
 """ Send command to LCD """

 sleep(0.001)
 bits=bin(bits)[2:].zfill(8)

 GPIO.output(self.pin_rs, char_mode)

 for pin in self.pins_db:
	 GPIO.output(pin, False)

 for i in range(4):
	 if bits[i] == "1":
		 GPIO.output(self.pins_db[::-1][i], True)

 GPIO.output(self.pin_e, True)
 GPIO.output(self.pin_e, False)

 for pin in self.pins_db:
	 GPIO.output(pin, False)

 for i in range(4,8):
	 if bits[i] == "1":
		 GPIO.output(self.pins_db[::-1][i-4], True)


 GPIO.output(self.pin_e, True)
 GPIO.output(self.pin_e, False)

def message(self, text):
 """ Send string to LCD. Newline wraps to second line"""

 for char in text:
	 if char == ' ':
		 self.cmd(0xC0) # next line
	 else:
		 self.cmd(ord(char),True)

if __name__ == '__main__':
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
try:
	 if GPIO.input(21) == False:
	 lcd = HD44780()
list=images[0] + " " + images[1]
list=str(list)
lcd.message(list)		
	 if GPIO.input(16) == False:
lcd = HD44780()
list=images[2] + " " + images[3]
list=str(list)
lcd.message(list)
	 sleep(0.12)
	 except KeyboardInterrupt:
	 exit()

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vovka    29

Не используемые выводы дисплея подключены к земле?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
varik123    0

Не используемые выводы дисплея подключены к земле?

В смысле к GND или к "пустым" дыркам на плате? Да, подключены к дыркам, как на схеме выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
UTSource

Найдите миллионы труднодоступных

электронных компонентов

varik123    0

Косяк был в коде инициализации. Переписал программу.

#import
import RPi.GPIO as GPIO
import os
import socket
import fcntl
import struct
import time
from time import gmtime, strftime, sleep
directory = '/media/TRANSCEND'
files = os.listdir(directory)
images = filter(lambda x: x.endswith('.jpg'), files) 
# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18

# Define some device constants
LCD_WIDTH = 16    # Maximum characters per line
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
def main():
 # Main program block

 GPIO.setwarnings(False)
 GPIO.setmode(GPIO.BCM)	   # Use BCM GPIO numbers
 GPIO.setup(LCD_E, GPIO.OUT)  # E
 GPIO.setup(LCD_RS, GPIO.OUT) # RS
 GPIO.setup(LCD_D4, GPIO.OUT) # DB4
 GPIO.setup(LCD_D5, GPIO.OUT) # DB5
 GPIO.setup(LCD_D6, GPIO.OUT) # DB6
 GPIO.setup(LCD_D7, GPIO.OUT) # DB7

 # Initialise display
 lcd_init()
 i=0
 GPIO.setmode(GPIO.BCM)
 GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)

 while True:
   try:
    if GPIO.input(21) == False:
  i=i+1
  j=i+1
  lcd = HD44780()
  lcd_string(images[i], LCD_LINE_1)
  lcd_string(images[j], LCD_LINE_2)	   
    if GPIO.input(16) == False:
  i=i-1
  j=i+1
  lcd = HD44780()
  lcd_string(images[i], LCD_LINE_1)
  lcd_string(images[j], LCD_LINE_2)
    sleep(0.12)
   except KeyboardInterrupt:
    exit()

def lcd_init():
 # Initialise display
 lcd_byte(0x33,LCD_CMD) # 110011 Initialise
 lcd_byte(0x32,LCD_CMD) # 110010 Initialise
 lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
 lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
 lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
 lcd_byte(0x01,LCD_CMD) # 000001 Clear display
 time.sleep(E_DELAY)
def lcd_byte(bits, mode):
 # Send byte to data pins
 # bits = data
 # mode = True  for character
 #	    False for command
 GPIO.output(LCD_RS, mode) # RS
 # High bits
 GPIO.output(LCD_D4, False)
 GPIO.output(LCD_D5, False)
 GPIO.output(LCD_D6, False)
 GPIO.output(LCD_D7, False)
 if bits&0x10==0x10:
   GPIO.output(LCD_D4, True)
 if bits&0x20==0x20:
   GPIO.output(LCD_D5, True)
 if bits&0x40==0x40:
   GPIO.output(LCD_D6, True)
 if bits&0x80==0x80:
   GPIO.output(LCD_D7, True)
 # Toggle 'Enable' pin
 lcd_toggle_enable()
 # Low bits
 GPIO.output(LCD_D4, False)
 GPIO.output(LCD_D5, False)
 GPIO.output(LCD_D6, False)
 GPIO.output(LCD_D7, False)
 if bits&0x01==0x01:
   GPIO.output(LCD_D4, True)
 if bits&0x02==0x02:
   GPIO.output(LCD_D5, True)
 if bits&0x04==0x04:
   GPIO.output(LCD_D6, True)
 if bits&0x08==0x08:
   GPIO.output(LCD_D7, True)
 # Toggle 'Enable' pin
 lcd_toggle_enable()
def lcd_toggle_enable():
 # Toggle enable
 time.sleep(E_DELAY)
 GPIO.output(LCD_E, True)
 time.sleep(E_PULSE)
 GPIO.output(LCD_E, False)
 time.sleep(E_DELAY)
def lcd_string(message,line):
 # Send string to display

 message = message.ljust(LCD_WIDTH," ")
 lcd_byte(line, LCD_CMD)
 for i in range(LCD_WIDTH):
   lcd_byte(ord(message[i]),LCD_CHR)
if __name__ == '__main__':
 try:
   main()
 except KeyboardInterrupt:
   pass
 finally:
   lcd_byte(0x01, LCD_CMD)
   lcd_string("Goodbye!",LCD_LINE_1)
   GPIO.cleanup()

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: Dandan He
      Здравствуйте, Уважаемые форумчане!
      TOMTOP – интернет-магазин, специализирующийся на продажах товаров китайского производства. Магазин TOMTOP не является новичком на рынке – он был основан ещё в 2004 году. К 2017 году портал завоевал репутацию заботливого и ответственного торговца высококачественной продукции, а также получил признание такого «гиганта» продаж, как Alibaba. В 2006 году Alibaba пожаловала продавцу TOMTOP статус «золотого поставщика» — очень почётный для азиатского рынка.
      Доступные способы оплаты
      Российским покупателям магазин TOMTOP даёт возможность оплачивать товары множеством способов:
      С банковских карт Visa и MasterCard. Оплата происходит через защищённый сервер платежей Alipay – риск того, что деньги попадут к мошенникам и не дойдут до продавца, сведён к нулю.
      Посредством PayPal. Именно этот способ оплаты считается наиболее безопасным — покупатель, прибегнувший к услугам PayPal, может быть уверен: если он вдруг станет жертвой мошенников, ему вернут деньги. Однако сервис PayPal неудобен для оплаты дорогостоящих товаров — если сумма единовременного платежа превосходит 1000 $, платёж наверняка будет задержан на несколько дней для проверки транзакции.
      С электронных кошельков. TOMTOP ведёт сотрудничество с 3-мя ведущими отечественными платёжными системами – QIWI, Яндекс.Деньги, WebMoney. Комиссия при оплате с кошельков перечисленных систем не берётся.
      Доставка товара
      Покупатель вправе выбрать один из 2-х способов доставки: почтовая (дёшево и сердито) или экспресс (для тех, кому срочно). Доставка посредством авиапочты является бесплатной – в этом плане магазин TOMTOP «заткнул за пояс» даже площадку AliExpress, которая в 2017 году за пересылку многих товаров в Россию стала требовать деньги.
      Стоимость экспресс-доставки зависит от того, какого рода товар и с какого склада он отправляется. За быструю доставку гаджета с китайского склада покупателю придётся заплатить порядка 4 тыс. рублей. Экспресс-доставка смартфона / планшета со склада, размещённого в России, обойдётся примерно в 1 тыс. рублей. Если речь идёт о каком-либо мелком и дешёвом товаре (например, о светодиодной Wi-Fi лампочке), экспресс-доставка с отечественного склада может оказаться бесплатной.
       
      Основной сайт: https://www.tomtop.com/
      Служба поддержки: service@tomtop.com
      ПАРТНЕРСКАЯ ПРОГРАММА : https://www.tomtop.com/help/affiliate-program.html
      Как присоединиться к нашей партнерской программе?
      Выберите партнерские сети и зарегистрируйтесь как партнер или издатель.
      Найдите идентификатор программы Tomtop.
      Подать заявку, чтобы присоединиться к нам и ждать нашего одобрения.
      Получите наши ссылки для продвижения и просмотра комиссионных.

    • Автор: Mihail Besshaposhnikov
      Доброго времени суток!
      Может и встречался вопрос на форуме но я не нашел. Мне необходима схема релейного модуля с питанием от 12в с управлением с raspberry pi (сама малина питается от своего источника).  Думаю использовать uln2003, мне необходимо управлять шестью нагрузками (тремя реле и тремя светодиодными лентами по 100 мА). Можете подсказать схему?
    • Автор: Андрей18
      Есть схема подключения (см. прикреплённый файл). Хочу понять преимущество подобного подключения.

      Я бы вместо резистора R2 подсоединил ключ, и к "земле" бы тут ничего не подключал.

    • Автор: Андрей18
      Хочу не в теории, а на практике ознакомиться работой с транзисторами. Так же на будущее хочу включать и выключать "малинкой" цепи, где идёт 5V, 9V, 12V, 24V и т.д. Для начала решил поэксперементировать с транзистором BC547B, нашёл для него документацию datasheet.

      Примерная схема:
      От пина "малинки" (напряжение 3,3V, максимальная сила тока 16mA) через ограничительное сопротивление R1 идёт ток на базу транзистора.
      Колектор транзистора подключён к "плюсу" 5V батарейки (крону понижаю при помощи LM2596).
      Эмиттер транзистора будет подключён к "полезной нагрузке" (двум светодиодам с резистором R2, а потом к моторчику), а после этой "полезной нагрузки" провод разделяется и идёт одним концом к "минусу" батарейки, а вторым к "земле" "малинки".
      Хочу расчитать значение сопротивления R1, чтобы ничего не сжечь.
      Rmin=U/Imax=3,3V/16mA=207Om.
      Следовательно, беру ближайший резистор, что у меня есть 330Ом.
      Высчитываю получившиюся силу тока: I=U/R=3,3V/330Om=0,01A=10mA.
      Теперь открываю документацию к транзистору "DC Current Gain" - "(IC = 100 mA, VCE = 5.0 V)" = 180
      Т.е. при подачи напряжения на пин через транзистор сможет течь ток с напряжением 5V и силой тока в 1,8A (10mA*180=1800mA)?
      Что-то мне эти расчёты не нравятся. В чём ошибка?
    • Гость Roman
      Автор: Гость Roman
       
      import sys
      SUBJECT = b"Subject: "
      HEADER_END = b"\r\n\r\n"
      def find_pos(email):
          return map(
                  lambda x: email.find(x) + len(x),
                  (SUBJECT, HEADER_END)
                  )
      with open(sys.argv[1], "rb") as f:
          email = f.read()
          subject_pos, header_end_pos = find_pos(email)
          print(subject_pos, header_end_pos)