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