Hello, I'm trying to make timer which spit out gps signal every 10 or 60 seconds.

here is my code.

*

**import threading
import time
import serial
import datetime, string
from pynmea import nmea
def init_serial():
    COMNUM = 13  
    global ser  
    ser = serial.Serial()
    ser.baudrate = 9600
    ser.port = 12 
    ser.timeout = 1 
    ser.open() **

def to_degrees(lats, longs): #convert nmea signal to usual altitude, longitude
    lat_deg = lats[0:2]
    lat_mins = lats[2:4]
    lat_secs = round(float(lats[5:])*60/10000, 2)
    lat_str = lat_deg + u'°'+ lat_mins + string.printable[68] + str(lat_secs) + string.printable[63]

    lon_deg = longs[0:3]
    lon_mins = longs[3:5]
    lon_secs = round(float(longs[6:])*60/10000, 2)
    lon_str = lon_deg + u'°'+ lon_mins + string.printable[68] + str(lon_secs) + string.printable[63]
    return [lat_str, lon_str]

def gpgga():  # get gps signal
    data = ser.readline()
    if data[0:6] == "$GPGGA":
        gpgga = nmea.GPGGA()
        gpgga.parse(data)
        lats = gpgga.latitude
        lat_dir = gpgga.lat_direction
        longs = gpgga.longitude
        long_dir = gpgga.lon_direction
        alt = gpgga.antenna_altitude
        time = gpgga.timestamp
        lat_lon = to_degrees(lats, longs)  
        print time   
        print "Latitude: ", lat_lon[0]+lat_dir ,"&", "Longitude: ", lat_lon[1]+long_dir
        print "Altitude: ", alt

class Timer(threading.Thread):  # Repeat timer and here is questions.
    def __init__(self):
        threading.Thread.__init__(self)
        self.event = threading.Event()

    def run(self):
        while not self.event.is_set():
            init_serial()
            print datetime.datetime.now()
            gpgga()
            self.event.wait(14.2857142857142857142857)
            ser.close()

    def stop(self):
        self.event.set()
i=0
while i<100:
    tmr=Timer()
    tmr.start()
    print i
    i=i+1
    tmr.stop()
    time.sleep(10)

ser.close()* 

at the timer part, self.event.wait(14.2857142857142857142857) is waiting function but it didn't work and only time.sleep(10) function works.

what's wrong? and how to fix it

Dani AI

Generated

The symptom is explained by the thread-stop logic rather than a bug in Event.wait. In the posted main loop creates a new Timer, calls start(), then immediately calls stop() — that stop() sets the Event, so any subsequent self.event.wait(timeout) returns immediately. time.sleep() “appears” to work only because it blocks the caller that calls it (main thread), not because Event.wait() is broken.

A simple, correct pattern:

  • Start one background thread (or one Timer instance) and let its run() loop call event.wait(interval) between work cycles.
  • Call stop() only when the repeating work should end.
  • Use the return value of event.wait(timeout) to detect an early wake (it returns True if the event was set).

Example (illustrative, not a drop-in for the original code):

# inside the worker thread
while not stop_event.is_set():
    read_gps_once()
    # returns True if stop_event was set while waiting
    if stop_event.wait(10.0):
        break

Practical cautions for the GPS/serial case: open the serial port once (preferably as an instance attribute, e.g. self.ser) instead of opening/closing it each loop; wrap open/read/close in try/finally to avoid leaks; avoid shared global ser to prevent races; call join() from stop() so the main thread waits for a clean shutdown.

' Condition-based approach is a good alternative when the interval or wake-up needs to be signalled with additional state (use notify() to interrupt a wait). For a simple stop/timeout pattern, Event.wait(timeout) is more straightforward. For stable scheduling (avoiding drift), compute the next absolute run time with time.time() and wait the remaining delta rather than chaining fixed sleeps.

I've always found the threading module easier when Condition instances are used. Here is a periodic timer implemented with a condition:

from __future__ import print_function 
import datetime as dt
import threading as th
import time

class PeriodicTimer(th.Thread):
    def __init__(self, delay):
        th.Thread.__init__(self)
        self.locked = th.Condition()
        self.delay = float(delay)
        assert self.delay > 0.0
        self.stopped = False

    def run(self):
        print("Periodic timer starting")
        self.stopped = False
        with self.locked:
            while not self.stopped:
                print("Periodic timer:", dt.datetime.now())
                self.locked.wait(self.delay)
        print("Periodic timer exiting")

    def stop(self):
        with self.locked:
            self.stopped = True
            self.locked.notify()
        self.join()

if __name__ == '__main__':
    t = PeriodicTimer(0.37)
    t.start()
    time.sleep(3)
    t.stop()

""" my output -->
Periodic timer starting
Periodic timer: 2015-06-03 09:52:42.774104
Periodic timer: 2015-06-03 09:52:43.153796
Periodic timer: 2015-06-03 09:52:43.523985
Periodic timer: 2015-06-03 09:52:43.894159
Periodic timer: 2015-06-03 09:52:44.264333
Periodic timer: 2015-06-03 09:52:44.634513
Periodic timer: 2015-06-03 09:52:45.004683
Periodic timer: 2015-06-03 09:52:45.374836
Periodic timer: 2015-06-03 09:52:45.745005
Periodic timer exiting
"""
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.