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()

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


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

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
Vovka    23

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

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


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

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

    • Гость 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.
      Прошу советов.
    • Автор: mrGear
      Доброго времени суток, форумчане!
      Давно хочу установить на дрифтовую машинку управление через wi-fi. Почитав немного матчасть, понял, что все не так просто. В общем нужен совет, по выбору мозгов для следующих задач:
      1. Передать видео / аудио с камеры формата hd и микрофона, установленных на модели на компьютер, телефон, без задержек.
      2. Установить пропорциональное управление двигателем / поворотами и несколько команд вроде включить/выключить свет, через тот же компьютер / телефон.
      3. Управление подвесом камеры (соблюдения прямой линии между направлением скольжения модели и подвесом камеры, то есть едете прямо - камера сзади, входите в поворот боком - подвес камеры и вектор направления движения параллельны). Здесь по подробнее: камера устанавливается на плече из проволоки, которая в свою очередь, крепится к бесколлекторному двигателю на крыше модели, (как при трех осевом стабилизаторе на квадрике, только здесь по одной оси) с видом от третьего лица так сказать. Подозреваю, нужен будет еще какой то датчик направления движения.
      Само устройство должно быть не очень большое, чтобы спрятаться под коркой (до 10х10 см) и иметь вычислительную мощность, которой бы хватило с неким запасом для последующих надстроек. Цена до 50$. Рассматривал Raspberry Pi 3 Model B, может подскажите еще какие варианты.
       Заранее благодарю за ответы!
    • Гость Дмитрий
      Автор: Гость Дмитрий
      Доброго времени суток, форумчане!
      Давно хочу установить на дрифтовую машинку управление через wi-fi. Почитав немного матчасть, понял, что все не так просто. В общем нужен совет, по выбору мозгов для следующих задач:
      1. Передать видео / аудио с камеры формата hd и микрофона, установленных на модели на компьютер, телефон, без задержек.
      2. Установить пропорциональное управление двигателем / поворотами и несколько команд вроде включить/выключить свет, через тот же компьютер / телефон.
      3. Управление подвесом камеры (соблюдения прямой линии между направлением скольжения модели и подвесом камеры, то есть едете прямо - камера сзади, входите в поворот боком - подвес камеры и вектор направления движения параллельны). Здесь по подробнее: камера устанавливается на плече из проволоки, которая в свою очередь, крепится к бесколлекторному двигателю на крыше модели, (как при трех осевом стабилизаторе на квадрике, только здесь по одной оси) с видом от третьего лица так сказать. Подозреваю, нужен будет еще какой то датчик направления движения.
      Само устройство должно быть не очень большое, чтобы спрятаться под коркой (до 10х10 см) и иметь вычислительную мощность, которой бы хватило с неким запасом для последующих надстроек. Цена до 50$. Рассматривал Raspberry Pi 3 Model B, может подскажите еще какие варианты.
       Заранее благодарю за ответы!