Skip to content

Commit c1bf79d

Browse files
author
Kevin J Walters
committed
Adding batched writes to reduce the wear on flash, writes are every 6 minutes now.
Backlight cycle time now 2 hours as it takes a while to heat things up. Renaming the variables holding long integer time in ns.
1 parent ba7d0a7 commit c1bf79d

File tree

1 file changed

+38
-20
lines changed

1 file changed

+38
-20
lines changed

clue-multitemplogger/clue-multitemplogger.py

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
### clue-mutlitemplogger.py v1.1
1+
### clue-mutlitemplogger.py v1.2
22
### Measure temperature from multiple sensors and log to CIRCUITPY
33

4+
### This now writes every 6 minutes to REDUCE THE WEAR on the flash chip
5+
### (replacing this involves SMD soldering!)
6+
### See https://forums.adafruit.com/viewtopic.php?f=65&t=175527
7+
48
### Tested with Adafruit CLUE and CircuitPython 6.1.0
59

610
### MIT License
@@ -31,7 +35,6 @@
3135

3236
import microcontroller
3337
import board
34-
import busio
3538
from adafruit_onewire.bus import OneWireBus
3639
import adafruit_ds18x20
3740
import adafruit_bmp280
@@ -49,10 +52,16 @@
4952

5053
MAX_AIN = 2**16 - 1
5154

55+
VERBOSE = False
56+
57+
### Measure every 10 seconds but do not write to CIRCUITPY at this
58+
### rate as the flash does not have wear-levelling and
5259
count = 3
5360
interval = 10
5461
interval_ns = interval * 1000 * 1000 * 1000
55-
verbose = False
62+
write_buffer_lines = 108 ### 8640 bytes every 108/3*10=360 seconds
63+
pending_writes = []
64+
5665
console = True
5766

5867

@@ -65,10 +74,13 @@
6574
### NeoPixel colour during measurement
6675
### Bright values may be useful if powered from a
6776
### USB power bank with low-current auto off
77+
RECORDING = 0xff0000
6878
READING = 0x00ff00 + (0x0000ff if data_file else 0)
6979
BLACK = 0x000000
7080

7181

82+
### First value might be questionable with a high impedance source
83+
### due to input multiplexing
7284
def get_voltage(ain, samples=500):
7385
return sum([ain.value for _ in range(samples)]) / (samples * MAX_AIN) * vref
7486

@@ -84,7 +96,7 @@ def find_DS18X20(bus, verbose=True):
8496
if verbose:
8597
for dev in devices:
8698
print("ROM = {}\tFamily = 0x{:02x}".format([hex(i) for i in dev.rom],
87-
dev.family_code))
99+
dev.family_code))
88100
return devices[0] if devices else None
89101

90102

@@ -102,8 +114,8 @@ def measure_temps(sensor_list=None):
102114
ow_bus = OneWireBus(DS18X20_PIN)
103115
bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c)
104116
sht31d = adafruit_sht31d.SHT31D(i2c)
105-
ds18b20 = adafruit_ds18x20.DS18X20(ow_bus,
106-
find_DS18X20(ow_bus, verbose=verbose))
117+
ds18b20 = adafruit_ds18x20.DS18X20(ow_bus,
118+
find_DS18X20(ow_bus, verbose=VERBOSE))
107119
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
108120

109121
ntc_ain = AnalogIn(NTC_PIN)
@@ -125,15 +137,21 @@ def measure_temps(sensor_list=None):
125137

126138
def output(text, *, pad=" ", pad_len=0, end=b"\x0d\x0a", encoding="ascii"):
127139
if pad and pad_len:
128-
out_text = text + " " * (pad_len - len(text) - len(end))
140+
out_text = text + " " * (pad_len - len(text) - len(end))
129141
else:
130-
out_text = text
131-
142+
out_text = text
143+
132144
if console:
133145
print(out_text)
134146
if data_file:
135-
data_file.write(out_text.encode(encoding) + end)
136-
data_file.flush()
147+
pending_writes.append(out_text.encode(encoding) + end)
148+
if len(pending_writes) >= write_buffer_lines:
149+
pixel[0] = RECORDING
150+
for line in pending_writes:
151+
data_file.write(line)
152+
data_file.flush()
153+
pending_writes.clear()
154+
pixel[0] = BLACK
137155

138156

139157
### 80 chars minus CRLF
@@ -145,29 +163,29 @@ def output(text, *, pad=" ", pad_len=0, end=b"\x0d\x0a", encoding="ascii"):
145163
output(HEADER, pad_len=FIXED_WIDTH)
146164

147165

148-
last_loop_t = 0
166+
last_loop_ns = 0
149167

150-
backlight_cycle_dur_ns = 1800e9
168+
backlight_cycle_dur_ns = 7200e9
151169
backlight_cycle = [1.0, 0.0, 0.0, 0.125, 0.25, 0.5]
152170

153-
start_loop_t = time.monotonic_ns()
171+
start_loop_ns = time.monotonic_ns()
154172
while True:
155173
while True:
156-
now_t = time.monotonic_ns()
157-
if now_t > last_loop_t + interval_ns:
174+
now_ns = time.monotonic_ns()
175+
if now_ns > last_loop_ns + interval_ns:
158176
break
159-
last_loop_t = now_t
177+
last_loop_ns = now_ns
160178

161179
### Cycle the backlight through the brightness values stored in list
162-
phase, _ = math.modf((now_t - start_loop_t) / backlight_cycle_dur_ns)
180+
phase, _ = math.modf((now_ns - start_loop_ns) / backlight_cycle_dur_ns)
163181
backlight = backlight_cycle[min(int(phase * len(backlight_cycle)),
164182
len(backlight_cycle) - 1)]
165183
set_backlight(backlight)
166184

167185
### Take a few measurements and print / log them
168186
for _ in range(count):
169-
in_start_t = time.monotonic_ns()
187+
in_start_ns = time.monotonic_ns()
170188
temps = measure_temps()
171-
data_as_text = ("{:d},{:.3f},".format(in_start_t, backlight)
189+
data_as_text = ("{:d},{:.3f},".format(in_start_ns, backlight)
172190
+ ",".join([str(temp) for temp in temps.values()]))
173191
output(data_as_text, pad_len=FIXED_WIDTH)

0 commit comments

Comments
 (0)