ติดตั้งและใช้งาน LoRaWAN Pycom Firmware บน Heltec LoRa V.2.0

Somsak Lima
5 min readOct 26, 2024

--

ดาวน์โหลด Firmware Pycom LoRa สำหรับ Heltec ได้จากเวป

มีสอง File
- HELTEC_WS-1.20.2.rc6.tar.gz Tar-Ball สำหรับ Heltec Wireless Stick, 800–900MHz (8MB)

-HELTEC_WSL-1.20.2.rc6.tar.gz Tar-Ball สำหรับ the Heltec Wireless Stick Lite, 800–900MHz (4MB)

เลือก HELTEC_WS-1.20.2.rc6.tar.gz แตกไฟล์

โปรแกรมที่ใช้ Flash คือ Flash Download Tool สามารถ Download ได้จากเวปของผู้ผลิต ESP32 https://www.espressif.com/en/support/download/other-tools

ให้เลือก COM ที่ต่อ Heltec อยู่ อาจคลิก ERASE ก่อนแล้วค่อยคลิก START

เปิด Thonny เพื่อเขียนโปรแกรม อย่าลืมตั้งค่า TX Power ให้เป็นไปตามกฎหมายกำหนดคือไม่เกิน 50mW (eirp)

กำหนดชื่อขาดังนี้

GPIO0,P2
GPIO1,P1
GPIO2,P8
GPIO3,P0
GPIO4,P3
GPIO5,P5
GPIO12,P9
GPIO13,P10
GPIO14,P23
GPIO15,P4
GPIO18,
GPIO19,P7
GPIO21,P12
GPIO22,P11
GPIO23,
GPIO25,P22
GPIO26,P21
GPIO27,P6
GPIO32,P19
GPIO33,P20
GPI34,P18
GPI35,P17
GPI36,P13
GPI37,P14
GPI38,P15
GPI39,P16

แทนการใช้ชื่อขา P16 อาจใช้ GPIO39 แทนได้ เป็นต้น

นอกจากการใช้โปรแกรม Fash Download Tool แล้วเราอาจจะใช้เวปแอปแทนได้ที่

Flash โดยใช้เวปแอป ที่เวป https://espressif.github.io/esptool-js/

  1. ScanI2C.py
from machine import Pin, I2C
import machine
pin16 = machine.Pin('P8', machine.Pin.OUT)
pin16.value(1)
i2c = I2C(0, pins=('P3','P4'))
print('Scan i2c bus...')
devices = i2c.scan()
if len(devices) == 0:
print("No i2c device !")
else:
print('i2c devices found:',len(devices))
for device in devices:
print("Decimal address: ",device," | Hexa address: ",hex(device))

2.Reset.py

import machine;help (machine);machine.reset()

3.Blink.py

import machine
from machine import Pin
from time import sleep
led = machine.Pin('P22', machine.Pin.OUT)
while True:
led.value(not led.value())
sleep(0.5)

4.OLED1306Demo.py

import ssd1306
from ssd1306 import SSD1306_I2C
import machine
from machine import Pin, I2C
pin16 = machine.Pin('P8', machine.Pin.OUT)
pin16.value(1)
i2c = I2C(0, pins=('P3','P4'))
devices = i2c.scan()
oled = ssd1306.SSD1306_I2C(128,64, i2c)
oled.fill(0)
oled.text('Hello, World 1!', 0, 0)
oled.text('Hello, World 2!', 0, 10)
oled.text('Hello, World 3!', 0, 20)
oled.text('Hello, World 4!', 0, 30)
oled.show()

ssd1306.py ให้เลือกของ Pycom

5.abp.py

import socket
import ubinascii
import struct
import time
from network import LoRa
from cayennelpp import CayenneLPP
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923, tx_power=14)
dev_addr = struct.unpack(">l", ubinascii.unhexlify('250115AA'))[0]
nwk_swkey = ubinascii.unhexlify('5D14801A33B3A35C67CCA15B3343E1AA')
app_swkey = ubinascii.unhexlify('40302FD21B34509864C572D40D1188AA')
lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
print(lora.stats())
while True:
temp=25
hum=50
pa=1000
print('temp:', temp, ' Hum:', hum , 'PA:', pa)
c = CayenneLPP()
c.addTemperature(1, float(temp))
c.addRelativeHumidity(3, float(hum))
msg=bytes(list(c.getBuffer()))
s.setblocking(0)
s.send(msg)
s.setblocking(False)
data = s.recv(64)
print('Downlink:',data)
time.sleep(10)

6.abpOled.py


import socket
import ubinascii
import struct
import time
import machine
import ssd1306
from cayennelpp import CayenneLPP
from network import LoRa
from ssd1306 import SSD1306_I2C
from machine import Pin, I2C
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923, tx_power=14)
dev_addr = struct.unpack(">l", ubinascii.unhexlify('250115AA'))[0]
nwk_swkey = ubinascii.unhexlify('5D14801A33B3A35C67CCA15B3343E1AA')
app_swkey = ubinascii.unhexlify('40302FD21B34509864C572D40D1188AA')
lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
pin16 = machine.Pin('P8', machine.Pin.OUT)
pin16.value(1)
i2c = I2C(0, pins=('P3','P4'))
devices = i2c.scan()
oled=ssd1306.SSD1306_I2C(128,64,i2c)
oled.text("LoRaWAN Thailand",0,0)
oled.show()
count=0
while True:
temp=25
hum=50
pa=1000
print('temp:', temp, ' Hum:', hum , 'PA:', pa)
oled.fill(0)
oled.text("LoRaWAN Thailand",0,0)
oled.text("Temp: "+str(temp), 0, 10)
oled.text("Hum: "+str(hum), 0, 20)
oled.text("PA:"+str(pa), 0, 30)
oled.text("Count "+str(count), 0, 50)
oled.show()
c = CayenneLPP()
c.addTemperature(1, float(temp))
c.addRelativeHumidity(3, float(hum))
msg=bytes(list(c.getBuffer()))
s.setblocking(True)
s.send(msg)
s.setblocking(False)
data = s.recv(64)
print('Downlink:',data)
count=count+1
time.sleep(10)

7.otaa.py


import socket
import time
import ubinascii
from cayennelpp import CayenneLPP
from network import LoRa
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923, tx_power=14)
app_eui = ubinascii.unhexlify('ABABABABABABABAB')
app_key = ubinascii.unhexlify('45ADB18947EF42ADC36231E01E508461')
dev_eui = ubinascii.unhexlify('70B3D57ED006B08D')
lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)
while not lora.has_joined():
time.sleep(2.5)
print('Not yet joined...')
print('Joined')
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
while True:
temp=25
hum=50
pa=1000
print('temp:', temp, ' Hum:', hum , 'PA:', pa)
c = CayenneLPP()
c.addTemperature(1, float(temp))
c.addRelativeHumidity(3, float(hum))
msg=bytes(list(c.getBuffer()))
s.setblocking(True)
s.send(msg)
s.setblocking(False)
data = s.recv(64)
print('Downlink:',data)
time.sleep(10)

8.otaaOled.py


import socket
import time
import ubinascii
import ssd1306
import machine
from cayennelpp import CayenneLPP
from ssd1306 import SSD1306_I2C
from machine import Pin, I2C
from network import LoRa
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923, tx_power=14)
app_eui = ubinascii.unhexlify('ABABABABABABABAA')
app_key = ubinascii.unhexlify('45ADB18947EF42ADC36231E01E5084AA')
dev_eui = ubinascii.unhexlify('70B3D57ED006B0AA')
lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)
pin16 = machine.Pin('P8', machine.Pin.OUT)
pin16.value(1)
i2c = I2C(0, pins=('P3','P4'))
devices = i2c.scan()
oled=ssd1306.SSD1306_I2C(128,64,i2c)
oled.text("LoRaWAN Thailand",0,0)
oled.text("Trying to Join",0,20)
oled.show()
while not lora.has_joined():
time.sleep(2.5)
print('Not yet joined...')
print('Joined')
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
count=0
while True:
temp=25
hum=50
pa=1000
print('temp:', temp, ' Hum:', hum , 'PA:', pa)
oled.fill(0)
oled.text("LoRaWAN Thailand",0,0)
oled.text("Temp: "+str(temp), 0, 10)
oled.text("Hum: "+str(hum), 0, 20)
oled.text("PA:"+str(pa), 0, 30)
oled.text("Count "+str(count), 0, 50)
oled.show()
c = CayenneLPP()
c.addTemperature(1, float(temp))
c.addRelativeHumidity(3, float(hum))
msg=bytes(list(c.getBuffer()))
s.setblocking(True)
s.send(msg)
s.setblocking(False)
data = s.recv(64)
print('Downlink:',data)
count=count+1
time.sleep(10)

9.OtaaOledAHT10.py ให้เชื่อมต่อ Sensor AHT10 ตามภาพ

import machine
import socket
import time
import ubinascii
import ssd1306
import ahtx0
from network import LoRa
from cayennelpp import CayenneLPP
from ssd1306 import SSD1306_I2C
from machine import Pin, I2C
from time import sleep

#Applications myasr6601 End devices tbeam
led = machine.Pin('P22', machine.Pin.OUT)

pin16 = machine.Pin('P8', machine.Pin.OUT)
pin16.value(1)
i2c = I2C(0, pins=('P3','P4'))
devices = i2c.scan()
oled=ssd1306.SSD1306_I2C(128,64,i2c)
sensor = ahtx0.AHT10(i2c)

lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923, tx_power=14)
app_eui = ubinascii.unhexlify('ABABABABABABABAA')
app_key = ubinascii.unhexlify('45ADB18947EF42ADC36231E01E5084AA')
dev_eui = ubinascii.unhexlify('70B3D57ED006B0AA')
lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)

oled.text("LoRaWAN Thailand",0,0)
oled.text("Trying to Join",0,20)
oled.show()

while not lora.has_joined():
oled.text("LoRaWAN Thailand",0,0)
oled.text("Trying to Join",0,20)
oled.text("X",15,30)
oled.show()
time.sleep(1)
oled.text("O",15,30)
oled.show()
time.sleep(1)
oled.fill(0)
print('Not yet joined...')

print('Joined')
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
sensor = ahtx0.AHT10(i2c)
count=0
while True:
temp=round(sensor.temperature,2)
hum=round(sensor.relative_humidity,2)
print( "------------------------------------")
print( "Packet #{}".format( count) )
print("AHT10 values:")
print('temp:', temp, ' Hum:', hum )
print( "------------------------------------")
oled.fill(0)
oled.text("LoRaWAN Thailand",0,0)
oled.text("Temp: "+str(temp), 0, 10)
oled.text("Hum: "+str(hum), 0, 20)
oled.text("Count "+str(count), 0, 50)
oled.show()
c = CayenneLPP()
c.addTemperature(1, float(temp))
c.addRelativeHumidity(3, float(hum))
msg=bytes(list(c.getBuffer()))
s.setblocking(True)
led.value(1)
sleep(0.5)
led.value(0)
sleep(10)
s.send(msg)
s.setblocking(False)
data = s.recv(64)
print('Downlink:',data)
count=count+1

10. แสดงค่า Parameters

    print(lora.stats())

ข้อมูลเก็บแบบ Type Tuple

(rx_timestamp=3128505, rssi=-71, snr=6.0, sfrx=5, sftx=5, tx_trials=0, tx_power=14, tx_time_on_air=57, tx_counter=0, tx_frequency=923400000)
923400000

เลือกแสดงเป็นรายตัว เช่น

print(lora.stats().tx_frequency)

11.แก้ boot.py เป็นไฟล์ที่ต้องการให้ทำงาน

import machine
machine.main('otaa.py')

12. หากต้องการสื่อสาร P2P แบบ LoRa

from network import LoRa
import socket
import machine
import time

# more params can also be given, like frequency, tx power and spreading factor
lora = LoRa(mode=LoRa.LORA, region=LoRa.AS923, tx_power=14)

# create a raw LoRa socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)

while True:
# send some data
s.setblocking(True)
s.send('Hello2')

# get any data received...
s.setblocking(False)
data = s.recv(64)
print(data)

# wait a random amount of time
time.sleep(machine.rng() & 0x0F)

อาจจะเปลี่ยนไปใช้ Sensor ASAIR AM2315C ซึ่งใช้ Chip AHT10 โดยไม่ต้องเปลี่ยนโปรแกรมเนื่องจากใช้ Chip เดียวกัน

Ref. ตัวอย่างอื่นที่อาจจะพอใช้ได้ เช่น

  1. https://github.com/pycom/pycom-libraries/tree/master/examples
  2. https://github.com/iot-lnu/applied-iot/tree/master/Pycom%20Micropython%20(esp32)

--

--

Somsak Lima
Somsak Lima

Written by Somsak Lima

สนับสนุนและส่งเสริมให้ผู้สนใจสามารถใช้งานเทคโนโลยี LoRa และ LoRaWAN ได้ โดยนำความรู้ที่ได้ไปต่อยอดเพื่อใช้งาน

No responses yet