Python Forum

Full Version: reset on inactivity (building a morse decoder)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Dear Forum users,

for our museum i`m building a simpel morse decoder program. it is working with a very simple script that i changed a little bit.

Stil i have a little issue that i can`t solve
First here part the code:

#!/usr/bin/python3
import pygame
import time
import gpiozero as gpio
import _thread as thread
from array import array
from pygame.locals import *
from morse_lookup import *

import os
 
os.system("clear") # Linux - OSX

pygame.mixer.pre_init(44100, -16, 1, 1024)
pygame.init()
class ToneSound(pygame.mixer.Sound):
    def __init__(self, frequency, volume):
        self.frequency = frequency
        pygame.mixer.Sound.__init__(self, self.build_samples())
        self.set_volume(volume)

    def build_samples(self):
        period = int(round(pygame.mixer.get_init()[0] / self.frequency))
        samples = array("h", [0] * period)
        amplitude = 2 ** (abs(pygame.mixer.get_init()[1]) - 1) - 1
        for time in range(period):
            if time < period / 2:
                samples[time] = amplitude
            else:
                samples[time] = -amplitude
        return samples

def decoder_thread():
    global key_up_time
    global buffer
    new_word = False
    while True:
        time.sleep(.01)
        key_up_length = time.time() - key_up_time
        if len(buffer) > 0 and key_up_length >= 1.5:
            new_word = True
            bit_string = "".join(buffer)
            try_decode(bit_string)
            del buffer[:]
        elif new_word and key_up_length >= 4.5:
            new_word = False
            sys.stdout.write(" ")
            sys.stdout.flush()

tone_obj = ToneSound(frequency = 800, volume = .5)

pin = 4
key = gpio.Button(pin, pull_up=True)

DOT = "."
DASH = "-"

key_down_time = 0
key_down_length = 0
key_up_time = 0
buffer = []

thread.start_new_thread(decoder_thread, ())

print("Welkom bij de morse emulator van maritiem centrum Ameland")

while True:
    key.wait_for_press()
    key_down_time = time.time() #record the time when the key went down
    tone_obj.play(-1) #the -1 means to loop the sound
    key.wait_for_release()
    key_up_time = time.time() #record the time when the key was released
    key_down_length = key_up_time - key_down_time #get the length of time it was held down for
    tone_obj.stop()
    buffer.append(DASH if key_down_length > 0.20 else DOT)
I want to restart or reset the program when there is a idle time of 2 minutes, so when a new gast arrives the screen is blank. can anybody help me with that?
while True:
    key.wait_for_press(timeout) # timeout is seconds as a float, 120 = 2mins
    if not key.is_pressed():
        resetstuff()
    else:
        key_down_time = time.time() #record the time when the key went down
        tone_obj.play(-1) #the -1 means to loop the sound
(Apr-09-2020, 12:26 PM)deanhystad Wrote: [ -> ]
while True:
    key.wait_for_press(timeout) # timeout is seconds as a float, 120 = 2mins
    if not key.is_pressed():
        resetstuff()
    else:
        key_down_time = time.time() #record the time when the key went down
        tone_obj.play(-1) #the -1 means to loop the sound

Thank you very much, i tried it but i get following response:

Quote:File "./morse-code2.py", line 72
else:
^
IndentationError: unindent does not match any outer indentation level


while True:
    key.wait_for_press(120)
if not key.is_pressed():
    os.system("clear") # Linux - OSX
    print("Welkom bij de morse emulator van maritiem centrum Ameland")
    else:
    key_down_time = time.time() #record the time when the key went down
    tone_obj.play(-1) #the -1 means to loop the sound
    key.wait_for_release()
    key_up_time = time.time() #record the time when the key was released
    key_down_length = key_up_time - key_down_time #get the length of time it was held down for
    tone_obj.stop()
    buffer.append(DASH if key_down_length > 0.20 else DOT)
Indentation is how Python blocks code. Other languages use start and end markers, but in python you indicate which code is inside an if statement by indentation. The code below is a valid if/else.
while True:
    key.wait_for_press(120)
    if not key.is_pressed():
        os.system("clear") # Linux - OSX
        print("Welkom bij de morse emulator van maritiem centrum Ameland")
    else:
        key_down_time = time.time() #record the time when the key went down
        tone_obj.play(-1) #the -1 means to loop the sound
        key.wait_for_release()
This code complains about the "else:" because then indentation of the "print" command is an end marker for the "if" statement
while True:
    key.wait_for_press(120)
    if not key.is_pressed():
        os.system("clear") # Linux - OSX
    print("Welkom bij de morse emulator van maritiem centrum Ameland")
    else:
        key_down_time = time.time() #record the time when the key went down
        tone_obj.play(-1) #the -1 means to loop the sound
        key.wait_for_release()
The equivalent C code is:
while (1)
{
    wait_for_press(key, 120)
    if (!is_pressed(key))
    {
        os_system_clear()
    }
    print("Welkom bij de morse emulator van maritiem centrum Ameland");
    else
    {
        key_down_time = time()
        tone_obj_play(-1)
        wait_for_release(key)
    }
(Apr-15-2020, 12:40 PM)deanhystad Wrote: [ -> ]Indentation is how Python blocks code. Other languages use start and end markers, but in python you indicate which code is inside an if statement by indentation. The code below is a valid if/else.
while True:
    key.wait_for_press(120)
    if not key.is_pressed():
        os.system("clear") # Linux - OSX
        print("Welkom bij de morse emulator van maritiem centrum Ameland")
    else:
        key_down_time = time.time() #record the time when the key went down
        tone_obj.play(-1) #the -1 means to loop the sound
        key.wait_for_release()
This code complains about the "else:" because then indentation of the "print" command is an end marker for the "if" statement
while True:
    key.wait_for_press(120)
    if not key.is_pressed():
        os.system("clear") # Linux - OSX
    print("Welkom bij de morse emulator van maritiem centrum Ameland")
    else:
        key_down_time = time.time() #record the time when the key went down
        tone_obj.play(-1) #the -1 means to loop the sound
        key.wait_for_release()
The equivalent C code is:
while (1)
{
    wait_for_press(key, 120)
    if (!is_pressed(key))
    {
        os_system_clear()
    }
    print("Welkom bij de morse emulator van maritiem centrum Ameland");
    else
    {
        key_down_time = time()
        tone_obj_play(-1)
        wait_for_release(key)
    }


Thank you very much for the explanation.

Now i have the next problem i can't solve or understand.

Quote:Traceback (most recent call last):
File "./morse-code2.py", line 69, in <module>
if not key.is_pressed():
TypeError: 'bool' object is not callable
Angry maybe i'm stupid but it`s all new for my.
is_pressed has a True or False value it does not need to be called, remove the ()
if not key.is_pressed():
change to
if not key.is_pressed:
gpiozero.Button.is_pressed
(Apr-15-2020, 01:34 PM)Yoriz Wrote: [ -> ]is_pressed has a True or False value it does not need to be called, remove the ()
if not key.is_pressed():
change to
if not key.is_pressed:
gpiozero.Button.is_pressed

Thanks for the solution it works.

Now if got the next strange problem. Occasionally it looks like the program runs the reset stuf without a reason, sometimes after seconds somtimes after minuts.

When i run it in Mu 1.0.2 for debugging it gives the next "warning" TERM environment variable not set.

Any one an idea?
What exactly do you mean by "Occasionally it looks like the program runs the reset stuf without a reason, sometimes after seconds somtimes after minuts."

The reset should happen whenever the wait_for_press times out. What is your timeout period? Still 120? Then the reset should happen every 2 minutes. When it resets after seconds, is it seconds after pressing the key? Seconds after a prior reset?