pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

[SOLVED]Garbled Text on LCD only when running Pyton script.

Tue Jan 13, 2015 4:38 am

Hello, I'm running into a strange issue where when I add an additional function or elseif (elif), upon running the python script, and scrolling through the menu, it garbles the 20X4 lcd (no rgb). However, I have another python script that works perfectly. Scratching my head against this one. I have tried adjusting the epulse and edelay as I read from another post. What I would like it to do is output the artist and title information by running, mpc current | tail -c25 on lcd. Here is the attached python script: Thanks!

Code: Select all

# Define GPIO output pins for Radio Controls
PIN_SW1_PREV = 4
PIN_SW2_NEXT = 18

# The Adafruit_CharLCD class controls the LCD display
# using six GPIO output pins:
#  7 = RS (register select)
#  8 = E (enable/strobe)
#  25 = Data bit 4
#  24 = Data bit 5
#  23 = Data bit 6
#  17 = Data bit 7

#dependancies
from Adafruit_CharLCD import Adafruit_CharLCD
from datetime         import datetime
from subprocess       import *
from time             import sleep, strftime
import RPi.GPIO as GPIO

# globals
LCD = Adafruit_CharLCD()
PLAYLIST_MSG = []
STATION = 1
NUM_STATIONS = 0

E_PULSE = 0.000005
E_DELAY = 0.000005

def main():
   global STATION, NUM_STATIONS, PLAYLIST_MSG

   # Stop music player
   output = run_cmd("mpc stop" )

   # Setup GPIO
   GPIO.setmode(GPIO.BCM)            # Use BCM GPIO numbers
   GPIO.setup(PIN_SW1_PREV, GPIO.IN) # Previous Channel button
   GPIO.setup(PIN_SW2_NEXT, GPIO.IN) # Next Channel button

   # Setup AdaFruit LCD
   LCD.begin(20,4)
   LCD.clear()

# ----------------------------
# LOAD PLAYLIST OF STATIONS
# ----------------------------

   # Startup banner
   LCD.message('Welcome to\nPi Radio!')

   # Run shell script to add all stations
   # to the MPC/MPD music player playlist
   output = run_cmd ("mpc clear")
   output = run_cmd("/home/pi/projects/radio/radio_playlist.sh")

   # Load PLAYLIST_MSG list
   with open ("/home/pi/projects/radio/radio_playlist.sh", "r") as playlist:
      # Skip leading hash-bang line
      for line in playlist:
         if line[0:1] != '#!':  
               break
      # Remaining comment lines are loaded
      for line in playlist:
         if line[0] == "#" :
            PLAYLIST_MSG.append(line.replace(r'\n','\n')[1:-1] + "                ")
   playlist.close()

   sleep(1.5)
   NUM_STATIONS = len(PLAYLIST_MSG)

# ----------------------------
# START THE MUSIC!
# ----------------------------

   # Start music player
   LCD.clear()
   LCD.message(PLAYLIST_MSG[STATION - 1] )
   mpc_play(STATION)
   countdown_to_play = 0
      
   # Main loop
   while True:
      press = read_switches()

      # PREV button pressed
      if(press == 1):
         STATION -= 1
         if(STATION < 1):
            STATION = NUM_STATIONS
         LCD.setCursor(0,0)
         LCD.message(PLAYLIST_MSG[STATION - 1] )
         # start play in 300msec unless another key pressed
         countdown_to_play = 3

      # NEXT button pressed
      if(press == 2):
         STATION += 1
         if(STATION > NUM_STATIONS):
            STATION = 1
         LCD.setCursor(0,0)
         LCD.message(PLAYLIST_MSG[STATION - 1] )
         # start play in 300msec unless another key pressed
         countdown_to_play = 3

      # BOTH buttons pressed together
      if(press == 3):
         menu_pressed()
      # If we haven't had a key press in 300 msec
      # go ahead and issue the MPC command
      if(countdown_to_play > 0):
         countdown_to_play -= 1
         if(countdown_to_play == 0):
            # Play requested station
            mpc_play(STATION)

      delay_milliseconds(100)


def read_switches():

   # Initialize
   got_prev = False
   got_next = False

   # Read switches
   sw1_prev = GPIO.input(PIN_SW1_PREV)
   sw2_next = GPIO.input(PIN_SW2_NEXT)

   # Debounce switches and look for two-button combo
   while(sw1_prev or sw2_next):
      if(sw1_prev):
         got_prev = True
      if(sw2_next):
         got_next = True
      delay_milliseconds(1)
      sw1_prev = GPIO.input(PIN_SW1_PREV)
      sw2_next = GPIO.input(PIN_SW2_NEXT)
   if(got_prev and got_next):
      return 3
   if(got_next):
      return 2
   if(got_prev):
      return 1
   return 0



def delay_milliseconds(milliseconds):
   seconds = milliseconds / float(1000)	# divide milliseconds by 1000 for seconds
   sleep(seconds)



# ----------------------------
# RADIO SETUP MENU
# ----------------------------

MENU_LIST = [
   '1. Display Time \n   & IP Address ',
   '2. Output Audio \n   to HDMI      ',
   '3. Output Audio \n   to Headphones',
   '4. Auto Select  \n   Audio Output ',
   '5. Song        \n     Track       ',
   '6. Reboot       \n   Reboot       ',
   '7. System       \n   Shutdown!    ',
   '8. Exit         \n                ']

def menu_pressed():
   global MENU_LIST

   item = 0
   LCD.clear()
   LCD.message(MENU_LIST[item] )

   keep_looping = True
   while (keep_looping):

      # Wait for a key press
      press = read_switches()

      # PREV button
      if(press == 1):
         item -= 1
         if(item < 0):
            item = len(MENU_LIST) - 1
         LCD.clear()
         LCD.message(MENU_LIST[item] )

      # NEXT button
      elif(press == 2):
         item += 1
         if(item >= len(MENU_LIST)):
            item = 0
         LCD.clear()
         LCD.message(MENU_LIST[item] )

      # BOTH buttons together, This is "Select"
      elif(press == 3):
         keep_looping = False

         # Take action
         if(  item == 0):
            # display time and IP address
            display_ipaddr()
         elif(item == 1):
            # output to HDMI
            output = run_cmd("amixer -q cset numid=3 2")
         elif(item == 2):
            # output to headphone jack
            output = run_cmd("amixer -q cset numid=3 1")
         elif(item == 3):
            # output auto-select
              output = run_cmd("amixer -q cset numid=3 0")
         elif(item == 4):
            # Check artist/title info
              output = run_cmd("mpc current | tail -c25")          
         elif(item == 5):
            #reboot the system
            output = run_cmd("mpc clear")
            output = run_cmd("sudo reboot")
         elif(item == 6):
            #shutdown the system
            output = run_cmd("mpc clear")
            output = run_cmd("sudo halt -p")
      else:
         delay_milliseconds(100)

   # Restore display
   LCD.clear()
   LCD.message(PLAYLIST_MSG[STATION - 1] )

      

#def get_track():
#    show_track=run_cmd ("mpc current | tail -c25")   
#    if get_track == "":
#    get_track = run_cmd(show_track)
#    i = 0
#    keep_looping = True

     
def display_ipaddr():
   show_wlan0 = "ip addr show wlan0 | cut -d/ -f1 | awk '/inet/ {printf \"w%15.15s\", $2}'"
   show_eth0  = "ip addr show eth0  | cut -d/ -f1 | awk '/inet/ {printf \"e%15.15s\", $2}'"
   ipaddr = run_cmd(show_eth0)
   if ipaddr == "":
      ipaddr = run_cmd(show_wlan0)

   i = 0
   keep_looping = True
   while (keep_looping):

      # Every second, update the time display
      i += 1
      if(i % 10 == 0):
         LCD.setCursor(0,0)
         LCD.message(datetime.now().strftime('%b %d  %H:%M:%S\n'))
         LCD.message(ipaddr)
         #LCD.message('e%15.15s' % ( ipaddr ) )

      # Every 3 seconds, update ethernet or wi-fi IP address
      if(i == 60):
         ipaddr = run_cmd(show_eth0)
         i = 0
      elif(i == 30):
         ipaddr = run_cmd(show_wlan0)

      # Every 100 milliseconds, read the switches
      press = read_switches()
      if(press == 3):
         keep_looping = False
      delay_milliseconds(100)



def run_cmd(cmd):
   p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
   output = p.communicate()[0]
   return output



def run_cmd_nowait(cmd):
   pid = Popen(cmd, shell=True, stdout=NONE, stderr=STDOUT).pid



def mpc_play(STATION):
   pid = Popen(["/usr/bin/mpc", "play", '%d' % ( STATION )]).pid



if __name__ == '__main__':
  main()
Last edited by pi_noob on Fri Jan 23, 2015 1:00 am, edited 4 times in total.

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5618
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 11:28 am

Since I'm not a Python programmer I can't comment on the Python code but I can point out a hardware issue that can lead to garbled text (as shown here: http://www.cpmspectrepi.webspace.virgin ... ml#Testing_... ). If your interface is "4-bit parallel" and your "garbling" is similar to that shown in the last photo. your E-strobe pulse may be too short. A little more info. is here:
http://www.cpmspectrepi.webspace.virgin ... gData.html
and, FWIW, there's a forum thread here:
http://www.raspberrypi.org/forums/viewt ... 00#p641100
Trev.
Still running Raspbian Jessie or Stretch on some older Pi's (an A, B1, 2xB2, B+, P2B, 3xP0, P0W, 2xP3A+, P3B+, P3B, B+, and a A+) but Buster on the P4B's. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
PangolinPaws
Posts: 89
Joined: Wed Mar 05, 2014 9:04 pm
Location: Wiltshire, UK
Contact: Website

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 2:22 pm

I've noticed a similar thing happening to my LCD a couple of times. Turns out I had a second script running in the background that was also trying to use the LCD.

Perhaps this is unlikely for your setup, but I thought I'd mention it, just in case. ^_^
https://github.com/PangolinPaw

pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 3:07 pm

Thanks, FTrevorGowen for the hardware information! I believe I have an 8-bit parrallel lcd. PangolinPaws - I know it is strange. I do have another python script which calls the Adafruit LCD dependency for my lcd. However, if I remove this code from the else, else if statements:
elif(item == 4):
# Check artist/title info
output = run_cmd("mpc current | tail -c25")
The LCD display works perfectly and I am able to toggle between the menus. I am trying to achieve checking the artist/song title as an option and tried using output = run_cmd("mpc current"). I also did try to call a function from the else elseif statements.

Any help would be appreciated!

mike_p
Posts: 30
Joined: Fri Aug 01, 2014 2:35 pm
Location: Surrey, UK

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 3:23 pm

If you're using Adafruit_CharLCD then you are communicating with LCD with 4 bits, not 8.
The pulse widths and delay times that you need are built into the Adafruit_CharLCD.py script.
I'd have a play with those to get things working.
That script has "self.delayMicroseconds(1)" twice in the pulseEnable function. I'd replace the '1' with a constant and try a few different (longer) variations.

User avatar
PangolinPaws
Posts: 89
Joined: Wed Mar 05, 2014 9:04 pm
Location: Wiltshire, UK
Contact: Website

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 3:27 pm

pi_noob wrote:I do have another python script which calls the Adafruit LCD dependency for my lcd. However, if I remove this code from the else, else if statements:

Code: Select all

elif(item == 4):
# Check artist/title info 
output = run_cmd("mpc current | tail -c25") 
The LCD display works perfectly and I am able to toggle between the menus.
You've got a bit deeper into this than I have, but is it possible to completely clear the LCD briefly before the problematic code and see if that makes any difference?

P.S. Could you stick your code in [ code ] tags so we can see the indentation etc.?
https://github.com/PangolinPaw

pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 6:26 pm

Do you mean enter this code like below (without brackets) to clear lcd?

[lcd.clear()
elif(item == 4):
#Check artist/title info
output = run_cmd("mpc current | tail -c25") ]

User avatar
DougieLawson
Posts: 39120
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 6:46 pm

pi_noob wrote:Do you mean enter this code like below (without brackets) to clear lcd?

[lcd.clear()
elif(item == 4):
#Check artist/title info
output = run_cmd("mpc current | tail -c25") ]
No he means enter the code like:
[code]lcd.clear()
elif(item == 4):
#Check artist/title info
output = run_cmd("mpc current | tail -c25") [/code]

To get it formatted as:

Code: Select all

lcd.clear()
   elif(item == 4):
   #Check artist/title info
   output = run_cmd("mpc current | tail -c25") 
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
PangolinPaws
Posts: 89
Joined: Wed Mar 05, 2014 9:04 pm
Location: Wiltshire, UK
Contact: Website

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 8:47 pm

pi_noob wrote:Do you mean enter this code like below (without brackets) to clear lcd?

Code: Select all

lcd.clear()
   elif(itemr == 4):
   #Check artist/title info
   output = run_cmd("mpc current | tail -c25") 
Something like that. If not clearing the LCD is the problem then its position within your If statements is probably the key.

If you could add those code tags to your original post we could figure out where to try the lcd.clear()
https://github.com/PangolinPaw

ame
Posts: 3172
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 8:58 pm

What is the actual output of this command?

Code: Select all

mpc current | tail -c25

pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 10:13 pm

Thanks, Pangolin and Dougie for the tip. The original code has bee placed into the proper tags. Obvious newb on forum. Ame, the output of the tail command would ouput the last 25 bytes of the current artist/song on the radio station. However, sometimes it doesn't display the artist and song title as this depends on the radio station streaming site. It's not the best way, just was playing with this type of command.

ame
Posts: 3172
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 10:17 pm

pi_noob wrote:Thanks, Dougie for the tip. The original code has bee placed into the proper tags. Obvious newb on forum. Ame, the output of the tail command would ouput the last 25 bytes of the current artist/song on the radio station. However, sometimes it doesn't display the artist and song title as this depends on the radio station streaming site. It's not the best way, just was playing with this type of command.
I know what the command does, but my purpose for asking was to know *exactly* what the output of the command is. You said it corrupts the display, so it's quite possible that there are junk characters in those 25 bytes that do odd things to the display.

pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 10:20 pm

I have even tried using the mpc current command.

pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

Re: Garbled Text on LCD only when running certain Python scr

Tue Jan 13, 2015 11:46 pm

I've tried adjusting the self.delayMicroseconds(1)" on both for the pulseEnable function..no dice. Any other suggestions?

I've added functions in the script. Here is the added code if anyone wants to try it out and get back to me, please.

Code: Select all

# ----------------------------
# RADIO SETUP MENU
# ----------------------------

MENU_LIST = [
   '1. Display Time \n   & IP Address ',
   '2. Output Audio \n   to HDMI      ',
   '3. Output Audio \n   to Headphones',
   '4. Auto Select  \n   Audio Output ',
   '5. Song        \n     Track       ',
   '6. Reboot       \n   Reboot       ',
   '7. System       \n   Shutdown!    ',
   '8. Exit         \n                ']

def menu_pressed():
   global MENU_LIST

   item = 0
   LCD.clear()
   LCD.message(MENU_LIST[item] )

   keep_looping = True
   while (keep_looping):

      # Wait for a key press
      press = read_switches()

      # PREV button
      if(press == 1):
         item -= 1
         if(item < 0):
            item = len(MENU_LIST) - 1
         LCD.clear()
         LCD.message(MENU_LIST[item] )

      # NEXT button
      elif(press == 2):
         item += 1
         if(item >= len(MENU_LIST)):
            item = 0
         LCD.clear()
         LCD.message(MENU_LIST[item] )

      # BOTH buttons together, This is "Select"
      elif(press == 3):
         keep_looping = False

         # Take action
         if(  item == 0):
            # display time and IP address
            display_ipaddr()
            
         elif(item == 1):
            # output to HDMI
            output = run_cmd("amixer -q cset numid=3 2")
         
         elif(item == 2):
            # output to headphone jack
            output = run_cmd("amixer -q cset numid=3 1")
         
         elif(item == 3):
            # output auto-select
              output = run_cmd("amixer -q cset numid=3 0")

         elif(item == 4):
            # Check artist/title info
              #output = run_cmd("mpc current")  
              load_playlist()
              getTrack()
         elif(item == 5):
            #reboot the system
            output = run_cmd("mpc clear")
            output = run_cmd("sudo reboot")

         elif(item == 6):
            #shutdown the system
            output = run_cmd("mpc clear")
            output = run_cmd("sudo halt -p")
      else:
         delay_milliseconds(100)

   # Restore display
   LCD.clear()
   LCD.message(PLAYLIST_MSG[STATION - 1] )

def load_playlist():
   global STATION, NUM_STATIONS, PLAYLIST_MSG

   # Run shell script to add all stations
   # to the MPC/MPD music player playlist
   output = run_cmd("mpc clear")
   output = run_cmd("/home/pi/projects/radio/radio_playlist.sh")

   # Load PLAYLIST_MSG list
   PLAYLIST_MSG = []
   with open ("/home/pi/projects/radio/radio_playlist.sh", "r") as playlist:
      # Skip leading hash-bang line
      for line in playlist:
         if line[0:1] != '#!':  
               break
      # Remaining comment lines are loaded
      for line in playlist:
         if line[0] == "#" :
            PLAYLIST_MSG.append(line.replace(r'\n','\n')[1:-1] + "                ")
   playlist.close()
   NUM_STATIONS = len(PLAYLIST_MSG)



def getTrack():
   L= [S.strip('\n') for S in os.popen('mpc').readlines()]        # Get the Track info from the stdout of the mpc command
   output = run_cmd("mpc current | tail -c25")
   station = output [0:20]                                           # Pick out the Station and Track info
   track =  output [-21:-1]
   LCD.message(station + " "*(20 - len(station)), 0, 0)
   LCD.message(track + " "*(20 - len(track)), 0, 1) 

pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

Re: Garbled Text on LCD only when running certain Python scr

Sat Jan 17, 2015 2:20 am

After endless programming, I resolved this by modifying certain functions. You may close out this post.

User avatar
rpdom
Posts: 17172
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Garbled Text on LCD only when running certain Python scr

Sat Jan 17, 2015 6:08 am

How about posting your solution so that others may benefit from your experience? :)

(You can't "close" the post, but you can edit the thread title on your first post and add [SOLVED] to show it as fixed)

pi_noob
Posts: 8
Joined: Tue Jan 13, 2015 4:28 am

Re: [SOLVED]Garbled Text on LCD only when running Pyton scri

Fri Jan 23, 2015 1:03 am

Sorry for the delay. The reason for my garbled text, as strange as this sounds, was some faulty coding. I used the os.system commands, for example:

Code: Select all

 if ( GPIO.input(PIN_SW3_PAUSE) == True):
          os.system("mpc pause")

Return to “Beginners”