Guys,
A bit of a change of direction… Before I start looking at waking from a PIN, need to get the basic code right first!
I thought my code was working fine… It isnt, not quite. Im having trouble with machine.deepsleep().
The LoPy4 goes to sleep fine but when it wakes up it restarts the machine, re-joins TTN and then uploads the next set of data. Consequently the counter is always 0 and perhaps more importantly (from a power management perspective) Im wasting a whole heap of battery power re-joining TTN every transmission.
This is a screenshot of watching the data come into TTN when using machine.deepsleep(20000) in my code:
And this is a screenshot when I simply remove the machine.deepsleep(20000) line from my LoPy4 code:
I have purposefully set the sleep time low so as to be able to diagnose easily.
I have also tried to use lora.nvram_save() and lora.nvram_restore() but I have not been able to solve the issue.
I have included my code below in the hopes that someone can show me the error of my ways!
from network import LoRa
import socket
import utime
import binascii
import pycom
import ustruct
import machine
import onewire
from machine import Pin
from machine import ADC
from machine import ADC
from onewire import DS18X20
from onewire import OneWire
#DS18B20 data line connected to pin P10
ow = OneWire(Pin('P10'))
temp = DS18X20(ow)
# Disable LED heartbeat (so we can control the LED)
#pycom.heartbeat(False)
# Temp measurement
def temp_measure():
print("")
print("Reading DS18B20 Sensors...")
Current_Air_Temp = 0.0
Current_Soil_Temp = 0.0
# b = bytearray to hold ROM addresses from OneWire address scan
utime.sleep(1)
b = (onewire.OneWire.scan(ow))
# Below prints the array, b
#print("b = ", b)
soil_temp_rom = b[0]
#print("Soil Temp ROM = ", b[0])
air_temp_rom = b[1]
#print("Air Temp ROM = ", b[1])
utime.sleep(1)
temp.start_conversion(soil_temp_rom)
temp.start_conversion(air_temp_rom)
utime.sleep(1)
Current_Soil_Temp = temp.read_temp_async(soil_temp_rom)
Current_Air_Temp = temp.read_temp_async(air_temp_rom)
print("Current Soil Temp = ", Current_Soil_Temp)
print("Current Air Temp = ", Current_Air_Temp)
return Current_Soil_Temp, Current_Air_Temp
#********************************
# takes battery voltage readings
def adc_battery():
adc = ADC(0) # initialise adc hardware
adc_c = adc.channel(attn=3, pin='P16') # create an object to sample ADC on pin 16 with attenuation of 11db (config 3)
adc_samples = [] # initialise the list
for count in range(100): # take 100 samples and append them into the list
adc_samples.append(int(adc_c()))
adc_samples = sorted(adc_samples) # sort the list
adc_median = adc_samples[int(len(adc_samples)/2)] # take the center list row value (median average)
# apply the function to scale to volts
adc_median = adc_median * 2 / 4095 / 0.3275
# print(adc_samples)
return adc_median
# lora config
# Do not need to connect, disconnect, reconnect to TTN. Simply connect once and leave machine to sleep, wake, upload and sleep again.
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923)
# TTN access info
app_eui = binascii.unhexlify('********************')
app_key = binascii.unhexlify('%%%%%%%%%%%%%%%%%%%')
# attempt join - continues attempts background
lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
# wait for a connection
print('Waiting for LoRaWAN network connection...')
while not lora.has_joined():
utime.sleep(1)
# if no connection in a few seconds, then reboot
if utime.time() > 500:
print("possible timeout")
machine.reset()
pass
# we're online, set LED to green and notify via print
#pycom.rgbled(0x004600)
print('Network joined!')
# setup the socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
s.setblocking(False)
s.bind(1)
#lora.nvram_save()
#count = 0
# limit to 200 packets; just in case power is left on
# Alternitavely, in the final application the while statement could be a while True, can then remove count function
while True:
# lora.nvram_restore()
# Get Median Battery Voltage
lipo_voltage = adc_battery()
print('Battery voltage: ', lipo_voltage)
# Get Temperature from DS18x20 Sensors
temps = temp_measure()
# Combine Battery Voltage and temperature readings into one bytes package for sending to LORA
# Note that the "3f" in the ustruck.pack code below means 3 variables are expected, each a float.
send_packet = ustruct.pack('3f', *[temps[0], temps[1], lipo_voltage])
print('Packed Send_packet:', send_packet)
print ('Unpacked Send_packet is:', ustruct.unpack('<3f',send_packet))
# send the prepared packet via LoRa
s.send(send_packet)
# The time delay below is to allow the packet to be sent before the machine goes to sleep.
# utime.sleep(3)
# check for a downlink payload, up to 64 bytes
rx_pkt = s.recv(64)
# check if a downlink was received
if len(rx_pkt) > 0:
print("Downlink data on port 200:", rx_pkt)
pycom.rgbled(0xffa500)
# input("Downlink recieved, press Enter to continue")
utime.sleep(3)
pycom.rgbled(0x004600)
utime.sleep(3)
# count += 1
# print('Going to sleep now...')
# lora.nvram_save()
utime.sleep(3)
# machine.deepsleep(3600000)
# machine.deepsleep(20000)
# lora.nvram_restore()
utime.sleep(3)
print ("End Code")
Thanks
Jon