Permalink
Browse files

Significant changes based on live testing of the code on the Telit GM…

…862-GPS

module:

1. The module does not support floating point and so the gpt2.get() function has been modified to only use integer arithmetic and thus not do conversion of latitude and longitude.  This leaves most of the returned elements as strings.  Except altitude which is needed for comparisons.

2. The main loop is wrapped in the try/except that will hide any inflight errors (although they will be logged to the log file).  I hope this will never be called.

3. The timeout on SMS message sending has been increased from the default to 30 seconds because it can take a while to send the message and this was corrupting the return from the temperature command.

4. Improved handling of timestamps to make it clearer in the SMS messages when a message occurred.

5. Modified the upload script to delete the .pyo files for uploaded .py files so that the module will recompile and not use the previous version.
  • Loading branch information...
jgrahamc committed Nov 20, 2010
1 parent e4feb38 commit 2811ca675040af17d0fb3713dd732d1ec69ccbb0
View
@@ -31,4 +31,5 @@ upload: $(UPL)
@touch $@
.PHONY: test
+test:
@python gaga-1.py
View
@@ -20,3 +20,8 @@ TODO
1. Need to contact Telit and ask them what happens to GPS access above
the COCOM limit to make sure gps2 module handles the failure more
correctly.
+
+2. Should delete all files on the Telit module with a clean Makefile
+command
+
+3. Performs check the checksum of the loaded scripts in upload
View
@@ -14,10 +14,12 @@
import MOD
+import sys
import sms
import gps2
import phone
import util
+import logger
# Given a dictionary from the GPS reports the current location via SMS
# if it is valid. Should be passed the position from gps2.get().
@@ -26,12 +28,13 @@
# for battery voltage and the current module internal temperature
def report_position(p):
+ global state
v = gps2.voltage()
t = util.temperature()
- i = '(%dmV, %dC)' % ( v, t )
+ i = '(%dmV, %dC, %s)' % ( v, t, state )
if p['valid']:
- send_sms( '%s %s %.2fm %.2fdeg %.2fkph %dsats %s' % ( p['latitude'],
+ send_sms( '%s %s %dm %sdeg %skph %ssats %s' % ( p['latitude'],
p['longitude'], p['altitude'], p['course'], p['speed'],
p['satellites'], i ) )
else:
@@ -70,10 +73,11 @@ def send_sms(m):
# altitude it transitions to Recovery mode.
state = ''
-set_state( 'LAUNCH' )
sms.init()
gps2.init()
+set_state( 'LAUNCH' )
+
# The rules for the states are as follows:
#
# Launch: get GPS position every 1 minute and SMS, check for
@@ -88,27 +92,35 @@ def send_sms(m):
# Recovery: get GPS position every 1 minute and SMS
while 1:
- position = gps2.get()
-
- if state == 'LAUNCH':
- report_position(position)
- if position['valid'] and ( position['altitude'] > ascent_altitude ):
- set_state( 'ASCENT' )
- elif state == 'ASCENT':
- report_position(position)
- if position['valid'] and ( position['altitude'] > flight_altitude ):
- set_state( 'FLIGHT' )
- elif state == 'FLIGHT':
- if position['valid'] and ( position['altitude'] < recovery_altitude ):
- set_state( 'RECOVERY' )
- elif state == 'RECOVERY':
- report_position(position)
-
- if state == 'LAUNCH' or state == 'RECOVERY':
- delay = 1
- elif state == 'ASCENT':
- delay = 2
- else:
- delay = 5
+ try:
+ position = gps2.get()
+
+ if state == 'LAUNCH':
+ report_position(position)
+ if position['valid'] and \
+ ( position['altitude'] > ascent_altitude ):
+ set_state( 'ASCENT' )
+ elif state == 'ASCENT':
+ report_position(position)
+ if position['valid'] and \
+ ( position['altitude'] > flight_altitude ):
+ set_state( 'FLIGHT' )
+ elif state == 'FLIGHT':
+ if position['valid'] and \
+ ( position['altitude'] < recovery_altitude ):
+ set_state( 'RECOVERY' )
+ elif state == 'RECOVERY':
+ report_position(position)
+
+ if state == 'LAUNCH' or state == 'RECOVERY':
+ delay = 1
+ elif state == 'ASCENT':
+ delay = 2
+ else:
+ delay = 5
+
+ MOD.sleep(delay * 600)
+
+ except:
+ logger.log( "Caught exception in main loop: %s" % sys.exc_info()[1] )
- MOD.sleep(delay * 600)
View
@@ -19,34 +19,20 @@ def init():
# The utc is the UTC time from the GPS. course is the cog, satellites
# is the nsat value. speed is the spkm (km/h) and valid indicates
# whether the GPS has a 3D fix.
-#
-# Conversions performed:
-#
-# utc, altitude, course and speed converted to float
-# satellites converted to int
-# longitude and latitude converted to decimal degrees
def get():
p = GPS.getActualPosition()
logger.log( 'gps2.get() -> %s' % p )
a = p.strip().split(',')
if len(a) == 11 and int(a[5]) == 3:
- global lastaltitude
- latd = int(a[1][0:2])
- latm = float(a[1][2:-1])
- latc = a[1][-1]
- lat = '%.4f%s' % ( latd + latm / 60, latc )
- lond = int(a[2][0:3])
- lonm = float(a[2][3:-1])
- lonc = a[2][-1]
- lon = '%.4f%s' % ( lond + lonm / 60, lonc )
- return { 'latitude' : lat,
- 'longitude' : lon,
- 'altitude' : float(a[4]),
- 'utc' : float(a[0]),
- 'course' : float(a[6]),
- 'satellites' : int(a[10]),
- 'speed' : float(a[7]),
+ altitude = int(a[4].split('.')[0])
+ return { 'latitude' : a[1],
+ 'longitude' : a[2],
+ 'altitude' : altitude,
+ 'utc' : a[0],
+ 'course' : a[6],
+ 'satellites' : a[10],
+ 'speed' : a[7],
'valid' : 1
}
else:
@@ -3,7 +3,8 @@
# Copyright (c) 2010 John Graham-Cumming
import SER
-import MOD
+
+import util
log_file = 'gaga-1.log'
@@ -13,8 +14,8 @@
# to.
def log(m):
- t = MOD.secCounter()
- d = '%d: %s\r' % (t, m)
+ t = util.timestamp()
+ d = '%s: %s\r' % (t, m)
SER.send(d)
try:
f = open( log_file, 'a' )
View
@@ -4,6 +4,7 @@
import at
import logger
+import util
# Set up SMS by turning on text mode using the AT+CMGF command
@@ -33,13 +34,17 @@ def can():
return ( int(m[0]) != 99 ) and ( int(m[1]) != 99 )
# Send a message to a specified phone number
+#
+# Note that when sending the message the wait time for a response is
+# increased to 30 seconds as sending the SMS may take time.
def send(phone, text):
logger.log( 'sms.send(%s...,"%s")' % ( phone[0:4], text ) )
if can():
r = at.cmd( 'AT+CMGS="%s"' % phone )
if r == '\r\n> ':
- r = at.raw( '%s\x1A' % text )
+ t = util.timestamp()
+ r = at.raw( '%s: %s\x1A' % ( t, text ), 30 )
else:
r = at.raw( '\x1B' )
logger.log( 'Failed to get SMS prompt' )
View
@@ -60,6 +60,18 @@
die "Failed to verify that script was uploaded\n";
}
+# If we are uploading a .py file instead of a .pyo check to see if
+# there's a .pyo file with the same name and delete it. This is
+# needed because the Telit won't recompile the .py file automatically.
+
+if ( $ARGV[0] =~ /\.py$/ ) {
+ my $pyo = "$ARGV[0]o";
+ if ( $r =~ /#LSCRIPT: \"$pyo\"/ ) {
+ $r = cmd( $port, "AT#DSCRIPT=\"$pyo\"", $oke );
+ die "Failed to delete .pyo file\n" if ( $r !~ /OK/ );
+ }
+}
+
exit 0;
sub cmd
View
@@ -2,7 +2,12 @@
#
# Copyright (c) 2010 John Graham-Cumming
+import MOD
+
import at
+import logger
+
+epoch = -1
# Retrieves the internal temperature of the module and returns it,
# returns -1000 if something goes wrong
@@ -21,10 +26,26 @@ def temperature():
w = t.split()
if len(w) < 2:
+ logger.log( "Temperature read returned %s" % t )
return -1000
m = w[1].split(',')
if len(m) != 2:
+ logger.log( "Temperature read returned %s" % t )
return -1000
else:
return int(m[1])
+
+# Gets the time since start in seconds and returns a string of the
+# form T+nnn.
+
+def timestamp():
+ t = MOD.secCounter()
+
+ global epoch
+ if epoch < 0:
+ epoch = t
+
+ t = t - epoch
+
+ return "T+%d" % t

0 comments on commit 2811ca6

Please sign in to comment.