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    27

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

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


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

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

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

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


Ссылка на сообщение
Поделиться на других сайтах
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()

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

    • Автор: Андрей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)
    • Автор: Michael4you
      Основные обязанности:
      •проектирование, разработка и поддержка ПО для встраиваемых систем;
      •сопровождение кода и тестов;
      •документирование разрабатываемого ПО;
      Требования к кандидату: 
      • опыт работы от 3 лет;
      • уверенное знание C;
      • опыт разработки встраиваемых приложений;
      • опыт работы с платформами на ARM-процессорах;
      • опыт работы с STM32;
      • опыт работы с ОСРВ (желательно FreeRTOS);
      • опыт работы с Keil, System Workbench;
      • опыт работы c ModBus, USB, CAN;
      Приветствуется:
      • опыт проектирования архитектур ПО;
      • знание Python;
      Условия:
      •трудоустройство по ТК РФ;
      •доход обсуждается с успешным кандидатом (от 60 тыс.руб.)
      •дистанционная работа, можно работать из дома;
      •выплаты заработной платы 2 раза в месяц
      Наш сайт: http://i-mt.net/
      Моя почта: dezh@i-mt.net
      Мой мобильный: +7963 776 36 55 
      С уважением, Михаил.
    • Автор: ktulx
      Приветствую.
      Схема простая: малина - pca9685 - оптрон - LDD-1000H - светодиоды.
      Все питания берётся от одного БП, причём на драйвер идёт минус 48 вольт. Отсюда и оптрон.
      Теперь о проблеме.
      Запускаю питоновый скрипт через cron. Каждый раз, будь то включение сд, выключение или изменение яркости - сначала происходит мгновенная вспышка на максимальной яркости, а затем уже то, что по плану. В общем-то оно и понятно - создаю новый объект класса при каждом запуске скрипта.
      Пример led_on:
      import Adafruit_PCA9685 pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(100) pwm.set_pwm(0, 0, 1000) Был на форуме Adafruit. Там мне "посоветовали", чтобы я не инициализировал контроллер каждый раз.
      Но как так-то?
      В общем, возможно ли софтварно решить эту задачу?
      Хардварно не придумал ничего лучше, чем повесить полевик на Output Enable и менять уровень на пине каждый раз перед работой с контроллером из нового скрипта.
      Это хоть и лучше, чем сейчас, но всё равно будет кратковременно моргать, только уже темнотой )
      Здесь можно посмотреть библиотеку от Adafruit для работы с PCA9685.
      Прошу советов.
  • Сообщения

    • Именно такое я и предложил. На странице 30 форума схема V19. Там пока напряжение в базе 3904 не достигнет 0,6В, никакого воздействия на остальную схему не происходит.   Есть мысль воспользоваться реле в качестве датчика тока. Например автомобильное реле. Там есть высоковитковая обмотка и проходящий через нее замкнутый сердечник. Должно работать. У меня пока китайские датчики тока еще не кончились, но и с реле надо будет попробовать.
    • У Вас есть по меньшей мере 2 проблемы - отсутствие сердечника и опыта. В активе может быть городская свалка или прайс радиомагазина, например. "Схема Пальник" - это что вообще такое? Надо приводить схему, лучше с описанием и наладкой. А уж с пояльника лучше вообще ничего не брать - сайт тот ещё. Также поищите - тут вроде была ссылка на статью "расчёт дросселя для класса Д"




       
    • Вообще то для этого есть специальные шарики. Не зря же называется накатка шаров. Где то в промышленых масштабах может и используется паста. А вообще эти шарики очень удобно использовать вместо пасты для ручного монтажа. Легко дозируются, хорошо хранятся. Не знаю что у вас за проблема с пастой. Заряжаю её для удобства в обычный шприц, ставлю специальную иголку для дозаторов и спокойно наношу пасту. В составе пасты уже есть флюс так что проблем не возникает. Видимо у вас проблемы с самой платой Категорически поддерживаю. Можно и хорошим инструментом не суметь ничего сделать. А про жало 4 мм зря удивляетесь. При пайке не буду же я при пайке каждого вывода набирать новый припой. А так набирается некоторое количество припоя и можно запаять несколько выводов. У планарных микросхем можно чуть ли не целый ряд запаять.
    • Красиво ответили, оно понятно ляпать языком не мешки тягать. Главное красиво уйти от ответа . Объясните пожалуйста тогда разницу между p и n каналом согласно вашим "научным" убеждениям?
    • Вы меня не поняли Я про выводы микросхемы 74нс02 там по схеме микросхема блоками расписана 1.2.3. я расписал выводы микросхемы согласно дата шиту от 1 до 16 ноги вот я и спросил правильно я расписал их.
    • То есть надо было указывать 35 кГц?
    • Вот схема подключения вибромоторчика Источник где подписано Snd Inp подключаешь на 9 ногу К157УД2, часть схемы отвечающий на звук возможно придется убрать если будет конфликтовать ...