0

I would kindly ask for some support with my first program i am trying to write.

I have a raspberry pi 4 and am using the program Thonny and Python 3.9.2.

My program is trying to do the following.

There is a Microphone, and if it hears something it should turn on the yellow light. If it hears something 3 times in a set period of time it will turn on the red light.

The display runs though a script of explination and when the yellow or red light comes on it should switch to those expressions.

This is the problem I am having:

(to the best of my inspection) if the display is trying to change to the next line in the scrip and the yellow LED message is triggered the display gets "confused" and puts out nonsense.

I have tried to tell the display to only put out the discriptive script if the yellow and red light are off, but this didnt seem to really help.

The other observation i have is with the yellow and red LED. If the RED led triggers i want the counter reset on the yellow counter so that both yellow and red stay on for the same time, but the yellow light just stays on for the remainder of its time.sleep cycle.

I am a complete beginner and cant figure this out, is there an interupt command or something i could use here?

Here is the code for reference:

#V02 Trying to clean up the code and remove unessisary lines but working on fixing the strange characters that arrive and trying to get the system to reboot on its own.

import RPi.GPIO as GPIO #starts the IO functionality of the pi
import time # we need this for the sleep function
import threading #threading so we can get more than one thing to run at the same time
from time import sleep #sleep function
GPIO.setmode(GPIO.BCM) # setting for the IO
GPIO.setwarnings(False) #Suppress warnings
GPIO.setup(12,GPIO.OUT) #green
GPIO.setup(16,GPIO.OUT) #yellow
GPIO.setup(20,GPIO.OUT) #red
GPIO.setup(21,GPIO.IN)  #NOISE SENSOR
# GPIO to LCD mapping
LCD_RS = 4 # BCM GPIO 4
LCD_E = 17 # BCM GPIO 17
LCD_D4 = 6 # BCM GPIO 6
LCD_D5 = 13 # BCM GPIO 13
LCD_D6 = 19 # BCM GPIO 19
LCD_D7 = 26 # BCM GPIO 26

# Device constants
LCD_CHR = True # Character mode
LCD_CMD = False # Command mode
LCD_CHARS = 16 # Characters per line (16 max)
LCD_LINE_1 = 0x80 # LCD memory location for 1st line
LCD_LINE_2 = 0xC0 # LCD memory location 2nd line

GPIO.output(16,GPIO.LOW) #set all pins to LOW Start postion for program
GPIO.output(20,GPIO.LOW) #set all pins to LOW Start postion for program
GPIO.output(12,GPIO.LOW) #set all pins to LOW Start postion for program

def Green(): #This is the status LED for the Green LED
    while True:
        GPIO.output(12,GPIO.HIGH)
        time.sleep(2.5)
        GPIO.output(12,GPIO.LOW)
        time.sleep(.5)
        
def Yellow():
    while True:
        if GPIO.input(21) == 1: #this is the microphone sending a detection signal 

            print("Sound Detected")
            GPIO.output(16,GPIO.HIGH) #turn on the yellow LED
            lcd_text("I heard that",LCD_LINE_1)
            lcd_text("Relax",LCD_LINE_2)
            time.sleep(10)
            GPIO.output(16,GPIO.LOW) #turn off the yellow LED
            x = 0
        
def Red():
    x = 0
    while True:
            if GPIO.input(16) == 1 and GPIO.input(21) == 1: #if Yellow light and Microphone activate at the same time we start counter for RED LED 
                    x += 1
                    print(x)
                    time.sleep(.45)
            if x > 2:
                    print("Too noisy in here")
                    GPIO.output(16,GPIO.HIGH)#if the x counter (sound counter) reaches greater than 3 we set the yellow and red LED on for 5 seconds
                    GPIO.output(20,GPIO.HIGH)
                    lcd_text("Schnauze",LCD_LINE_1)
                    lcd_text("sonst Beule",LCD_LINE_2)         
                    time.sleep(10)
                    GPIO.output(20,GPIO.LOW)
                    GPIO.output(16,GPIO.LOW)
                    x = 0
            if GPIO.input(16) == 0: #if the yellow light goes out before we reach x > 2 we set x back to 0
                    x = 0



t1 = threading.Thread(target=Green)
t2 = threading.Thread(target=Yellow)
t3 = threading.Thread(target=Red)

t1.start()
t2.start()
t3.start()



# Define main program code
def main():
 
 GPIO.setwarnings(False)
 GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
 GPIO.setup(LCD_E, GPIO.OUT) # Set GPIO's to output mode
 GPIO.setup(LCD_RS, GPIO.OUT)
 GPIO.setup(LCD_D4, GPIO.OUT)
 GPIO.setup(LCD_D5, GPIO.OUT)
 GPIO.setup(LCD_D6, GPIO.OUT)
 GPIO.setup(LCD_D7, GPIO.OUT)

# Initialize display
 lcd_init()

# Loop - send text and sleep 3 seconds between texts

 while True:
     
       if GPIO.input(16) == 0 and GPIO.input(20) == 0:
         lcd_text("Welcome to",LCD_LINE_1)
         lcd_text("P4DQ",LCD_LINE_2)
         time.sleep(5) # 3 second delay
         lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
         
       if GPIO.input(16) == 0 and GPIO.input(20) == 0:
         lcd_text("I detect loud",LCD_LINE_1)
         lcd_text("noise",LCD_LINE_2)
         time.sleep(5) # 3 second delay
         lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
         
       if GPIO.input(16) == 0 and GPIO.input(20) == 0:
         lcd_text("Green LED",LCD_LINE_1)
         lcd_text("I'm listening",LCD_LINE_2)
         time.sleep(5) # 3 second delay
         lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
         
       if GPIO.input(16) == 0 and GPIO.input(20) == 0:
         lcd_text("Yellow LED",LCD_LINE_1)
         lcd_text("I hear something",LCD_LINE_2)
         time.sleep(5)
         lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
       
       if GPIO.input(16) == 0 and GPIO.input(20) == 0:
         lcd_text("Red LED",LCD_LINE_1)
         lcd_text("It's TOO LOUD :(",LCD_LINE_2)
         time.sleep(5)
         lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
         
       if GPIO.input(16) == 0 and GPIO.input(20) == 0:
         lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
         
  

# End of main program code

# Initialize and clear display
def lcd_init():
 lcd_write(0x33,LCD_CMD) # Initialize
 lcd_write(0x32,LCD_CMD) # Set to 4-bit mode
 lcd_write(0x06,LCD_CMD) # Cursor move direction
 lcd_write(0x0C,LCD_CMD) # Turn cursor off
 lcd_write(0x28,LCD_CMD) # 2 line display
 lcd_write(0x01,LCD_CMD) # Clear display
 time.sleep(0.0005) # Delay to allow commands to process


def lcd_write(bits, mode):
# High bits
 GPIO.output(LCD_RS, mode) # RS

 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():
 time.sleep(0.0005)
 GPIO.output(LCD_E, True)
 time.sleep(0.0005)
 GPIO.output(LCD_E, False)
 time.sleep(0.0005)

def lcd_text(message,line):
 # Send text to display
 message = message.ljust(LCD_CHARS," ")

 lcd_write(line, LCD_CMD)

 for i in range(LCD_CHARS):
     lcd_write(ord(message[i]),LCD_CHR)


#Begin program
try:
 main()

finally:
 lcd_write(0x01, LCD_CMD)
 GPIO.cleanup()
  • I can't dive in to all of the details of your program, but I have written embedded firmware for real medical and industrial products, and if I were assigned to do what you are trying to do, I would not use threads. I would most likely build a [_superloop_](https://stackoverflow.com/a/72262639/801894) program. – Solomon Slow May 16 '22 at 16:39
  • Thank you for the feedback :) I am a total beginner with no real training, so everything is helpful. Thanks for your time! – Halcyon520nm May 17 '22 at 06:30
  • If you want to use thread, I think you should add some state checker or `Lock()` to avoid any thread interruption. – danangjoyoo May 21 '22 at 23:36
  • Thank you Danangjoyoo, I will look into that, my current approch right now is to try to have the treads communicate with each other with Global Variables. But i really am a total beginner and this is tricky stuff for me. Thanks for your idea!!! – Halcyon520nm May 23 '22 at 07:14

0 Answers0