Python Forum
Need my program to run concurrent operations
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need my program to run concurrent operations
#1
Rasberry Pi Model B  running Rasbian  (Debian 8) Linux,  Python 3.4

I have a Raspberry Pi, rotary encoder and an OLED serial display, AXE133Y details below:
http://www.picaxe.com/Hardware/Add-on-Mo...LED-Module

There is no python code or module available for this display so I wrote one and called it oled.py
It allows for clearing the display, displaying a message at line 1 or 2 or any character position and
scrolling text.

I am using mpd (Music Player deamon) to play internet radio via ethernet. The station
is selected with the rotary switch and the current track being played is sent to the serial
display. The display scrolls the artist/track which can take 5 or 10 seconds depending on number
of characters in the track information.

And that delay blocks the program from reading the rotary switch.
I need to add either threading (or multiprocessing), pass the artist/track information and be
ready to read the rotary switch information again.

I have created a module for the switch and display rotary_mod.py   and  oled.py
The main program is rotary_test.py

rotary_test.py   (Main program)
from RPi import GPIO
from time import sleep
import rotary_mod
import oled
import subprocess
oled.clr()

while True:
       #  Call rotary_mod.function() returns rotary position and switch state
       counter=rotary_mod.function()[0]
       switch=rotary_mod.function()[1]
       oled.msg(str(counter))
       if (counter == 7 and switch == 0):
               subprocess.call('mpc play 1', shell=True)
               oled.clr(1)
               oled.msg("Cinemix",1,4)
               track = subprocess.call('mpc current', shell=True)
               oled.scroll(str(track),2)

       if (counter == 8 and switch == 0):
               subprocess.call('mpc stop', shell=True)
               oled.msg("Stop Cinemix",2,2)
               sleep(2)
               oled.clr()

       sleep(0.001)
rotary_mod.py  (Rotary switch module)
from RPi import GPIO
from time import sleep

clk = 17
dt = 18
sw = 27
GPIO.setmode(GPIO.BCM)
GPIO.setup(clk, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(dt, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(sw, GPIO.IN, pull_up_down=GPIO.PUD_UP)
counter = 0
clkLastState = GPIO.input(clk)

def function():
               clkState = GPIO.input(clk)
               dtState = GPIO.input(dt)
               global switch
               switch = GPIO.input(sw)
               global clkLastState,counter
               if clkState != clkLastState:
                       sleep(0.005) # contact settle:
                       if dtState != clkState:
                               counter += 1
                       else:
                               counter -= 1
               clkLastState = clkState
               return(counter,switch)  # return count pstn and switch on or off
oled.py  (OLED AXE133Y module)
#!/usr/bin/python3
import serial
import sys
from time import sleep

PORT="/dev/ttyAMA0"
BAUDRATE=2400
BYTESIZE=8
PARITY='N'
STOPBITS=1
TIMEOUT=3.0

s=serial.Serial(PORT,BAUDRATE,BYTESIZE,PARITY,STOPBITS,TIMEOUT)
# Timing Constants 5ms for OLED
DELAY=0.005

def cmd(a,b=0): # sends single or double command to display e.g cmd(254,128) print at line 1
 s.write ((chr(a)).encode('latin_1'))
 sleep(0.005)
 if b==0:
   return
 else:
   s.write ((chr(b)).encode('latin_1'))
   sleep(0.005)
   return

def clr(line=0):
 cmd(254,2) # unshift display  
 if (line == 1):
   cmd(254,128) 
   clear()   
   cmd(254,128) # reset to L1, Pos1
 elif (line == 2):
    cmd(254,192)
    clear()    
    cmd(254,192)
 else:
   cmd(254,1)
   sleep(0.3)


def chars(message):  # convert each character to ASCII code and send to display
  for ch in message:
         op = ord(ch)   
         s.write((chr(op)).encode('ascii'))
         sleep(0.005)


def msg(text, line=1, pos=1):
 cmd(254,2) # unshift display
 if line == 2:
   cmd(254,(pos+191))
   chars(text)
 else:
   cmd(254,(pos+127))
   chars(text)    

def scroll(msg):
 msg=(" "+msg+" ")
 for i in range(len(msg)):
   cmd(254)   # write at (254,x) where x is char position from next line
   s.write((chr(127+i)).encode('latin_1'))
   sleep(0.1) # speed
   op = ord(msg[i])
   s.write((chr(op)).encode('ascii'))
   sleep(0.005)
For clarity, in the main program code for only two positions of the rotary switch are shown, switch 7 + rotary
switch button plays the first station in the mpc playlist (mpc play 1) and postion 8 + rotary switch button is
used to stop the stream (mpc stop). The station playlist in mpc is first loaded outside the program, with command
mpc load stations. 'stations' is just a text file containing URL of station.

I found some documentation on threading:
https://pymotw.com/3/threading/

but at the moment its beyond my grasp how to make my script use threading.
I'll just add some additional notes about the main program:
oled.clr(1)
oled.msg("Cinemix",1,4)
track = subprocess.call('mpc current', shell=True)
oled.scroll(str(track),2)

The OLED display has two lines of 16 characters, oled.clr(1) clears first line.
oled.msg("Cinemix", 1,4) displays station name starting line1, character 4
Line 3 variable 'track' will hold the artist/track information from output of 'mpc current'
oled.scroll(str(track),2)   Scrolls the artisl/track information on line 2 of the display, can take
5 or 10 seconds which is why I need threading or multiprocessing.


Finally, sorry for long message this is quite a big ask.
If it cannot be done in python, I can solve it other ways, passing the info to an Arduino
and getting the Arduino to take care of the display routine.

Thanks in advance.
Will provide a schematic should anyone want one.
Reply
#2
This from Python 3.6.2 docs:

concurrent.futures:
Quote:The concurrent.futures module provides a high-level interface for asynchronously executing callables.

The asynchronous execution can be performed with threads, using ThreadPoolExecutor, or separate processes, using ProcessPoolExecutor. Both implement the same interface, which is defined by the abstract Executor class.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Replicate Excel operations with Python Lumberjack 3 1,809 May-10-2022, 01:44 AM
Last Post: Lumberjack
  Class variables and Multiprocessing(or concurrent.futures.ProcessPoolExecutor) Tomli 5 3,875 Nov-12-2021, 09:55 PM
Last Post: snippsat
  Problem with concurrent.futures. thunderspeed 3 2,043 Sep-01-2021, 05:21 PM
Last Post: snippsat
  concurrent.futures help samuelbachorik 2 1,742 Aug-22-2021, 07:20 AM
Last Post: bowlofred
  Program demonstrates operations of bitwise operators without using bitwise operations ShawnYang 2 1,781 Aug-18-2021, 03:06 PM
Last Post: deanhystad
  Random Choice Operations Souls99 6 2,922 Jul-31-2020, 10:37 PM
Last Post: Souls99
  Create bot to automate operations in IQ Option JonatasCavalini 0 12,475 Jul-19-2020, 02:23 AM
Last Post: JonatasCavalini
  Two operations in two ranges salwa17 3 2,126 Jun-22-2020, 04:15 PM
Last Post: perfringo
  Trying to understand concurrent.futures.ThreadPoolExecutor Laxminarsaiah 0 1,615 Dec-18-2019, 12:43 PM
Last Post: Laxminarsaiah
  How to avoid slow cursor operations? sevensixtwo 0 1,839 Oct-11-2019, 02:23 PM
Last Post: sevensixtwo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020