After letting the Degu unit run on battery power for an extended period, the Degu unit shuts itself down itself due to low battery (output says ~2.2V, read using the battery example code). Battery discharge:

After replacing the battery of the degu unit, main.py file is found to be corrupted. Details:
from machine import Pin
from machine import Signal
from machine import ADC
import zcoap
import time
import ujson
from ustruct import unpack, unpack_from
from array import array
from machine import I2C
# BMP280 default address.
BMP280_I2CADDR = 0x77
# Operating Modes
BMP280_OSAMPLE_1 = 1
BMP280_OSAMPLE_2 = 2
BMP280_OSAMPLE_4 = 3
BMP280_OSAMPLE_8 = 4
BMP280_OSAMPLE_16 = 5
BMP280_REGISTER_CONTROL_HUM = 0xF2
BMP280_REGISTER_CONTROL = 0xF4
class BMP280:
def __init__(self,
mode=BMP280_OSAMPLE_1,
address=BMP280_I2CADDR,
i2c=None,
**kwargs):
# Check that mode is valid.
if mode not in [BMP280_OSAMPLE_1, BMP280_OSAMPLE_2, BMP280_OSAMPLE_4,
BMP280_OSAMPLE_8, BMP280_OSAMPLE_16]:
raise ValueError(
'Unexpected mode value {0}. Set mode to one of '
'BMP280_ULTRALOWPOWER, BMP280_STANDARD, BMP280_HIGHRES, or '
'BMP280_ULTRAHIGHRES'.format(mode))
self._mode = mode
self.address = address
if i2c is None:
raise ValueError('An I2C object is required.')
self.i2c = i2c
# load calibration data
self.i2c.writeto(self.address, 0x88)
dig_88_a1 = self.i2c.readfrom(self.address, 26)
self.i2c.writeto(self.address, 0xE1)
dig_e1_e7 = self.i2c.readfrom(self.address, 7)
self.dig_T1, self.dig_T2, self.dig_T3, self.dig_P1, \
self.dig_P2, self.dig_P3, self.dig_P4, self.dig_P5, \
self.dig_P6, self.dig_P7, self.dig_P8, self.dig_P9, \
_, self.dig_H1 = unpack("<HhhHhhhhhhhhBB", dig_88_a1)
self.dig_H2, self.dig_H3 = unpack("<hB", dig_e1_e7)
e4_sign = unpack_from("<b", dig_e1_e7, 3)[0]
self.dig_H4 = (e4_sign << 4) | (dig_e1_e7[4] & 0xF)
e6_sign = unpack_from("<b", dig_e1_e7, 5)[0]
self.dig_H5 = (e6_sign << 4) | (dig_e1_e7[4] >> 4)
self.dig_H6 = unpack_from("<b", dig_e1_e7, 6)[0]
self.i2c.writeto(self.address, bytearray([BMP280_REGISTER_CONTROL, 0x3F]))
self.t_fine = 0
# temporary data holders which stay allocated
self._l1_barray = bytearray(2)
self._l8_barray = bytearray(8)
self._l3_resultarray = array("i", [0, 0, 0])
def read_raw_data(self, result):
""" Reads the raw (uncompensated) data from the sensor.
Args:
result: array of length 3 or alike where the result will be
stored, in temperature, pressure, humidity order
Returns:
None
"""
self._l1_barray[0] = BMP280_REGISTER_CONTROL_HUM
self._l1_barray[1] = self._mode
self.i2c.writeto(self.address, self._l1_barray)
self._l1_barray[0] = BMP280_REGISTER_CONTROL
self._l1_barray[1] = self._mode << 5 | self._mode << 2 | 1
self.i2c.writeto(self.address, self._l1_barray)
sleep_time = 1250 + 2300 * (1 << self._mode)
sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
time.sleep_us(sleep_time) # Wait the required time
# burst readout from 0xF7 to 0xFE, recommended by datasheet
self.i2c.writeto(self.address, 0xF7)
self._l8_barray = self.i2c.readfrom(self.address, 9)
readout = self._l8_barray
# pressure(0xF7): ((msb << 16) | (lsb << 8) | xlsb) >> 4
raw_press = ((readout[0] << 16) | (readout[1] << 8) | readout[2]) >> 4
# temperature(0xFA): ((msb << 16) | (lsb << 8) | xlsb) >> 4
raw_temp = ((readout[3] << 16) | (readout[4] << 8) | readout[5]) >> 4
# humidity(0xFD): (msb << 8) | lsb
raw_hum = (readout[6] << 8) | readout[7]
result[0] = raw_temp
result[1] = raw_press
result[2] = raw_hum
def read_compensated_data(self, result=None):
""" Reads the data from the sensor and returns the compensated data.
Args:
result: array of length 3 or alike where the result will be
stored, in temperature, pressure, humidity order. You may use
this to read out the sensor without allocating heap memory
Returns:
array with temperature, pressure, humidity. Will be the one from
the result parameter if not None
"""
self.read_raw_data(self._l3_resultarray)
raw_temp, raw_press, raw_hum = self._l3_resultarray
# temperature
var1 = ((raw_temp >> 3) - (self.dig_T1 << 1)) * (self.dig_T2 >> 11)
var2 = (((((raw_temp >> 4) - self.dig_T1) *
((raw_temp >> 4) - self.dig_T1)) >> 12) * self.dig_T3) >> 14
self.t_fine = var1 + var2
temp = (self.t_fine * 5 + 128) >> 8
# pressure
var1 = self.t_fine - 128000
var2 = var1 * var1 * self.dig_P6
var2 = var2 + ((var1 * self.dig_P5) << 17)
var2 = var2 + (self.dig_P4 << 35)
var1 = (((var1 * var1 * self.dig_P3) >> 8) +
((var1 * self.dig_P2) << 12))
var1 = (((1 << 47) + var1) * self.dig_P1) >> 33
if var1 == 0:
pressure = 0
else:
p = 1048576 - raw_press
p = (((p << 31) - var2) * 3125) // var1
var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25
var2 = (self.dig_P8 * p) >> 19
pressure = ((p + var1 + var2) >> 8) + (self.dig_P7 << 4)
# humidity
h = self.t_fine - 76800
h = (((((raw_hum << 14) - (self.dig_H4 << 20) -
(self.dig_H5 * h)) + 16384)
>> 15) * (((((((h * self.dig_H6) >> 10) *
(((h * self.dig_H3) >> 11) + 32768)) >> 10) +
2097152) * self.dig_H2 + 8192) >> 14))
h = h - (((((h >> 15) * (h >> 15)) >> 7) * self.dig_H1) >> 4)
h = 0 if h < 0 else h
h = 419430400 if h > 419430400 else h
humidity = h >> 12
if result:
result[0] = temp
result[1] = pressure
result[2] = humidity
return result
return array("i", (temp, pressure, humidity))
@property
def values(self):
""" human readable values """
t, p, h = self.read_compensated_data()
p = p // 256
pi = p // 100
pd = p - pi * 100
hi = h // 1024
hd = h * 100 // 1024 - hi * 100
return ("{}".format(t / 100), "{}.{:02d}".format(pi, pd),
"{}.{:02d}".format(hi, hd))
def negtive_converter(raw):
if raw > 32767:
raw = (65536 - raw) * (-1)
return raw
def light_sensor():
ADC_REF = 0.6
ADC_RESOLUTION=4096 #12bit
ain = ADC(0)
ain.gain(ain.GAIN_1_6) #gain set to 1/6
raw = negtive_converter(ain.read())
v = (raw / ADC_RESOLUTION) * ADC_REF * 6
return v
def air_quality_sensor():
ain = ADC(0)
return negtive_converter(ain.read())
def sound_sensor():
ain = ADC(4)
return negtive_converter(ain.read())
def battery_voltage():
R6 = 68
R8 = 100
ADC_REF = 0.6
ADC_RESOLUTION=îÅ\¾ ô ^ S 5 @ PäùçÖ3ñý ýPäùçÖ ¼ef, #ÜÕa & degu «Í ÿ ÿÿ ô 2ëž]äÖOw ô $ ªª ì N¼ à T XZ }£7äYöì ì Ëéw ô $ ªª ì 7À ðÆ T XZ }£7äYöì ì Ëéw ô $ ì :À ðÆ T XZ }£7äYöì ì Ëéw ô $ ªª ì #Ä ØÊ T XZ }£7äYöì ì Ëéw ô $ ªª ì È ÀÎ T XZ }£7äYöì ì Ëéw ô $ ªª ì õË ¨Ò T XZ }£7äYöì ì Ëéw ô $ ªª ì ÞÏ Ö T XZ }£7äYöì ì Ëéw ô $ ªª ì ÇÓ xÚ T XZ }£7äYöì ì Ëéw ô $ ªª ì °× `Þ T XZ }£7äYöì ì Ëéw ô $ ªª ì ™Û Hâ T XZ }£7äYöì ì Ëéwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
After replacing corrupted main.py, the Degu unit is still unable to connect to the gateway (A6). Suspect that the network information partition is also corrupted. After using “dd” to clear network information partition and re-register unit on gateway, it started to work again.
We've been running two Degu units on batteries. This issue has happened twice on the same Degu unit so far, but hasn't occurred on the other which was also battery powered, and also ran down the batteries to the point of power failure, but with no corruption.
After letting the Degu unit run on battery power for an extended period, the Degu unit shuts itself down itself due to low battery (output says ~2.2V, read using the battery example code). Battery discharge:

After replacing the battery of the degu unit, main.py file is found to be corrupted. Details:
After replacing corrupted main.py, the Degu unit is still unable to connect to the gateway (A6). Suspect that the network information partition is also corrupted. After using “dd” to clear network information partition and re-register unit on gateway, it started to work again.
We've been running two Degu units on batteries. This issue has happened twice on the same Degu unit so far, but hasn't occurred on the other which was also battery powered, and also ran down the batteries to the point of power failure, but with no corruption.