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

Commit fdacf34

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

File tree

4 files changed

+71
-30
lines changed

4 files changed

+71
-30
lines changed

pysense/lib/pysense.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
from machine import Pin
2-
import time
1+
import time
2+
import struct
3+
import math
4+
import pycom
35

4-
__version__ = '1.0.0'
6+
__version__ = '1.0.1'
7+
8+
EXP_RTC_PERIOD = 7000
59

610
class Pysense:
711

@@ -15,6 +19,7 @@ class Pysense:
1519
CMD_PROD_ID = const(0x12)
1620
CMD_SETUP_SLEEP = const(0x20)
1721
CMD_GO_SLEEP = const(0x21)
22+
CMD_CALIBRATE = const(0x22)
1823
CMD_BAUD_CHANGE = const(0x30)
1924
CMD_DFU = const(0x31)
2025

@@ -50,26 +55,26 @@ class Pysense:
5055
PCON_ADDR = const(0x096)
5156
STATUS_ADDR = const(0x083)
5257

53-
class Pysense:
5458

5559
def __init__(self, i2c=None, sda='P22', scl='P21'):
5660
if i2c is not None:
5761
self.i2c = i2c
5862
else:
59-
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
import time
55
import struct
66
import math
7+
import pycom
78

8-
__version__ = '1.0.0'
9+
__version__ = '1.0.1'
10+
11+
EXP_RTC_PERIOD = 7000
912

1013
class Pytrack:
1114

@@ -19,6 +22,7 @@ class Pytrack:
1922
CMD_PROD_ID = const(0x12)
2023
CMD_SETUP_SLEEP = const(0x20)
2124
CMD_GO_SLEEP = const(0x21)
25+
CMD_CALIBRATE = const(0x22)
2226
CMD_BAUD_CHANGE = const(0x30)
2327
CMD_DFU = const(0x31)
2428

@@ -54,23 +58,26 @@ class Pytrack:
5458
PCON_ADDR = const(0x096)
5559
STATUS_ADDR = const(0x083)
5660

61+
5762
def __init__(self, i2c=None, sda='P22', scl='P21'):
5863
if i2c is not None:
5964
self.i2c = i2c
6065
else:
6166
self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl))
67+
self.sda = sda
68+
self.scl = scl
69+
self.clk_cal_factor = 1
6270
self.reg = bytearray(6)
63-
scan_r = self.i2c.scan()
64-
if not scan_r or not I2C_SLAVE_ADDR in scan_r:
71+
try:
72+
# init the ADC for the battery measurements
73+
self.poke_memory(ANSELC_ADDR, 1 << 2)
74+
self.poke_memory(ADCON0_ADDR, (0x06 << _ADCON0_CHS_POSN) | _ADCON0_ADON_MASK)
75+
self.poke_memory(ADCON1_ADDR, (0x06 << _ADCON1_ADCS_POSN))
76+
# enable the pull-up on RA3
77+
self.poke_memory(WPUA_ADDR, (1 << 3))
78+
except Exception:
6579
raise Exception('Pytrack board not detected')
6680

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-
7481
def _write(self, data, wait=True):
7582
self.i2c.writeto(I2C_SLAVE_ADDR, data)
7683
if wait:
@@ -80,9 +87,13 @@ def _read(self, size):
8087
return self.i2c.readfrom(I2C_SLAVE_ADDR, size + 1)[1:(size + 1)]
8188

8289
def _wait(self):
83-
time.sleep_us(100)
90+
count = 0
91+
time.sleep_us(10)
8492
while self.i2c.readfrom(I2C_SLAVE_ADDR, 1)[0] != 0xFF:
85-
time.sleep_us(100)
93+
time.sleep_us(10)
94+
count += 1
95+
if (count > 1000): # timeout after 10ms
96+
raise Exception('Pytrack board timeout')
8697

8798
def _send_cmd(self, cmd):
8899
self._write(bytes([cmd]))
@@ -123,6 +134,8 @@ def set_bits_in_memory(self, addr, bits):
123134
self.magic_write_read(addr, _or=bits)
124135

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

128141
def go_to_sleep(self):
@@ -134,6 +147,14 @@ def go_to_sleep(self):
134147
# kill the run pin
135148
Pin('P3', mode=Pin.OUT, value=0)
136149

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

pytrack/main.py

Lines changed: 2 additions & 1 deletion
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)