Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Commit 3c8953c

Browse files
author
Daniel Campora
committed
pycom_libraries: Add sleep time calibration function.
1 parent bc764af commit 3c8953c

File tree

4 files changed

+69
-31
lines changed

4 files changed

+69
-31
lines changed

pysense/lib/pysense.py

+32-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from machine import Pin
22
import time
3+
import pycom
34

4-
__version__ = '1.0.0'
5+
__version__ = '1.0.1'
6+
7+
EXP_RTC_PERIOD = 7000
58

69
class Pysense:
710

@@ -15,6 +18,7 @@ class Pysense:
1518
CMD_PROD_ID = const(0x12)
1619
CMD_SETUP_SLEEP = const(0x20)
1720
CMD_GO_SLEEP = const(0x21)
21+
CMD_CALIBRATE = const(0x22)
1822
CMD_BAUD_CHANGE = const(0x30)
1923
CMD_DFU = const(0x31)
2024

@@ -50,26 +54,27 @@ class Pysense:
5054
PCON_ADDR = const(0x096)
5155
STATUS_ADDR = const(0x083)
5256

53-
class Pysense:
5457

5558
def __init__(self, i2c=None, sda='P22', scl='P21'):
5659
if i2c is not None:
5760
self.i2c = i2c
5861
else:
5962
from machine import I2C
6063
self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl))
64+
self.sda = sda
65+
self.scl = scl
66+
self.clk_cal_factor = 1
6167
self.reg = bytearray(6)
62-
scan_r = self.i2c.scan()
63-
if not scan_r or not I2C_SLAVE_ADDR in scan_r:
68+
try:
69+
# init the ADC for the battery measurements
70+
self.poke_memory(ANSELC_ADDR, 1 << 2)
71+
self.poke_memory(ADCON0_ADDR, (0x06 << _ADCON0_CHS_POSN) | _ADCON0_ADON_MASK)
72+
self.poke_memory(ADCON1_ADDR, (0x06 << _ADCON1_ADCS_POSN))
73+
# enable the pull-up on RA3
74+
self.poke_memory(WPUA_ADDR, (1 << 3))
75+
except Exception:
6476
raise Exception('Pysense board not detected')
6577

66-
# init the ADC for the battery measurements
67-
self.poke_memory(ANSELC_ADDR, 1 << 2)
68-
self.poke_memory(ADCON0_ADDR, (0x06 << _ADCON0_CHS_POSN) | _ADCON0_ADON_MASK)
69-
self.poke_memory(ADCON1_ADDR, (0x06 << _ADCON1_ADCS_POSN))
70-
# enable the pull-up on RA3
71-
self.poke_memory(WPUA_ADDR, (1 << 3))
72-
7378
def _write(self, data, wait=True):
7479
self.i2c.writeto(I2C_SLAVE_ADDR, data)
7580
if wait:
@@ -79,9 +84,13 @@ def _read(self, size):
7984
return self.i2c.readfrom(I2C_SLAVE_ADDR, size + 1)[1:(size + 1)]
8085

8186
def _wait(self):
82-
time.sleep_us(100)
87+
count = 0
88+
time.sleep_us(10)
8389
while self.i2c.readfrom(I2C_SLAVE_ADDR, 1)[0] != 0xFF:
84-
time.sleep_us(100)
90+
time.sleep_us(10)
91+
count += 1
92+
if (count > 1000): # timeout after 10ms
93+
raise Exception('Pysense board timeout')
8594

8695
def _send_cmd(self, cmd):
8796
self._write(bytes([cmd]))
@@ -122,6 +131,8 @@ def set_bits_in_memory(self, addr, bits):
122131
self.magic_write_read(addr, _or=bits)
123132

124133
def setup_sleep(self, time_s):
134+
self.calibrate_rtc()
135+
time_s = int((time_s * self.clk_cal_factor) + 0.5) # round to the nearest integer
125136
self._write(bytes([CMD_SETUP_SLEEP, time_s & 0xFF, (time_s >> 8) & 0xFF, (time_s >> 16) & 0xFF]))
126137

127138
def go_to_sleep(self):
@@ -133,6 +144,14 @@ def go_to_sleep(self):
133144
# kill the run pin
134145
Pin('P3', mode=Pin.OUT, value=0)
135146

147+
def calibrate_rtc(self):
148+
self._write(bytes([CMD_CALIBRATE]), wait=False)
149+
Pin('P21', mode=Pin.IN)
150+
pulses = pycom.pulses_get('P21', 50000)
151+
self.i2c = I2C(0, mode=I2C.MASTER, pins=(self.sda, self.scl))
152+
period = pulses[2][1] - pulses[0][1]
153+
self.clk_cal_factor = (EXP_RTC_PERIOD / period) * 0.98
154+
136155
def button_pressed(self):
137156
button = self.peek_memory(PORTA_ADDR) & (1 << 3)
138157
return not button

pytrack/lib/L76GNSS.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def coordinates(self, debug=False):
4444
while True:
4545
if self.timeout_status != True:
4646
break
47-
nmea += self._read()
47+
nmea += self._read().lstrip(b'\n\n').rstrip(b'\n\n')
4848
gngll_idx = nmea.find(b'GNGLL')
4949
if gngll_idx >= 0:
5050
gngll = nmea[gngll_idx:]

pytrack/lib/pytrack.py

+34-16
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
from machine import I2C
21
from machine import Pin
3-
import machine
42
import time
5-
import struct
6-
import math
3+
import pycom
74

8-
__version__ = '1.0.0'
5+
__version__ = '1.0.1'
6+
7+
EXP_RTC_PERIOD = 7000
98

109
class Pytrack:
1110

@@ -19,6 +18,7 @@ class Pytrack:
1918
CMD_PROD_ID = const(0x12)
2019
CMD_SETUP_SLEEP = const(0x20)
2120
CMD_GO_SLEEP = const(0x21)
21+
CMD_CALIBRATE = const(0x22)
2222
CMD_BAUD_CHANGE = const(0x30)
2323
CMD_DFU = const(0x31)
2424

@@ -54,23 +54,27 @@ class Pytrack:
5454
PCON_ADDR = const(0x096)
5555
STATUS_ADDR = const(0x083)
5656

57+
5758
def __init__(self, i2c=None, sda='P22', scl='P21'):
5859
if i2c is not None:
5960
self.i2c = i2c
6061
else:
62+
from machine import I2C
6163
self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl))
64+
self.sda = sda
65+
self.scl = scl
66+
self.clk_cal_factor = 1
6267
self.reg = bytearray(6)
63-
scan_r = self.i2c.scan()
64-
if not scan_r or not I2C_SLAVE_ADDR in scan_r:
68+
try:
69+
# init the ADC for the battery measurements
70+
self.poke_memory(ANSELC_ADDR, 1 << 2)
71+
self.poke_memory(ADCON0_ADDR, (0x06 << _ADCON0_CHS_POSN) | _ADCON0_ADON_MASK)
72+
self.poke_memory(ADCON1_ADDR, (0x06 << _ADCON1_ADCS_POSN))
73+
# enable the pull-up on RA3
74+
self.poke_memory(WPUA_ADDR, (1 << 3))
75+
except Exception:
6576
raise Exception('Pytrack board not detected')
6677

67-
# init the ADC for the battery measurements
68-
self.poke_memory(ANSELC_ADDR, 1 << 2)
69-
self.poke_memory(ADCON0_ADDR, (0x06 << _ADCON0_CHS_POSN) | _ADCON0_ADON_MASK)
70-
self.poke_memory(ADCON1_ADDR, (0x06 << _ADCON1_ADCS_POSN))
71-
# enable the pull-up on RA3
72-
self.poke_memory(WPUA_ADDR, (1 << 3))
73-
7478
def _write(self, data, wait=True):
7579
self.i2c.writeto(I2C_SLAVE_ADDR, data)
7680
if wait:
@@ -80,9 +84,13 @@ def _read(self, size):
8084
return self.i2c.readfrom(I2C_SLAVE_ADDR, size + 1)[1:(size + 1)]
8185

8286
def _wait(self):
83-
time.sleep_us(100)
87+
count = 0
88+
time.sleep_us(10)
8489
while self.i2c.readfrom(I2C_SLAVE_ADDR, 1)[0] != 0xFF:
85-
time.sleep_us(100)
90+
time.sleep_us(10)
91+
count += 1
92+
if (count > 1000): # timeout after 10ms
93+
raise Exception('Pytrack board timeout')
8694

8795
def _send_cmd(self, cmd):
8896
self._write(bytes([cmd]))
@@ -123,6 +131,8 @@ def set_bits_in_memory(self, addr, bits):
123131
self.magic_write_read(addr, _or=bits)
124132

125133
def setup_sleep(self, time_s):
134+
self.calibrate_rtc()
135+
time_s = int((time_s * self.clk_cal_factor) + 0.5) # round to the nearest integer
126136
self._write(bytes([CMD_SETUP_SLEEP, time_s & 0xFF, (time_s >> 8) & 0xFF, (time_s >> 16) & 0xFF]))
127137

128138
def go_to_sleep(self):
@@ -134,6 +144,14 @@ def go_to_sleep(self):
134144
# kill the run pin
135145
Pin('P3', mode=Pin.OUT, value=0)
136146

147+
def calibrate_rtc(self):
148+
self._write(bytes([CMD_CALIBRATE]), wait=False)
149+
Pin('P21', mode=Pin.IN)
150+
pulses = pycom.pulses_get('P21', 50000)
151+
self.i2c = I2C(0, mode=I2C.MASTER, pins=(self.sda, self.scl))
152+
period = pulses[2][1] - pulses[0][1]
153+
self.clk_cal_factor = (EXP_RTC_PERIOD / period) * 0.98
154+
137155
def button_pressed(self):
138156
button = self.peek_memory(PORTA_ADDR) & (1 << 3)
139157
return not button

pytrack/main.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from LIS2HH12 import LIS2HH12
66

77
py = Pytrack()
8-
l76 = L76GNSS(py, timeout = 60) # GSP timeout set to 60 seconds
8+
l76 = L76GNSS(py, timeout=120) # GSP timeout set to 120 seconds
99
li = LIS2HH12(py)
1010

1111
print(li.acceleration())
@@ -14,3 +14,4 @@
1414
print(li.yaw())
1515

1616
print(l76.coordinates())
17+

0 commit comments

Comments
 (0)