Heltec Wifi LoRa V.3 ด้วย MicroPython

Somsak Lima
5 min readSep 20, 2024

--

ติดตั้ง Thonny ให้เรียบร้อยบน PC

ลง MicroPython ใน Heltec Wifi LoRa V.3 ด้วย Thonny ก่อน ซึ่งมีทางเลือกสองวิธีในการดำเนินการ

วิธีที่แรกใช้ Thonny Download และติดตั้งให้อัตโนมัติ

คลิก Tools/Option/Interpreter

คลิก Install or update MicroPython(esptools)

เลือก Option ให้ถูกต้องแล้วคลิก Install

วิธีสองเลือก Download จากเวปมาลงเอง

ให้ Download Firmware จากเวป MicroPython https://micropython.org/

เลือก Download Firmware ESP32-S3 แบบไม่มี SPIRAM 4MiB Flash และเอาแบบ file .bin

เปิดโปรแกรม thonny คลิก install or update MicroPython(esptool) ในเมนู Tools/Option/Interpreter

เลือก Option ต่างๆ ให้ถูกต้องแล้วคลิกขีดสามขีด เพื่อเลือก Select Local MicroPython image แล้วเลือกไฟล์ที่เรา Download มา

เมื่อเลือกให้ถูกต้องครบถ้วนแล้วให้คลิก install

Note! Pin ที่ใช้ของ Board Heltec Wifi Lora V.3

1.First I2C
scl pin is 18 (Fixed)
sda pin is 17 (Fixed)
RST OLED is 21 (Fixed)
2.Second I2C
scl pin is 45 (Option)
sda pin is 46 (Option)

chip is SX1262
chip pins
SS (CS)= 8
SCK (CLK)= 9
MOSI = 10
MISO = 11
RST = 12
BUSY (GPIO) = 13
DIO1 (also irq) = 14

Link Schematic คลิก

  1. Blink.py
from machine import Pin
from time import sleep
led = Pin(35, Pin.OUT)
while True:
led.value(not led.value())
sleep(0.5)

หรือ

import time
def blink(count, delay):
for ind in range(count):
led.on()
time.sleep(1)
led.off()
time.sleep(1)

LED_PIN = const(35)
led = machine.Pin(LED_PIN, machine.Pin.OUT)
blink(3, 1000)

2. ScanI2C.py

2.1 Scan First I2C
ใช้ First I2C ต้องตั้ง Pin 21 high

import machine
pin21 = machine.Pin(21, machine.Pin.OUT)
pin21.value(1)
i2c = machine.SoftI2C(scl=machine.Pin(18), sda=machine.Pin(17), freq=20000) #heltec V3

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.2 Scan I2C ทั้งคู่

import machine
pin21 = machine.Pin(21, machine.Pin.OUT)
pin21.value(1)
i2c = machine.SoftI2C(scl=machine.Pin(18), sda=machine.Pin(17), freq=20000) #heltec V3

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))


i2c = machine.SoftI2C(scl=machine.Pin(45), sda=machine.Pin(46), freq=20000) #heltec V3
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))

3. OLED1306Demo.py

#From hardware platform: FireBeetle-ESP32
import machine, ssd1306, time
from machine import Pin,SoftI2C
pin21 = machine.Pin(21, machine.Pin.OUT)
pin21.value(1) #heltec V3

# init ic2 object
i2c = machine.SoftI2C(scl=machine.Pin(18), sda=machine.Pin(17), freq=20000) #heltec V3
lcd=ssd1306.SSD1306_I2C(128,64,i2c,60)
lcd.text("DFRobot",0,0)
for i in range(0,28):
lcd.pixel(2*i,10,1)
lcd.line(0,12,54,12,1) #draw a line from (0,12) to (54,12) color is blue
lcd.hline(10,32,108,1) #draw a horizontal line,from (10,32),length 108,color is blue
lcd.vline(64,0,64,1) #draw a vertical line,from (64,0),length 64,color is blue
lcd.fill_rect(59,27,10,10,1) #draw a rectangle,from (59,27) to (10,10) fill with blue
lcd.rect(56,24,16,16,1) #draw a rectangle frame,from (59,27) to (10,10) and color is blue
lcd.fill_rect(59,27,10,10,1)
lcd.fill_rect(88,0,40,20,1)
lcd.line(88,0,128,20,0) #draw a line from (88,0) to (128,20) color is black
lcd.line(88,20,128,0,0)
lcd.show() #display pix

4. PrintBME280

import machine
import bme280
temp = 0
pa = 0
hum = 0
i2c = machine.SoftI2C(scl=machine.Pin(45), sda=machine.Pin(46), freq=20000) #heltec V3
bme = bme280.BME280(i2c=i2c)
temp,pa,hum = bme.values
#print(bme.values)
print("Temp:",temp)
print("Hum:",hum)
print("Pa:",pa)

5. BME280Oled.py

import machine, time, ssd1306, bme280
pinScl = 22
pinSda = 18
addrOled = 60
addrBME280 = 118
hSize = 64
wSize = 128
oledIsConnected = False
bmeIsConnected = False
temp = 0
pa = 0
hum = 0
pin16 = machine.Pin(16, machine.Pin.OUT)
pin16.value(1)
i2c1 = machine.SoftI2C(scl=machine.Pin(45), sda=machine.Pin(46), freq=20000) #heltec V3
pin16 = machine.Pin(21, machine.Pin.OUT) #heltec V3
pin16.value(21) #heltec V3
i2c2 = machine.SoftI2C(scl=machine.Pin(18), sda=machine.Pin(17), freq=20000) #heltec V3

bmeIsConnected = True
oledIsConnected = True
while True:
if bmeIsConnected:
bme = bme280.BME280(i2c=i2c1,address=addrBME280)
print("BME280 values:")
temp,pa,hum = bme.values
print("Temp:",temp)
print("Hum:",hum)
print("Pa:",pa)

if oledIsConnected:
oled = ssd1306.SSD1306_I2C(128, 64, i2c2, 60)
oled.fill(0)
if bmeIsConnected:
oled.text("Temp. "+temp, 0, 0)
oled.text("PA "+pa, 0, 10)
oled.text("Hum. "+hum, 0, 20)
oled.show()
else:
oled.text("BME KO", 0, 0)
oled.show()
else:
print('! No i2c display')
time.sleep_ms(5000)

6. ใช้งานกับ Chirpstack LoRaWAN Join แบบ OTAA ส่งข้อมูลตัวอย่าง

Ref. https://github.com/GereZoltan/LoRaWAN

เป็น LoRaWAN 1.0.0 จึงใช้ได้กับ Chirpstack เท่านั้น ใช้ในการทดสอบทดลองเท่านั้น

import time
from cayennelpp import CayenneLPP
import base64
import machine,ubinascii
import LoRaWANHandler
from LoRaConfig import LoRaConfig

def blink(count, delay):
for ind in range(count):
led.on()
time.sleep(2)
led.off()
time.sleep(2)

print("This is the LoRa temperature and humidity measurement application.")
LoRaWANHandler.getBoardID()

LED_PIN = const(35)
led = machine.Pin(LED_PIN, machine.Pin.OUT)

lh = LoRaWANHandler.LoRaWANHandler(LoRaConfig)
blink(3, 1000)
lh.otaa()
blink(3, 1000)
time.sleep(5)

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))
d=list(c.getBuffer())
msg=bytes(d)
#msg=ubinascii.unhexlify(ubinascii.hexlify(c.getBuffer()).decode('ascii'))
lh.send(msg, False)
blink(2, 2000)
time.sleep(20)

7. ใช้งานกับ Chirpstack LoRaWAN Join แบบ OTAA ส่งข้อมูลจาก Sensor BME280

ต่อกับ Sensor BME280 แสดงผลบน OLED ได้ Comment ในส่วน Downlink Mac Command Processing ออก

Download ไฟล์ทั้งหมดได้จาก คลิก

VCC เชื่อม Pin 2
GND เชื่อม Pin 1
SCL เชื่อม Pin6 GPIO 45
SDA เชื่อม Pin5 GPIO 46

import time
import base64
import bme280
import machine,ubinascii, ssd1306, time
import LoRaWANHandler
from LoRaConfig import LoRaConfig
from machine import Pin,SoftI2C
from cayennelpp import CayenneLPP
temp = 0
pa = 0
hum = 0
pin21 = machine.Pin(21, machine.Pin.OUT)
pin21.value(1)
def blink(count, delay):
for ind in range(count):
led.on()
time.sleep(2)
led.off()
time.sleep(2)
print("This is the LoRa temperature and humidity measurement application.")
LoRaWANHandler.getBoardID()
LED_PIN = const(35)
led = machine.Pin(LED_PIN, machine.Pin.OUT)
i2c0 = machine.SoftI2C(scl=machine.Pin(18), sda=machine.Pin(17), freq=20000) #heltec V3
i2c = machine.SoftI2C(scl=machine.Pin(45), sda=machine.Pin(46), freq=20000) #heltec V3
oled=ssd1306.SSD1306_I2C(128,64,i2c0,60)
oled.text("LoRaWAN Thailand",0,0)
oled.show()
lh = LoRaWANHandler.LoRaWANHandler(LoRaConfig)
blink(3, 1000)
lh.otaa()
blink(3, 1000)
#time.sleep(5)
count=0
while(True):
bme = bme280.BME280(i2c=i2c)
temp,pa,hum = bme.values
print("Temp:",temp)
print("Hum:",hum)
print("Pa:",pa)
print('temp:', temp, ' Hum:', hum , 'PA:', pa)
oled.fill(0)
oled.text("LoRaWAN Thailand",0,0)
oled.text("Temp. "+temp, 0, 10)
oled.text("PA "+pa, 0, 20)
oled.text("Hum. "+hum, 0, 30)
oled.text("Count "+str(count), 0, 50)
oled.show()
c = CayenneLPP()
c.addTemperature(1, float(temp))
c.addRelativeHumidity(3, float(hum))
d=list(c.getBuffer())
msg=bytes(d)
count=count+1
lh.send(msg, False)
blink(2, 2000)

Ref.

  1. https://gitlab.com/huberthoegl/ttn_workshop/-/tree/main?ref_type=heads
  2. https://hhoegl.de/etc/ttn_workshop/index.html

--

--

Somsak Lima
Somsak Lima

Written by Somsak Lima

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

Responses (1)