CircuitPython for SAMD21

แนะนำการติดตั้งและใช้งาน CircuitPython สำหรับ Atmel/Microchip SAMD21 (ARM Cortex-M0+) เช่น บอร์ด Arduino Zero (Compatible)

วิธีการติดตั้ง CircuitPython สำหรับ SAMD21: วิธีที่ 1

เป้าหมายคือ เราก็ต้องการติดตั้ง Adafruit UF2 Bootloader ลงในหน่วยความจำ Flash ภายในชิป SAMD21 โดยใช้ Arduino Sketch เป็นตัวช่วย เมื่อสามารถใช้ Adafruit UF2 Bootloader ได้แล้ว จึงติดตั้งไฟล์เฟิร์แวร์ CircuitPython เป็นขั้นตอนถัดไป

  1. เตรียมบอร์ดไมโครคอนโทรลเลอร์ ATSAMD21 (Arduino Zero Compatible) เช่น WeMos / RobotDyn M0 / M0-Mini และได้ติดตั้ง Arduino Zero Bootloader ไว้พร้อมใช้งานแล้ว

  2. ติดตั้งแพคเกจสำหรับ Arduino SAMD Boards (ARM Cortex-M0+) สำหรับ Arduino Boards Manager / Arduino IDE

  3. ติดตั้ง Adafruit UF2 Bootloader สำหรับ SAMD21

  4. ติดตั้ง CircuityPython Firmware สำหรับ SAMD21

เริ่มต้นด้วยการเปิดใช้งาน Arduino IDE (Windows) และจะต้องมีการติดตั้งแพคเกจสำหรับ Arduino SAMD Boards (ARM Cortex-M0+) เพื่อคอมไพล์ Arduino Sketch สำหรับบอร์ดที่ใช้สถาปัตยกรรมดังกล่าว

บอร์ดที่ใช้ชิป SAMD21 นิยมใช้ชิป ATSAMD21G18A (32-bit ARM Cortex-M0+) หน่วยความจำภายใน 256KB Flash และ 32KB SRAM ความเร็วสูงสุด 48MHz

โดยปรกติ เราใช้ไฟล์เฟิร์มแวร์ Arduino Zero Bootloader (samd21_sam_ba.bin) สำหรับบอร์ดดังกล่าว แต่เราจะเปลี่ยนมาใช้ Adafruit UF2 Bootloader for UF2-SAMDx1 (ใช้ได้กับ SAMD21 และ SAMD51)

การติดตั้ง Adafruit UF2 Bootloader สำหรับการบอร์ด SAMD21 นั้น มีสองวิธี คือ

  1. วิธีแรก คือ การคอมไพล์ Arduino Sketch (.ino) ลงไปใน SAMD21 เมื่อทำงานจะเขียนข้อมูลส่วนที่เป็น UF2 Bootloader และอัปเดทลงในบริเวณของ On-chip Flash สำหรับทำหน้าที่เป็น Bootloader โดยใช้ซอฟต์แวร์ Arduino IDE ดังนั้นจะเขียนทับและอัปเดต Bootloader เดิมของ Arduino

  2. วิธีที่สอง คือ การติดตั้งโดยใช้ไฟล์ .bin แต่จะต้องใช้อุปกรณ์ที่เป็น SWD Programmer เช่น SEGGER J-Link Debug Probe เป็นต้น และ Arduino Bootloader ก็จะถูกเขียนทับเช่นกัน

ข้อดีของ Adafruit UF2 Bootloader คือ เมื่อติดตั้งได้แล้ว เราจะมองเห็น Virtual Driver (USB Mass Storage) เอาไว้สำหรับอัปโหลดไฟล์ Application File ประเภท .uf2 และนอกจากนั้นยังสามารถใช้กับ Arduino IDE ได้อีกด้วย สำหรับโปรแกรม Arduino Sketch ผ่านทาง USB-to-Serial (Virtual COM Port) ได้ตามปรกติ

ขั้นตอนในเอกสารนี้ ได้ทดลองใช้กับไฟล์ Arduino Sketch ที่ทางผู้พัฒนาของ Adafruit เผยแพร่เอาไว้: update-bootloader-zero-v3.10.0.ino หรือเลือกเวอร์ชันที่ใหม่กว่าได้จาก:

จากนั้นให้สร้างไดเรกทอรีสำหรับ Arduino Sketch ใหม่ ใน Arduino IDE และตั้งชื่อให้ตรงกับ update-bootloader-zero-v3.10.0 แล้วนำไฟล์ .ino ดังกล่าว ไปใส่ในไดเรกทอรีที่สร้างขึ้น

บอร์ดที่ได้นำมาทดลองใช้คือ WeMos M0-SAMD21 Mini ซึ่งมีขนาดเล็กกว่าและราคาถูกกว่าบอร์ด Arduino Zero

แหล่งข้อมูลที่เกี่ยวข้องบอร์ด SAMD21 M0-Mini และน่าจะมีประโยชน์สำหรับผู้ที่สนใจ สามารถศึกษาได้จาก https://github.com/BLavery/SAMD21-M0-Mini

เมื่อคอมไพล์และอัปโหลดไปยังบอร์ด SAMD21 ได้แล้ว ให้กดปุ่ม RESET บนบอร์ด 2 ครั้งติดกัน (Double Click) เราจะมองเห็น Virtual Drive ชื่อ ZEROBOOT และก็ยังมองเห็น Serial Port ของบอร์ดังกล่าวด้วยเช่นกัน

เมื่อมองเห็น Virtual Drive แล้ว ให้ลากไฟล์ .uf2 ไปยังไดรฟ์ดังกล่าว เพื่อทำขั้นตอนติดตั้ง CircuitPython

ข้อสังเกต: ไฟล์ที่เป็น CircuitPython Firmware สำหรับบอร์ด Arduino Zero Compatible มีให้เลือกสองแบบคือ .bin และ .uf2 สำหรับวิธีแรก ให้เราเลือกใช้ .uf2 เพราะมีความสะดวกในการติดตั้งใช้งาน และในขณะที่เขียนบทความนี้ เวอร์ชันล่าสุด คือ 6.0 (stable) และ 6.1 (beta) ออกมาให้ทดลองใช้งาน

เมื่อได้ดาวน์โหลดไฟล์ .uf2 มาแล้ว ให้ลากไฟล์นี้ไปใส่ลงใน Virtual Drive ของบอร์ด SAMD21 จากนั้นบอร์ด SAMD21 จะรีเซตตัวเอง และเมื่อเริ่มทำงานอีกครั้ง ชื่อไดรฟ์ที่ปรากฏจะเปลี่ยนเป็น CIRCUITPY

ตอนนี้เราก็สามารถเปิดโปรแกรมอย่างเช่น Mu Editor หรือ Thonny IDE เชื่อมต่อกับ CircuitPython REPL ผ่านทางพอร์ต Virtual Serial (over USB) ได้

‍‍ ‍‍วิธีการติดตั้ง CircuitPython สำหรับ SAMD21: วิธีที่ 2

เป้าหมายคือ การติดตั้ง Adafruit UF2 Bootloader สำหรับ SAMD21 โดยใช้อุปกรณ์ SWD Programmer

วิธีนี้จะต้องใช้อุปกรณ์ฮาร์ดแวร์เสริม เช่น J-Link Debug Probe นำมาต่อกับบอร์ด SAMD21 โดยใช้รูปแบบที่เรียกว่า SWD (Serial Wire Debug) และใช้สาย Jumper จำนวน 4 เส้น คือ VCC (3.3V), GND, SWDIO, SWCLK และใช้ร่วมกับซอฟต์แวร์ของบริษัท SEGGER ที่มีชื่อว่า J-Link

ในกรณีนี้ จะต้องดาวน์โหลดไฟล์ เช่น bootloader-zero-v3.10.0.bin (หรือใหม่กว่า) ได้จาก https://github.com/adafruit/uf2-samdx1/releases/

ถัดไปให้เชื่อมต่ออุปกรณ์ J-Link Debug Probe กับบอร์ด SAMD21 โดยใช้ SWD Interface จากนั้นเปิดโปรแกรม SEGGER J-Flash เลือกอุปกรณ์ (Device) เป็น ATSAMD21G18A แล้วทำคำสั่งจากเมนู Target > Connect

เมื่อเชื่อมต่อกับอุปกรณ์และบอร์ด SAMD21 ผ่านทาง SWD โดยใช้อุปกรณ์ J-Link ได้แล้ว ให้เปิดไฟล์ (หรือลากมาวาง) .bin ที่ได้ดาวน์โหมดมา แล้วทำขั้นตอน Erase Chip และ Program Verify ตามลำดับ

ข้อสังเกต: การเชื่อมต่ออุปกรณ์ SEGGER J-Link ซึ่งมีคอนเนกเตอร์แบบ 2x10 Pin (JTAG Interface, 2.54mm spacing) ไปยังบอร์ด SAMD21 M0-Mini ที่ใช้คอนเนกเตอร์แบบ 2x5 Pin (SWD interface, 1.27mm spacing) จะต้องใช้โมดูลแปลงที่เรียกว่า JTAG-to-SWD Converter (ดูตัวอย่างได้จากอุปกรณ์ของบริษัท Adafruit) และสายเคเบิล

เมื่อทำมาถึงขั้นตอนนี้ เราก็ได้ Adafruit UF2 ฺBootloader ติดตั้งไว้ใน SAMD21 สำเร็จแล้ว จากนั้นก็ติดตั้งไฟล์ .uf2 ผ่าน Virtual Drive ตามที่ได้อธิบายไว้เหมือนวิธีแรก

ถัดไปเราก็สามารถทดลองเขียนโค้ด CircuitPython โดยใช้ Editor / IDE อย่างเช่น Mu Editor หรือ Thonny IDE

การใช้งานบอร์ด Seeeduino XIAO

บอร์ดไมโครคอนโทรลเลอร์ที่ใช้ชิป ATSAMD21 อีกตัวเลือกหนึ่งคือ บอร์ด XIAO ที่จำหน่ายโดย SeeedStudio บอร์ดนี้มีขนาดค่อนข้างเล็ก สามารถเสียบขาลงบนเบรดบอร์ดได้ เชื่อมต่อกับคอมพิวเตอร์ด้วย USB-C และได้ติดตั้ง UF2 Bootloader มาพร้อมใช้งานแล้ว

ไฟล์ Schematic ของบอร์ด: https://files.seeedstudio.com/wiki/Seeeduino-XIAO/res/Seeeduino-XIAO-v1.0-SCH-191112.pdf

การเข้าสู่โหมด UF2 Bootloader จะต้องใช้ลวดสายไฟเชื่อมต่อหรือสัมผัสที่ขา RST (Reset) ไปยัง GND ซึ่งมีลักษณะเป็น Pad อยู่ด้านบนของบอร์ด บริเวณด้านข้างของ USB-C Connector โดยจะต้องสัมผัสสองครั้งอย่างเร็ว เสมือนการกดปุ่ม Double Click

เมื่อเข้าสู่โหมด UF2 Bootloader ได้แล้ว จะมองเห็น Virtual Drive ชื่อ Arduino จากนั้นให้ลากไฟล์ .uf2 สำหรับ CircuitPython เพื่อทำการติดตั้ง ไฟล์ .uf2 สำหรับบอร์ดนี้ สามารถดาวน์โหลดได้จาก https://circuitpython.org/board/seeeduino_xiao/

ภายในไฟล์ INFO_UF2.TXT มีข้อความตามตัวอย่างดังนี้

UF2 Bootloader v3.7.0-33-g90ff611-dirty SFHWRO
Model: Seeeduino XIAO
Board-ID: SAMD21G18A-XIAO-v0

หลังจากที่ได้ติดตั้ง CircuitPython แล้ว จะมองเห็น Virtual Drive ที่มีชื่อว่า CIRCUITPY

ตัวอย่างโค้ดเพื่อทดสอบการทำงานเบื้องต้น

การทำงานของโค้ดตัวอย่างนี้ จะต้องต่อวงจรเพิ่มบนเบรดบอร์ดสำหรับ LEDs และวงจรปุ่มกด (Push Button) โดยใช้ขา D7, D8, D9 สำหรับ LED Output และ ขา D11 สำหรับ Push Button Input (Active-Low, Internal Pull-Up)

ให้สร้างไฟล์ให้ ใช้ชื่อ code.py หรือ main.py แล้วใส่โค้ดตามตัวอย่าง แล้วบันทึกไปยังอุปกรณ์ (บอร์ด SAMD21)

import time
import board
import random
from digitalio import DigitalInOut, Direction, Pull

# define GPIO pin numbers for Button and LEDs
btn_pin  = board.D11
led_pins = [board.D7, board.D8, board.D9]

# configure the Button pin object (input with pull-up)
btn = DigitalInOut(btn_pin)
btn.direction = Direction.INPUT
btn.pull = Pull.UP

# configure the LED pin objects (output)
leds = []
for pin in led_pins:
    led = DigitalInOut(pin)
    led.direction = Direction.OUTPUT
    leds.append( led )

try:
    t_saved = int(time.monotonic()*1000)
    cnt = 0
    # press the Button to stop or Ctrl+C
    while btn.value == True:
        # get current system time in msec
        t_now = int(time.monotonic()*1000)
        if t_now - t_saved >= 1000:
            print( 'Count: {}'.format(cnt) )
            cnt += 1
            t_saved = t_now
            index = random.randrange(0, 3)
            leds[index].value = True
            time.sleep(0.5)
            leds[index].value = False
except KeyboardInterrupt:
    pass

btn.deinit() # release button pin
for led in leds:
    led.deinit() # release LED pinprint('Done')

การทำงานของโค้ดตัวอย่าง จะทำให้ LED ติดและดับ ทีละดวง โดยการสุ่มเลือก ถ้าต้องการให้จบการทำงาน ให้กดปุ่ม Push Button ที่นำมาต่อเป็นอินพุต หรือถ้าเชื่อมต่อผ่าน CircuitPython REPL (Shell) ให้กดปุ่ม Ctrl+C

โค้ดตัวอย่างสำหรับบอร์ด XIAO

import time
import board
from digitalio import DigitalInOut, Direction

led = DigitalInOut( board.D13 ) # onboard LED
led.direction = Direction.OUTPUT
try:
    while True:
        led.value = True
        time.sleep(0.5)
        led.value = False
        time.sleep(0.5)
except KeyboardInterrupt:
    pass
led.deinit() # release LED pin
print('Done')

การใช้งาน Mu Editor สำหรับ CircuitPython-SAMD21

ซอฟต์แวร์ Mu Editor เป็น Open Source IDE ที่รองรับการเขียนโค้ดและใช้งาน CircuitPython สามารถใช้งานได้กับบอร์ดของ Adafruit และบอร์ดของผู้ผลิตอื่นได้

ในกรณีที่ใช้บอร์ด Seeeduino XIAO (SAMD21) พบว่า Mu Editor ไม่มีรายการ USB Device สำหรับบอร์ด XIAO เราก็สามารถแก้ไขได้ไม่ยาก โดยเพิ่มรายการลงในไฟล์ circuitpython.py ของ Mu Editor (ดูรูปภาพประกอบ)

สำหรับ Windows 10 ไฟล์ circuitpython.py จะอยู่ในไดเรกทอรี C:\Users\%USERNAME%\AppData\Local\Mu\pkgs\mu\modes\

ข้อสังเกตในการใช้งานบอร์ด SAMD21

ในเอกสารนี้ได้ยกตัวอย่างและเลือกใช้บอร์ดไมโครคอนโทรลเลอร์ที่ใช้ชิป ATSAMD21 เพื่อนำมาทดลองใช้กับ CircuitPython ซึ่งมีสองกรณี ได้แก่บอร์ด SAMD21 M0-Mini และ Seeeduino XIAO

บอร์ดเหล่านี้อาจมีการกำหนดและใช้งานขา I/O ที่แตกต่างกัน จำนวนขาที่ใช้ได้ไม่เท่ากัน ถ้าต้องการแสดงรายการขา I/O ที่ใช้กับ CircuitPython และดูความเชื่อมโยงระหว่างขา Board Pins และ Microcontroller Pins ก็ให้ทำคำสั่งต่อไปนี้ทางช่องทาง CircuitPython REPL

import board
help(board)

import microcontroller
help(microcontroller.pin)

ตัวอย่างข้อความเอาต์พุตสำหรับ CircuitPython-ZERO สำหรับบอร์ด SAMD21 M0-Mini แสดงรายการสำหรับ Board Pins

object <module ''> is of type module
  A0 -- board.A0
  A1 -- board.A1
  A2 -- board.A2
  A3 -- board.A3
  A4 -- board.A4
  A5 -- board.A5
  D0 -- board.D0
  RX -- board.D0
  D1 -- board.D1
  TX -- board.D1
  D2 -- board.D2
  D3 -- board.D3
  D4 -- board.D4
  D5 -- board.D5
  D6 -- board.D6
  D7 -- board.D7
  D8 -- board.D8
  D9 -- board.D9
  D10 -- board.D10
  D11 -- board.D11
  D12 -- board.D12
  D13 -- board.D13
  SDA -- board.SDA
  SCL -- board.SCL
  SCK -- board.SCK
  MOSI -- board.MOSI
  MISO -- board.MISO
  I2C -- <function>
  SPI -- <function>
  UART -- <function>

ตัวอย่างข้อความเอาต์พุตสำหรับ CircuitPython-ZERO สำหรับบอร์ด SAMD21 M0-Mini แสดงรายการสำหรับ Microcontroller Pins

object <module ''> is of type module
  PA00 -- microcontroller.pin.PA00
  PA01 -- microcontroller.pin.PA01
  PA02 -- board.A0
  PA03 -- microcontroller.pin.PA03
  PA04 -- board.A3
  PA05 -- board.A4
  PA06 -- board.D8
  PA07 -- board.D9
  PA08 -- board.D4
  PA09 -- board.D3
  PA10 -- board.D1
  PA11 -- board.D0
  PA12 -- board.MISO
  PA13 -- microcontroller.pin.PA13
  PA14 -- board.D2
  PA15 -- board.D5
  PA16 -- board.D11
  PA17 -- board.D13
  PA18 -- board.D10
  PA19 -- board.D12
  PA20 -- board.D6
  PA21 -- board.D7
  PA22 -- board.SDA
  PA23 -- board.SCL
  PA27 -- microcontroller.pin.PA27
  PA28 -- microcontroller.pin.PA28
  PA30 -- microcontroller.pin.PA30
  PA31 -- microcontroller.pin.PA31
  PB02 -- board.A5
  PB03 -- microcontroller.pin.PB03
  PB08 -- board.A1
  PB09 -- board.A2
  PB10 -- board.MOSI
  PB11 -- board.SCK
  PB22 -- microcontroller.pin.PB22
  PB23 -- microcontroller.pin.PB23

ถ้ารันโค้ดดังกล่าว โดยใช้ CircuitPython-XIAO จะได้ข้อความเอาต์พุตที่แตกต่างออกไปในบางส่วน

กล่าวสรุป

ในเนื้อหาส่วนนี้ ได้นำเสนอการติดตั้ง Adafruit UF2 Bootloader ให้กับบอร์ดไมโครคอนโทรลเลอร์ SAMD21 ที่ทำงานได้เหมือนบอร์ด Arduino Zero (Compatible) แต่ถ้าใช้บอร์ด Seeeduino XIAO ก็มี UF2 Bootloader ติดตั้งมาให้แล้ว จากนั้นก็ได้ติดตั้ง CircuitPython Firmware โดยใช้ไฟล์ .UF2 และทดลองเขียนโค้ดใน IDE เช่น Thonny IDE เชื่อมต่อกับบอร์ดดังกล่าว

เผยแพร่ภายใต้ลิขสิทธิ์ Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)

Last updated