ติดตั้ง Firmware MicroPython ของ Pycom ลง ESP32 ใช้กับ RFM95 หรือ SX1276
ตัวอย่างนี้จะเดินสาย Wiring แบบเดียวกันกับ Heltec LoRa V.2
RFM95 ESP32
NSS GPIO18
ISO GPIO27
OSI GPIO19
SCK GPIO5
RST GPIO14
DIO0 GPIO26
DIO1 GPIO35
DIO2 GPIO34
ดาวน์โหลด Firmware MicroPython ของ Pycom เพื่อใช้ LoRaWAN สำหรับ Heltec ได้จากเวป (สามารถเอามาลงใน ESP32 ได้หากเชื่อมต่อสายตาม Diagram ที่ให้ไว้)
https://github.com/robert-hh/Shared-Stuff
มีสอง 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_WSL-1.20.2.rc6.tar.gz ตัว Lite WSLแตกไฟล์
Flash โดยใช้โปรแกรมบน PC
โปรแกรมที่ใช้ Flash คือ Flash Download Tool ดาวน์โหลดได้จากเวป
https://www.espressif.com/en/support/download/other-tools หรือ คลิก
ให้เลือก COM ที่ต่อ ESP32 อยู่ อาจคลิก ERASE ก่อนแล้วค่อยคลิก START
Flash โดยใช้เวปแอป ที่เวป https://espressif.github.io/esptool-js/
เปิด Thonny เพื่อใช้งานหรือเขียนโปรแกรม อย่าลืมตั้งค่า TX Power ให้เป็นไปตามกฎหมายกำหนดคือไม่เกิน 50mW (eirp)
- ScanI2C.py
from machine import Pin, I2C
import machine
i2c = I2C(0, pins=('P12','P11'))
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('P8', 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
i2c = I2C(0, pins=('P12','P11'))
print('Scan i2c bus...')
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. Join LoRaWAN แบบ abp.py
from network import LoRa
import socket
import ubinascii
import struct
import time
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)
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)
print(type(lora.stats()))
print(lora.stats())
print(lora.stats().tx_frequency)
data = s.recv(64)
print('Downlink:',data)
time.sleep(10)
6. Join LoRaWAN แบบ abp และแสดงบนจอ OLED ด้วย 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
from network import LoRa
import socket
import time
import ubinascii
from cayennelpp import CayenneLPP
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)
print('Over the air network activation ... ', end='')
while not lora.has_joined():
time.sleep(2.5)
print('.', end='')
print('')
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)
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
led = machine.Pin('P8', machine.Pin.OUT)
i2c = I2C(0, pins=('P12','P11'))
print('Scan i2c bus...')
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( "------------------------------------")
print(lora.stats())
print("TX Freq:",lora.stats().tx_frequency)
print("RSSI:",lora.stats().rssi)
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, 30)
oled.text("Freq : "+str(lora.stats().tx_frequency), 0, 40)
oled.text("RSSI : "+str(lora.stats().rssi), 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)
led.value(1)
sleep(0.5)
led.value(0)
sleep(10)
s.setblocking(False)
print(type(lora.stats()))
print(lora.stats())
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. การเรียกชื่อ Pin
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
13.ใช้ Modbus ลองใช้กับ Soil NPK RS485 Sensor หรือ Energy Meter เป็นต้น
แนะนำให้ใช้ RS485 to TTL แบบอัตโนมัติ
โหลด Modbus Lib ได้จาก Github มี 3 Files uModBusConst.py, uModBusFunctions.py, uModBusSerial.py
แก้ Lib uModBusSerial.py ใส่ # หน้าบรรทัด 26–27 จาก
#self._uart = UART(uart_id, baudrate=baudrate, bits=data_bits, parity=parity, \
# stop=stop_bits, timeout_char=10, tx=tx, rx=rx)
เอา # หน้าบรรทัด 28–29 ออก ดู Tab Indent ให้ถุกต้อง
self._uart = UART(uart_id, baudrate=baudrate, bits=data_bits, parity=parity, \
stop=stop_bits, timeout_chars=10, pins=pins)
ต่อเข้า GPIO2 (P8)- RS485 TXD, GPIO15 (P4)- RS485 RXD
from machine import UART
import time
from time import sleep
from uModBusSerial import uModBusSerial
modbus= uModBusSerial (2, baudrate=4800, pins=['P8', 'P4'])
slave=0x01
address=0x1E
quantity=3
signed=True
register_value = modbus.read_holding_registers(slave, address, quantity, signed)
print('Input register value: ' + ' '.join('{:d}'.format(x) for x in register_value))
print ('N : %6d mg/kg' % register_value[0])
print ('P : %6d mg/kg' % register_value[1])
print ('K : %6d mg/kg' % register_value[2])
ผลการ Run
Input register value: 19 26 66
N : 19 mg/kg
P : 26 mg/kg
K : 66 mg/kg
Ref. ตัวอย่างอื่นที่อาจจะพอใช้ได้เช่น