New uTracker on GE865 and UBlox. Small size.
Schematic from GM862 Evaluation Board - USB.
New version (without Telit and additional chips) - here
See this post about how to add accelerometer chip to GM862
Web site and service from gpsgate.com (or install own)
![]()
![]()
no FT232RL - use USB-UART from Philips phone |
with FT232RL |
Compelete in box |
|
This python script support this tracker (with accelerometer chip)
[+] Expand
# STATUS pin use as RED led
# GPIO2 pin use as GREEN led
# GPIO3 (SDA) and GPIO12(SCL) use as I2C bus to LIS3LV02 accelerometer
# Auto shutdown on 25% battery or without change 3 attempts
# ToDo:
# 1. Update program from server (autoupdate)
# 2. Add UDP/SMS control channel (from server)
# 3. Add support to IO expander (8 out - MC33291 / 8 in)
# All LOCALS variables define in LOCALS.py
"""
# Set maximum send attemps or 0 to infinit
maxTrial = 0
# Server name or ip
server = ''
# Host name or ip (= server)
host = ''
# Page url to accept request
url = ''
# User name
http_user = ''
# User password
http_pass = ''
# GPRS parameters
cgdcont = ''
gprsuserid = ''
gprspassw = ''
# Interval between data upload to server in seconds
intervalNormal = 15
# Interval between no fix GPS location in seconds
intervalError = 10
# Interval to power check in 1/10 second
intervalPower = 20
maxPowerTrials = 3
# SIM pin number
pin = ''
imei=''
"""
import sys
import MOD
import MDM
import SER
import GPIO
import GPS
import IIC
import LOCALS
# Number of RED blinks on error
POWER_FAIL = 1
GPS_ERROR = 2
CONNECT_ERROR = 3
RESPONSE_ERROR = 4
LIS3LV02_READ_ERROR = 5
PIN_ERROR = 6
CREG_ERROR = 7
GPRS_ERROR = 8
IMEI_ERROR = 9
LIS3LV02_INIT_ERROR = 10
# Power save timeout in seconds at battery level = 25
powerSave = 10
attemptToPIN = 20
attemptToCREG = 20
attemptToCGATT = 20
attemptToIMEI = 2
class LIS3LV02:
def __init__(self):
self.LIS3LV02_ADDR = 0x1D
GPIO.setIOdir(13, 0, 0)
self.i2cbus = IIC.new(3, 12, self.LIS3LV02_ADDR)
self.Error = 0
self.Data = [0,0,0]
if (self.i2cbus.init() == -1):
print 'LIS3LV02 initialization error (1)'
self.Error = 1
elif (self.i2cbus.readwrite('\x20\x87', 0) == -1):
print 'LIS3LV02 initialization error (2)'
self.Error = 2
else:
ret = self.i2cbus.readwrite('\x0F', 1)
if (len(ret) == 1 and ord(ret[0]) == 0x3A):
self.Error = 0
else:
print 'LIS3LV02 initialization error (3) : ' + ret
self.Error = 3
def Read(self):
self.Data[0] = 0
self.Data[1] = 0
self.Data[2] = 0
if (self.Error == 0 or self.Error == 4):
ret = self.i2cbus.readwrite('\xA8', 6)
if (ret == -1):
self.Error = 4
print 'LIS3LV02 read error : %s' + ret
elif (len(ret) != 6):
self.Error = 4
print 'LIS3LV02 read error : %s' + ret
else:
self.Error = 0
for i in range(0,3):
k = ord(ret[i * 2 + 1])
k = k << 8;
k = k + ord(ret[i * 2])
if (k > 32767):
k = k - 65536
self.Data[i] = k;
return self.Data
def Send(data):
MDM.send(data, 5)
def SendCmd(command, expected='OK\r\n', timeout=2, addCR = 1):
timer = MOD.secCounter() + timeout
if (addCR == 1):
MDM.send(command + '\r', 5)
else:
MDM.send(command, 5)
response = command + MDM.read()
while (MOD.secCounter() < timer and response.find(expected) == -1):
response = response + MDM.read()
return response
def SendCmd5(cmd):
return SendCmd(command=cmd, timeout=5)
def GetLocation():
latitude = ''
longitude = ''
empty = ('', '', '', '', '', '', '')
position = GPS.getPosition()
if (position[0] == 0):
return empty
lat1 = str(position[0])
lon1 = str(position[2])
lat2 = lat1[0:len(lat1) - 7] + '.' + lat1[len(lat1) - 7:len(lat1)]
lon2 = lon1[0:len(lon1) - 7] + '.' + lon1[len(lon1) - 7:len(lon1)]
if (position[1] == 'S'):
latitude = '-' + lat2
else:
latitude = lat2
if (position[3] == 'W'):
longitude = '-' + lon2
else:
longitude = lon2
acp = GPS.getActualPosition()
acp = acp.replace('$GPSACP: ', '')
acparr = acp.split(',')
if (len(acpos) == 11):
if (acpos[9] != '' and acpos[0] != '' and acpos[4] != '' and acpos[8] != '' and acpos[6] != ''):
return (latitude, longitude, acpos[4], acpos[8], acpos[6], acpos[9], acpos[0])
else:
print 'Wrong ACP format. Empty actual position'
else:
print 'Wrong ACP format. Bad length.'
return empty
def GetSpeed():
acp = GPS.getActualPosition()
acp = acp.replace('$GPSACP: ', '')
acpos = acp.split(',')
if (len(acpos) == 11):
if (len(acpos[8]) > 0):
return Str2Int(acpos[8])
else:
print 'Wrong ACP format. Bad length.'
return 0
def BlinkRed(times):
BlinkGreenOff()
while(times > 0):
SendCmd('AT#SLED=1')
MOD.sleep(1)
SendCmd('AT#SLED=0')
MOD.sleep(1)
times = times - 1
BlinkGreenOn()
def BlinkGreenOff():
GPIO.setIOvalue(2, 0)
def BlinkGreenOn():
GPIO.setIOvalue(2, 1)
def BlinkGreen(times):
MOD.sleep(5)
while(times > 0):
GPIO.setIOvalue(2, 0)
MOD.sleep(1)
GPIO.setIOvalue(2, 1)
MOD.sleep(1)
times = times - 1
def InitModem():
trial = LOCALS.maxTrial
while (LOCALS.maxTrial == 0 or trial > 0):
trial = trial - 1
while (1 == 1):
# Check PIN ready
retry = attemptToPIN
fail = 1
while (retry > 0):
retry = retry - 1
response = SendCmd5('AT+CPIN?')
if (response.find('READY') > 0):
fail = 0
break
if (response.find('SIM PIN') > 0):
if (LOCALS.pin != ''):
response = SendCmd5('AT+CPIN=' + LOCALS.pin)
print response
else:
BlinkRed(PIN_ERROR)
print 'PIN not define.'
return 0
if (response.find('OK') > 0):
fail = 0
break
BlinkRed(PIN_ERROR)
print 'SIM not ready.'
MOD.sleep(50)
if (fail == 1):
break
retry = attemptToCREG
fail = 1
while (retry > 0):
retry = retry - 1
response = SendCmd5('AT+CREG?')
if (response.find('0,1') > 0 or response.find('0,5') > 0):
fail = 0
break
BlinkRed(CREG_ERROR)
print 'Not registered into network.'
MOD.sleep(50)
if (fail == 1):
break
response = SendCmd('AT+CGDCONT=1,"ip","' + LOCALS.cgdcont + '";#USERID="' + LOCALS.gprsuserid + '";#PASSW="' + LOCALS.gprspassw + '"')
retry = attemptToCGATT
fail = 1
while (retry > 0):
retry = retry - 1
response = SendCmd5('AT+CGATT?')
if (response.find('+CGATT: 1') > 0):
fail = 0
break
BlinkRed(GPRS_ERROR)
print 'Not attached to GPRS.'
MOD.sleep(10)
if (fail == 1):
break
retry = attemptToIMEI
fail = 1
while (retry > 0):
retry = retry - 1
response = SendCmd('AT+CGSN')
arr = response.split('\r\n')
LOCALS.imei=arr[1]
if (len(LOCALS.imei) > 0):
fail = 0
break;
BlinkRed(IMEI_ERROR)
print 'No IMEI.'
MOD.sleep(5)
if (fail == 1):
break
return 1
MOD.sleep(50)
return 0
def GetResponse():
timeEnd = MOD.secCounter() + 20
response = MDM.receive(2)
while (MOD.secCounter() < timeEnd):
response = response + MDM.receive(2)
if (response.find('\nOK') > 0 or response.find('\nERROR') > 0):
break
return response
def Disconnect():
response = SendCmd('+++', 'NO CARRIER\r\n', 20, 0)
return response
def CheckPower():
response = SendCmd('AT+CBC')
arr = response.split('\r\n')
response = arr[1]
response = response.replace('+CBC: ', '')
arr = response.split(',')
return (int(arr[0]), int(arr[1]))
def IsOnBattery():
power = CheckPower()
if (power[0] == 0):
return 1
return 0
def CheckCFUN():
response = SendCmd('AT+CFUN?')
if (response.find('+CFUN: 4') >= 0):
SendCmd('AT+CFUN=1')
print 'Set CFUN=1'
return 1
return 0
def ProcessAccData(data, newData, speed, copy=0):
if (copy == 1):
for i in range(0,3):
j = i * 2
k = newData[i]
data[j] = k
data[j + 1] = k
data[6] = speed
data[7] = speed
else:
for i in range(0,3):
j = i * 2
data[j] = max(data[j], newData[i])
data[j + 1] = min(data[j + 1], newData[i])
data[6] = max(data[6], speed)
data[7] = min(data[6], speed)
def Str2Int(str):
if (len(str) > 0):
if (str.find('.') > 0):
return int(str[0:str.find('.')])
else:
return int(str)
else:
return 0
def main():
trial = LOCALS.maxTrial
power = CheckPower()
while ((LOCALS.maxTrial == 0 or trial > 0) and power[0] == 0 and power[1] == 25):
trial = trial - 1
BlinkRed(POWER_FAIL)
print ('Power save at %s seconds' % powerSave)
MOD.powerSaving(powerSave)
if (LOCALS.maxTrial > 0 and trial == 0):
return 0
power = CheckPower()
CheckCFUN()
if (InitModem() == 0):
return 0
lis3lv02 = LIS3LV02()
if (lis3lv02.Error != 0):
BlinkRed(LIS3LV02_INIT_ERROR)
print 'LIS3LV02 initialization error'
dataLIS3LV02 = [0,0,0,0,0,0,0,0]
trial = LOCALS.maxTrial
lisError = 0
powerFails = 0
powerTrials = 0
print 'IMEI:'+LOCALS.imei
while (LOCALS.maxTrial == 0 or trial > 0):
trial = trial - 1
sleepTime = LOCALS.intervalNormal
power = CheckPower()
if (power[0] == 0 and power[1] == 0):
BlinkRed(POWER_FAIL)
if (powerFails == 0):
print 'Power fail initial, sleeping %s seconds' % (LOCALS.intervalPower / 10)
powerFails = 5
MOD.sleep(LOCALS.intervalPower)
trial = trial + 1
elif (powerFails == 1):
print 'Power save at %s seconds' % powerSave
MOD.powerSaving(powerSave)
else:
print 'Power fail, sleeping %s seconds' % (LOCALS.intervalPower / 10)
powerFails = powerFails - 1
MOD.sleep(LOCALS.intervalPower)
trial = trial + 1
continue
powerFails = 0
if (power[0] == 0 and power[1] == 25):
BlinkRed(POWER_FAIL)
print 'Power save at %s seconds' % powerSave
MOD.powerSaving(powerSave)
continue
if (power[0] == 0):
if (powerTrials == 0):
print 'Initialize power trials'
powerTrials = LOCALS.maxPowerTrials
elif (powerTrials == 1):
print 'Done power trials'
break
else:
print 'Step power trials (%d)' % powerTrials
powerTrials = powerTrials - 1
else:
powerTrials = 0
if (CheckCFUN() == 1):
if (InitModem() == 0):
continue
if (LOCALS.maxTrial > 0):
print '--- %d try left' % trial
else:
print '---'
location = GetLocation()
if (len(location[0]) == 0):
BlinkRed(GPS_ERROR)
sleepTime = LOCALS.intervalError
print 'Sorry no GPS fix.'
if (len(location[3]) > 0):
ProcessAccData(dataLIS3LV02, lis3lv02.Read(), Str2Int(location[3]))
else:
ProcessAccData(dataLIS3LV02, lis3lv02.Read(), 0)
lisError = max(lisError, lis3lv02.Error)
retry = 2
fail = 1
response = SendCmd('AT#GPRS=1')
while (retry > 0):
if (response.find('+IP') == -1 and response.find('already activated') == -1):
retry = retry - 1
print response
response = SendCmd('AT#GPRS=1')
else:
fail = 0
break
if (fail == 1):
BlinkRed(GPRS_ERROR)
sleepTime = LOCALS.intervalError
print 'Cannot activate GPRS.'
else:
response = SendCmd('AT#SKTD=0,80,' + LOCALS.server, 'CONNECT\r\n', 30)
print response
if (response.find('CONNECT') >= 0):
request = 'GET ' + LOCALS.url + '?longitude=' + location[1]
request = request + '&latitude=' + location[0]
request = request + '&altitude=' + location[2]
request = request + '&speed=' + location[3]
request = request + '&heading=' + location[4]
request = request + '&date=' + location[5]
request = request + '&time=' + location[6]
if (len(LOCALS.http_user) > 0):
request = request + '&username=' + LOCALS.http_user
request = request + '&pw=' + LOCALS.http_pass
else:
request = request + '&imei=' + LOCALS.imei
request = request + '&maxXAcc=' + str(dataLIS3LV02[0])
request = request + '&minXAcc=' + str(dataLIS3LV02[1])
request = request + '&maxYAcc=' + str(dataLIS3LV02[2])
request = request + '&minYAcc=' + str(dataLIS3LV02[3])
request = request + '&maxZAcc=' + str(dataLIS3LV02[4])
request = request + '&minZAcc=' + str(dataLIS3LV02[5])
request = request + '&maxSpeed=' + str(dataLIS3LV02[6])
request = request + '&minSpeed=' + str(dataLIS3LV02[7])
request = request + ' HTTP/1.1\r\n'
request = request + 'Host: ' + LOCALS.host + '\r\n\r\n'
print request
Send(request)
response = GetResponse()
print response
Disconnect()
if (len(response) > 0):
content = ''
i = response.find('\r\n\r\n')
if (i > 0 and (i + 4) < len(response)):
content = response[i + 4:len(response)]
arr = response.split('\r\n')
if (len(arr) >= 1):
response = arr[0]
if (response.find('HTTP/1.1 200 OK') >= 0):
if (len(content) > 0):
if (content == 'OK'):
BlinkGreen(1)
else:
BlinkRed(RESPONSE_ERROR)
print 'Bad response: ' + content
else:
BlinkRed(RESPONSE_ERROR)
print 'Empty content.'
else:
BlinkRed(RESPONSE_ERROR)
print 'HTTP/1.1 200 OK not found.'
else:
BlinkRed(RESPONSE_ERROR)
print 'No lines in response.'
else:
BlinkRed(RESPONSE_ERROR)
print 'Empty response.'
else:
BlinkRed(CONNECT_ERROR)
sleepTime = LOCALS.intervalError
print 'Cannot connect to host.'
if (lisError == 4):
lisError = 0
lis3lv02.Error = 0
BlinkRed(LIS3LV02_READ_ERROR)
print 'LIS3LV02 read error.'
ProcessAccData(dataLIS3LV02, lis3lv02.Read(), GetSpeed(), 1)
lisError = max(lisError, lis3lv02.Error)
print 'Sleeping at %s seconds' % sleepTime
while(sleepTime > 0):
MOD.sleep(4)
ProcessAccData(dataLIS3LV02, lis3lv02.Read(), GetSpeed())
lisError = max(lisError, lis3lv02.Error)
MOD.sleep(4)
ProcessAccData(dataLIS3LV02, lis3lv02.Read(), GetSpeed())
lisError = max(lisError, lis3lv02.Error)
sleepTime = sleepTime - 1
return 1
class SERWriter:
def write(self, s):
SER.send(s + '\r')
# Start point
# Redirect stdout to SER
SER.set_speed('115200','8N1')
oldSTDOUT = sys.stdout
oldSTDERR = sys.stderr
sys.stdout = sys.stderr = SERWriter()
print '\r\nGM862 Tracker 1.00'
GPIO.setIOdir(11, 0, 0)
BlinkGreenOn()
SendCmd('AT#SLED=0;+CMEE=2;&K0;#DSTO=10')
while (1 == 1):
try:
main()
break
except:
continue
print '\r\nDone'
GPIO.setIOvalue(2, 0)
SendCmd5('AT#SLED=2;&K3')
if (IsOnBattery()):
SendCmd('AT#SHDN', timeout=100)
sys.stdout = oldSTDOUT
sys.stderr = oldSTDERR


0 comment(s) so far