วิธีการ Flash Firmware CircuitPython ลงใน Black Pill
1.อุปกรณ์ที่ใช้
1.1 Black Pill ให้เลือกรุ่น STM32F411CE
1.2 USB to Serial TTL เช่น
2.Firmware ที่ใช้
ไปที่หน้าเวป https://circuitpython.org/board/stm32f411ce_blackpill/
คลิก Download .ฺBIN NOW จะได้ไฟล์ เช่น adafruit-circuitpython-stm32f411ce_blackpill-en_US-5.3.0.bin เป็นต้น
3. Software ที่ใช้ STM32CubeProgrammer
ดาวน์โหลดโปรแกรม STM32CubeProgrammer คลิก
หรือ Download ได้ที่เวป https://www.st.com/en/development-tools/stm32cubeprog.html ซึ่งต้องลงทะเบียนด้วย email แล้วจะมีลิ้งค์ให้ดาวน์โหลดส่งมาทาง email
การเชื่อมต่อสาย
USB Serial — -Black Pill
3V3 — เข้า — 3V
GND — เข้า — G
RX — — เข้า — A9
TX — — เข้า — A10
เริ่มต้น Flash Firmware
เปิด STM32CubeProgrammer
เลือก UART ตั้ง Port ให้ตรงที่เราเสียบบน PC ใช้ Baudrate 115200 และ Parity Even
เข้า Bootloader โหมดโดย กดปุ่ม BOOT0 กดค้างไว้ กดปุ่ม RESET แล้วจึงปล่อยปุ่ม RESET และ BOOT0 ตามลำดับ
คลิก Connect
หาก Connect ได้จะเห็นข้อมูล ตามตัวอย่าง
คลิกที่ TAB Open File เลือกไฟล์ .bin ที่เรา Download ได้มา แล้วคลิก Open
แล้วให้คลิกที่มุมขวาบน Download
หน้าต่าง Log จะขึ้น Download in Progress:
หากเสร็จสิ้นจะขึ้น Download Complete
การใช้งาน
เสียบสาย USB Type C หากทำงานถูกต้อง จะเห็น Virtual Drive ชื่อ CIRCUITPY ซึ่งทำงานคล้ายกับ Flash Drive ปรากฎขึ้น ของผู้เขียนจะขึ้่นเป็น Drive H:
เรียกโปรแกรม Thonny เข้าเมนู Tool /Option
เลือก CircuitPython (generic) และ Port ให้ถูกต้อง
จะเห็นว่ามีพื้นที่ให้เก็บโปรแกรมเพียง 28KB เท่านั้น ซึ่งก็น่าจะเพียงพอกับการใช้งานได้ระดับหนึ่ง
หลังจาก Soft Reboot ด้วย Key CTRL-D จะเห็นข้อความเกี่ยวกับ Firmware ดังนี้ Adafruit CircuitPython 5.3.0 on 2020–04–29; stm32f411ce-blackpill with STM32F411CE
soft rebootAuto-reload is on. Simply save files over USB to run them or enter REPL to disable.Press Ctrl-C to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 5.3.0 on 2020-04-29; stm32f411ce-blackpill with STM32F411CE
ทดสอบการใช้งาน
เพื่อให้สามารถใช้งาน Thonny ได้ง่ายขึ้นให้เปิด View หน้าต่าง Thonny เพิ่มขึ้น เช่น View Files, Shell เป็นต้น
ตัวอย่าง 1.0 กระพริบไฟ LED ด้วย Blink.py
ติดตั้ง Library simpleio ใต้ lib
import board
import time
import simpleio
led = simpleio.DigitalOut(board.LED)
while True:
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
ตัวอย่าง2.0 I2C Scan
เชื่อม Sensor ขา SCL เข้ากับขา B6 ของ STM32F411
เชื่อม Sensor ขา SDA เข้ากับขา B7 ของ STM32F411
import time
import board
import busio
i2c = busio.I2C(board.B6, board.B7)while not i2c.try_lock():
pass
while True:
print("I2C addresses found:", [hex(device_address) for device_address in i2c.scan()])time.sleep(2)
i2c.deinit()
จำเป็นต้องยกเลิกการใช้ PIN ฺ B6 และ B7 ด้วยคำสั่ง i2c.deinit()หากไม่ยกเลิกโดยใช้คำสั่งนี้เมื่อทำการ RUN จะเกิด Error เช่น
Traceback (most recent call last):
File “<stdin>”, line 10, in <module>
ValueError: B6 in use
ตัวอย่าง 3.0 แสดงค่า อุณหภูมิ และความชื้นด้วย Sensor AHT10
ต่อขา Sensor AHT10 ดังนี้
เชื่อม Sensor AHT10 ขา SCL เข้ากับขา B6 ของ STM32F411
เชื่อม Sensor AHT10 ขา SDA เข้ากับขา B7 ของ STM32F411
ลง Library เพิ่มเติมคือ lib adafruit_ahtx0 และ busio
import time
import board
import adafruit_ahtx0
import busio
i2c = busio.I2C(board.B6, board.B7)
sensor = adafruit_ahtx0.AHTx0(i2c)while True:
print("\nTemperature: %0.1f C" % sensor.temperature)
print("Humidity: %0.1f %%" % sensor.relative_humidity)
time.sleep(2)i2c.deinit()
ตัวอย่าง 4.0 ใช้ LoRaWAN กับมอดูล Maxiiot DL7612-AS923-TH ผ่าน UART
Maxiiot DL7612-AS923-TH เป็นมอดูลที่ได้รับอนุญาตินำเข้าจาก กสทช. อ่านวิธีการใช้งานฉบับเต็มได้จาก คลิก
เชื่อม Module Maxiiot ขา TX เข้ากับขา A3 ของ Black Pill STM32F411
เชื่อม Module Maxiiot ขา RX เข้ากับขา A2 ของ Black Pill STM32F411
โค้ดต่อไปนี้ใช้ทดสอบการเชื่อมต่อกับมอดูลเท่านั้น ผู้ใช้งานต้องเขียนเพื่มเติมเพื่อให้สามารถใช้งานได้
import board
import busio
import digitalio
uart = busio.UART(board.A2, board.A3, baudrate=115200, timeout=.1, receiver_buffer_size=512)
# uart.write(b"AT+INFO\r\n")
uart.write(b"AT+NCONFIG\r\n")
print(uart.read().decode('utf-8'))
บางครั้งจะเกิด Error เนื่องจากการไม่ได้ยกเลิกการเรียกใช้งาน อาจจะแก้โดยกด Ctril-D
ValueError: Hardware in use, try alternative pins
หรือ
Traceback (most recent call last):
File “<stdin>”, line 6, in <module>
ValueError: A3 in use
ตัวอย่าง 5.0 LoRaWAN ส่งข้อความ Hello
ใช้กับมอดูล Maxiiot DL7612-AS923-TH โปรแกรมทีให้จะส่ง Hello ไปเรื่อยๆ
เชื่อม Module Maxiiot ขา TX เข้ากับขา A3 ของ Black Pill STM32F411
เชื่อม Module Maxiiot ขา RX เข้ากับขา A2 ของ Black Pill STM32F411
import board
import time
import busio
# import digitalio
uart = busio.UART(board.A2, board.A3, baudrate=115200, timeout=.1, receiver_buffer_size=512)
def sendATcommand(ATcommand):
print("{0}\r\n".format(ATcommand))
uart.write(bytearray(b"{0}\r\n".format(ATcommand)))
rstr = uart.read(270)
if rstr:
rstr = str(rstr, "utf-8")
rstr = rstr
print(rstr)
return (rstr)
sendATcommand("AT+NRB")
time.sleep(20.0)
sendATcommand("AT+INFO")
time.sleep(5.0)
sendATcommand("AT+NCONFIG")
time.sleep(5.0)
cnt = 1
while True:
print("Hello! #{}".format(cnt))
sendATcommand("AT+NMGS=7,01670119026873")
# sendATcommand("AT+NCMGS=5,HELLO\r\n")
cnt = cnt + 1
time.sleep(5.0)
ผลการ RUN
AT+NRBREBOOTINGBooting…
DevName: DL7612
Version: DL7612R01A74
LoraMac: 1.0.2
Date: 2019–01–23
Comp: Maxiiot Ltd.
OKAT+INFOChannelMask :255,0,0,0,0,0
+CGATT:1
MAXIIOT
DL7612
Revision:DL7612R01A74
Date:2019–01–23
OKAT+NCONFIG+NCONFIG:CLASS,A
+NCONFIG:ISMBAND,2
+NCONFIG:CHMASK,00ff,0000,0000,0000,0000,0000
+NCONFIG:RXWIN2,923200000,2
+NCONFIG:ACTIVATE,1
+NCONFIG:POWER,0
+NCONFIG:PORT,2
+NCONFIG:ADR,1
+NCONFIG:DR,2,10,0,0
+NCONFIG:CFM,1
+NCONFIG:NNMI Enable,1
+NCONFIG:PNMI Enable,1
Hello! #1
AT+NMGS=7,01670119026873OK
+NMGS:0
OK
ตัวอย่าง 6.0 ใช้ Sensor อุณหภูมิ ความชื้น AHT10 ส่งขึ้น LoRaWAN Network Server ด้วยรูปแบบ CayenneLPP
ใช้กับมอดูล Maxiiot DL7612-AS923-TH
เชื่อม Module Maxiiot ขา TX เข้ากับขา A3 ของ Black Pill STM32F411
เชื่อม Module Maxiiot ขา RX เข้ากับขา A2 ของ Black Pill STM32F411
ต่อขา Sensor AHT10 ดังนี้
เชื่อม Sensor AHT10 ขา SCL เข้ากับขา B6 ของ STM32F411
เชื่อม Sensor AHT10 ขา SDA เข้ากับขา B7 ของ STM32F411
import adafruit_binascii
import adafruit_ahtx0
import board
import time
import busio
from cayennelpp import CayenneLPP
rstr = ""
i2c = busio.I2C(board.B6, board.B7)
sensor = adafruit_ahtx0.AHTx0(i2c)
uart = busio.UART(board.A2, board.A3, baudrate=115200, timeout=.1, receiver_buffer_size=512)
def sendATcommand(ATcommand):
print("{0}\r\n".format(ATcommand))
uart.write(bytearray(b"{0}\r\n".format(ATcommand)))
rstr = uart.read(270)
if rstr:
rstr = str(rstr, 'utf-8')
rstr = rstr
print(rstr)
return (rstr)
sendATcommand("AT+NRB")
sendATcommand("AT+NCONFIG")
cnt = 1
while rstr != '+CGATT:1':
time.sleep(20.0) # Wait for Join Accept
rstr = sendATcommand('AT+CGATT')
print('Respond String')
print(rstr)
if rstr.startswith('+CGATT:1'):
print('++++OTAA OK+++++')
break
print('Retry OTAA Continue')
while True:
print("********Packet No #{}".format(cnt))
print("********AHT10 values:***********")
temp = sensor.temperature
hum = sensor.relative_humidity
print('temp:', temp, ' Hum:', hum)
time.sleep(2)
c = CayenneLPP()
c.addTemperature(1, float(temp))
c.addRelativeHumidity(2, float(hum))
d = adafruit_binascii.hexlify(c.getBuffer())
print('---------Start Send Status------------')
sendATcommand("AT+NMGS={0},{1}\r\n".format(int(len(d)/2), (str(d)[2:-1])))
print('---------End Send Status--------------')
cnt = cnt + 1
time.sleep(10.0)
ผลการ run แสดงบน ChirpStack LoRaWAN Server
วิธีการเพิ่ม Library ลงใน STM32F411
ดาวน์โหลดจาก https://circuitpython.org/libraries
เลือก Download Bundle Version 5.x ซึ่งจะมีทั้ง Library .mpy และ Example
การติดตั้ง Library คือ เลือก copy .mpy จากใน Zip ไฟล์ ไปไว้ใน /lib ของ Black Pill
ตามรูปคือตัวอย่าง Library สำหรับอุปกรณ์ที่ Adafruit เตรียมไว้ให้กับ CircuitPython ครับ
อ่านวิธีติดตั้ง Library ฉบับเต็ม จาก https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries
ใช้กับ MU
ให้เปลี่ยนชื่อ Code ที่จะ run เป็น code.py เมื่อ reload ใหม่ก็จะถูกสั่งให้ทำงาน
ประสบการณ์การใช้งาน
ตัว CircuitPython ที่ติดตั้งเป็น Version ที่ค่อนข้างใหม่คือ 5.3.0 ปรับปรุงเมื่อวันที่ 2020–04–29 การใช้ภาษา CircuitPython ค่อนข้างเข้มงวดด้าน semantic syntax มากกว่า MicroPython และยังมีการ Lock หรือ Unlock IO หรือ resource ต่างๆ
ค่า Default timeout ที่กำหนดมา ไม่ค่อยจะ User Friendly เท่าไรทำให้พบปัญหาในการเขียนหรือ Run โปรแกรมค่อนข้างบ่อย เช่น Pin in use, Hang ที่ Most Recently Call last และ ValueError: Hardware in use, try alternative pins เป็นต้น
ตัวอย่างตาม Tutorial ต่างๆ ที่หาพบใน internet ยังไม่ค่อยได้อัพเดทให้ใช้กับ Adafruit CircuitPython 5.3.0 ดังนั้นเมื่อ Copy นำมาลองทดสอบมักพบว่า run ไม่ค่อยได้
อาจจะต้องทำความคุ้นเคยอีกระยะหรือรอให้ผู้พัฒนามีการอัพเดทคู่มือหรือตัวอย่างให้ตรงกับ Version ใหม่นี้
โปรแกรม Thonny ยังมีปัญหากับการใช้งาน CircuitPython บน BlackPill บ้าง เช่นการลบ File บน Black Pill อาจจะเลี่ยงไปใช้ File Manager บน MS windows ลบจาก Virtual Drive H: แทน
ที่เห็นข้อดีคือมี Lib พร้อมตัวอย่างของ Sensor ที่ขายอยู่ในท้องตลาดอยู่แทบจะครบทุกตัว และตัว Black Pill มีทั้งขาไฟ 5V และ 3.3V สามารถเลือกไฟป้อนเข้า Sensor ได้ตรงตามที่ Sensor ต้องการได้
Wish List
ปัจจุบันผู้เขียนได้ทดลองใช้ Development Board สำหรับ Python ดังนี้คือ
1.Pyboard
2.SAMD21
3.STM32F411
4.Micro:bit
5.Maxduino
6.ESP32
ทุก Board สามารถใช้ MicroPython ได้ แต่จะมีบางบอร์ดเท่านั้นที่มี Firmware สำหรับ CircuitPython หวังว่าในอนาคตจะมี Firmware CircuitPython ให้ครบทั้ง 6 Development Board
ทั้ง 6 บอร์ดจะมีวิธี การ Flash Firmware ที่แตกต่างกัน
- อุปกรณ์ที่ใช้ต่อกับ PC (USB Type C, USB-TTL, ST-Link, J-Link)
- รูปแบบ Pin Mapping สำหรับเชื่อมสาย
- วิธีเข้าสู่ Flash โหมด (Auto, Jumper, กด MicroSwitch)
- โปรแกรมที่ใช้ (Pytool, Thonny, upycraft, STM32Cube, STM32 Demo GUI, DfuSe Demo เป็นต้น)
- ลิ้งค์ตำแหน่งเก็บ Firmware ของแต่ละ Board จะหลากหลาย
อนาคตหากมีเวปแหล่งเดียวที่ให้ความรู้ได้ครบทุกเรื่องข้างต้นก็จะดีมากครับ