[TH] esp/esp32 class

บทความนี้เป็นการเรียนรู้การใช้งานคลาส esp และ esp32 ที่เป็นคลาสสำหรับใช้งานเฉพาะกับไมโครคอนโทรลเลอร์ esp8266 และ esp32 เพื่อเข้าถึงคุณลักษณะเฉพาะ และความสามารถภายในของชิพทั้ง 2

esp

เป็นคลาสที่ออกแบบเพื่อใช้งานกับไมโครคอนโทรลเลอร์ esp8266 และ esp32 เป็นการเฉพาะ ซึ่งประกอบไปด้วยฟังก์ชันและค่าคงที่ต่าง ๆ ดังภาพที่ 1

ภาพที่ 1 คลาส esp

ฟังก์ชัน info() ให้ข้อมูลเกี่ยวกับค่าตำแหน่งเริ่มต้น/สิ้นสุดของโปรแกรม ค่าเริ่มต้น/สิ้นสุดของrom0 ค่าเริ่มต้น/สิ้นสุดของหน่วยความจำเก็บข้อมูล ค่าเริ่มต้น/สิ้นสุดของข้อมูลแบบอ่านอย่างเดียว ค่าเริ่มต้น/สิ้นสุดของหน่วยความจำสแตก ค่าเริ่มต้นและสิ้นสุดของหน่วยความจำฮีพ (หรือ RAM สำหรับใช้งาน) และข้อมูลเกี่ยวกับ qstr/GC ดังภาพที่ 2

ภาพที่ 2 ตัวอย่างผลลัพธ์จากคำสั่ง info()

การกำหนดโหมดสลีปเพื่อประหยัดพลังงานทำได้ 3 แบบ คือ SLEEP_NONE, SLEEP_LIGHT และ SLEEP_MODEM หรือ 0, 1 และ 2 ซึ่งหมายถึง

  1. เป็นการกำหนดยกเลิกการสลีป
  2. ประหยัดพลังงานด้วยการหยุดการทำงานของหน่วยประมวลผลและWiFi
  3. ปิดการทำงานของ WiFi

โดยรูปแบบของการตรวจสอบรูปแบบคำสั่งตรวจสอบโหมดสลีป และกำหนดโหมดสลีปเป็นดังนี้

โหมด = esp.sleep_type()
esp.sleep_type( โหมด )

เมื่อใช้งานไมโครคอนโทรลเลอร์ esp8266 (สำหรับ ESP32 ต้องใช้ machine.deepsleep()) และต้องการเข้าสู่โหมดสดีปลีปเพื่อประหยัดพลังงานเป็นระยะเวลาที่กำหนดซึ่งต้องต่อ GPIO 16 เข้ากับขารีเซ็ตเพื่อใช้เป็นขาส่งสัญญาณรีเซ็ตเมื่อครบตามเวลาที่กำหนด หรือกดปุ่มรีเซ็ตเพื่อกลับมาทำงานใหม่ โดยรูปแบบของคำสั่งเป็นดังนี้

esp.deepsleep( หน่วยเวลาไมโครวินาที )

คำสั่งสำหรับอ่านค่า id ของหน่วยความจำแฟลชมีรูปแบบของการใช้งานดังนี้

esp.flash_id()

คำสั่งสำหรับใช้สอบถามปริมาณหน่วยความจำแฟลชมีรูปแบบการใช้งานดังต่อไปนี้

esp.flash_size()

ในบางครั้งผู้เขียนโปรแกรมต้องการเขียนข้อมูลลงหน่วยความจำแฟลชที่สามารถใช้งานได้ เพื่อใช้เป็นที่เก็บข้อมูลชั่วคราวสำหรับโปรแกรมที่พัฒนาขึ้น สามารถตรวจสอบตำแหน่งเริ่มต้นของหน่วยความจำแฟลชที่เขียนได้ หรือสั่งลบ/เขียน/อ่านหน่วยความจำแฟลชที่ระบุได้ด้วยคำสั่งต่าง ๆ ต่อไปนี้

ค่าตำแหน่ง = esp.flash_user_start()
esp.flash_erase(ตำแหน่งที่ต้องการลบ)
esp.flash_write(ตำแหน่ง, ค่าไบต์ที่ต้องการเขียน)
ข้อมูลที่อ่านได้ = esp.flash_read(ตำแหน่ง, จำนวนไบต์ที่ต้องการอ่าน )

สิ่งที่ทีมงานเราชอบที่สุดคือ ชุดคำสั่งสำหรับการขอจองหน่วยความจำฮีพ และการยกเลิกหน่วยความจำที่จอง ทำให้สะดวกเหมือนกับการเขียนในภาษา C/C++ โดยคำสั่งดังกล่าวเป็นดังนี้ ซึ่งค่าที่คินกลับจากการจองมี 2 กรณี คือ กรณีที่ให้ค่ากลับเป็น 0 หมายถึงการจองไม่ประสบความสำเร็จ และกรณีที่ได้ค่าตัวเลขที่มากกว่า 0 ซึ่งเป็นค่าเริ่มต้นของตำแหน่งหน่วยความจำที่ขอจอง

ตัวแปรอ้างอิงหน่วยความจำ = esp.malloc( จำนวนไบต์ที่ขอจอง )
esp.free( ตัวแปรอ้างอิงหน่วยความจำ )

ตัวอย่างการใช้งานคำสั่งอื่น ๆ ของคลาส esp เป็นดังต่อไปนี้ และได้ตัวอย่างผลลัพธ์ดังภาพที่ 3

# demoExp.py
# 2021-007-15 by JarutEx (https://www.jarutex.com)
import esp
print("> Class ..................: {}".format(esp.__name__))
print("> Firmware checking ......:");
print("validate :{}".format(esp.check_fw()))
print("> Flash ID ...............: {}".format(esp.flash_id()))
print("> Flash size .............: {}".format(esp.flash_size()))
print("> Flash User Start .......: {}".format(esp.flash_user_start()))
print("> memory infoamtion ......: {}".format(esp.meminfo()))
print("> Memory allocation ......:")
print("     before malloc 4KB ...: {} Bytes".format(esp.freemem()))
x = esp.malloc(4096)
print("     location of x .......: {}".format(x))
print("     after malloc 4KB ....: {} Bytes".format(esp.freemem()))
esp.free(x)
print("     after free ..........: {} Bytes".format(esp.freemem()))
x = esp.malloc( esp.freemem() + 1 )
if (x == 0):
    print("Not enough memory!!!")
ภาพที่ 3 ตัวอย่างผลลัพธ์จากโปรแกรม demoEsp.py

นอกจากนี้ยังมีฟังก์ชันสำหรับสั่งงานโมดูล DHT สมาร์ทพิกเซล (APA102) และ neopixel เป็นการเฉพาะให้ใช้งาน ซึ่งรูปแบบของการใช้งานเป็นดังนี้

esp.dht_readinto( pin, buf )
esp.apa102_write( clockPin, dataPin, pixels, numBytes )
esp.neopixel_write( pin, pixels, numBytes, is800KHz )

สำหรับการเปิดและปิดการแสดงข้อความสำหรับใช้ Debug การทำงานของโปรแกรมผ่านทาง UART ใช้คำสั่งดังนี้

esp.osdebug( หมายเลขพอร์ต UART )
esp.osdebug( None )

esp32

สำหรับคลาส esp32 เป็นคลาสที่ทำเพิ่มเติมสำหรับใช้กับไมโครคอนโทรลเลอร์ ESP32 เป็นการเฉพาะโดยรายการฟังก์ชัน คลาสย่อยและค่าคงที่เป็นดังภาพที่ 4

ภาพที่ 4 รายการคำสั่ง คลาสและค่าคงที่ของ esp32

จากภาพที่ 4 จะพบว่าการอ่านค่าความร้อนของเซ็นเซอร์ความร้อนภายใน ESP32 และค่าแม่เหล็ก (Hall Effect) สามารถกระทำผ่านคำสั่งตามรูปแบบต่อไปนี้

ค่าอุณหภูมิแบบฟาเรนไฮต์ = esp32.raw_temperature()
ค่าอุณหภูมิแบบเซลเซียส = (esp32.raw_temperature() -32.0)/1.8
ค่าคลื่นแม่เหล็ก = esp32.hall_sensor()

การเข้าถึงข้อมูลหน่วยความจำฮีพด้วยคำสั่ง idf_heap_info( ) มีรูปแบบของการใช้งานดังนี้ โดยค่าของคุณสมบัติ (capacities) ได้แก่ esp32.HEAP_DATA สำหรับการเข้าถึงหน่วยความจำเก็บข้อมูล และ esp32.HEAP_EXEC สำหรับการเข้าถึงหน่วยความจำชุดคำสั่งที่สามารถนำมาประมวลผลได้ด้วยตัวประมวลผล

ข้อมูล = esp32.idf_heap_info( คุณสมบัติที่ต้องการเข้าถึง )

ตัวอย่างของการสั่งแสดงข้อมูล idf_heap_info( ) เป็นดังนี้ และได้ผลลัพธ์ดังภาพที่ 5 ซึ่งผลลัพธ์ที่ได้เป็นข้อมูลแบบทูเพิล 4 ชุด คือ จำนวนไบต์ของฮีพ จำนวนไบต์ที่เหลือ ขนาดบล็อกที่ใหญ่ที่สุดที่สามารถจองได้ และจำนวนน้อยสุดที่สามารถเรียกคืนได้เมื่อหมดเวลาการใช้งาน

import esp32
print("=== HEAP DATA INFO ===")
print(esp32.idf_heap_info( esp32.HEAP_DATA ))
print("=== HEAP EXEC INFO ===")
print(esp32.idf_heap_info( esp32.HEAP_EXEC ))
ภาพที่ 5 ตัวอย่างผลลัพธ์การใช้ idf_heap_info( )

จากภาพที่ 5 จะพบว่าในฮีพข้อมูลนั้นมีให้ใช้ 5 ก้อน แต่ละก้อนมีขนาด 7280 16648 94608 15072 และ 113840 ส่วนฮีพโปรแกรมมีด้วยกัน 3 ก้อน ซึ่งมีขนาด 15072 113840 และ 23656 เป็นต้น

นอกจากนี้ฟังก์ชันในกลุ่มของการ wake_up หรือตั้งค่าการถูกปลุกจากการสลีปมีด้วยกัน 3 คำสั่งจากการ Touch (กำหนดค่า wake เป็น True หรือ False เพื่อเปิดและปิดการปลุกจากการทัช), EXT0 และ EXT1 ดังรูปแบบต่อไปนี้ โดยค่าของระดับมี 2 แบบ คือ esp32.WAKEUP_ALL_LOW และ esp32.WAKEUP_ANY_HIGH ส่วนรายการขานั้นสามารถระบุเป็น None หรือข้อมูลแบบทูเพิล/ลิสต์

esp32.wake_on_touch( wake )
esp32.wake_on_ext0( ขาที่ต้องการตรวจสอบ, ระดับ )
exp32.wake_on_ext1( รายการขา, ระดับ )

Partition

เป็นคลาสสำหรับการเข้าถึงพาร์ทิชันของหน่วยความจำแฟลชและรวมถึงชุดคำสั่งสำหรับการเปิดการทำอัพเดตแบบ OTA (over-the-air) รายการของคลาส Partition เพื่อบริหารจัดการพาร์ทิชันของหน่วยความจำแฟลช เป็นดังภาพที่ 7

ภาพที่ 7 คลาส esp32.Partition

การสร้างวัตถุเพื่อเข้าถึงพาร์ทิชันมีรูปแบบดังนี้ โดยค่า id คือ Partition.BOOT หรือ Partition.RUNNING หรือสตริงที่เป็นชื่อของพาร์ทิชันที่ต้องการเข้าถึง

วัตถุ = esp32.Partition( id )

รายชื่อของพาร์ทิชันของ Micropython จากไฟล์ partitions.csv เป็นดังนี้ ซึ่งจะพบว่า nvs เป็นพาร์ทิชันหนึ่งของระบบไฟล์ของ Micropython และประเภทของพาร์ทิชันมี 2 ประเภท คือ esp32.TYPE_APP และ esp32.TYPE_DATA

# Notes: the offset of the partition table itself is set in
# $ESPIDF/components/partition_table/Kconfig.projbuild and the
# offset of the factory/ota_0 partition is set in makeimg.py
# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 0x200000,
vfs,      data, fat,     0x220000, 0x180000,

การอ่านข้อมูลของพาร์ทิชันที่ขอเข้าถึงมีรูปแบบของคำสั่งดังนี้

วัตถุ.info()

ซึ่งผลลัพธ์ที่ได้กลับมาเป็นขอมูลแบบทูเพิลมีสมาชิก 6 ตัว แต่ละตัวมีความหมายเป็น type, subtype, addr, size, label และ encrypted ตามลำดับ ตัวอย่างของการอ่านข้อมูลของพาร์ทิชัน vfs ได้ข้อมูลกลับมาดังนี้

(1, 129, 2228224, 1572864, 'vfs', False)

การค้นหาพาร์ทิชันตามประเภท (type) ประเภทย่อย (subtype) และชื่อของพาร์ทิชัน (label) มีรูปแบบการใช้งานของคำสั่งดังนี้ ซึ่งถ้ากำหนดประเภทย่อยเป็น 255 หรือชื่อของพาร์ทิชันเป็น None หมายถึงประเภทใดก็ได้ หรือชื่อใดก็ได้

esp32.Partition.find( type=TYPE_APP, subtype=255, label=None )

กรณีที่ต้องการเปลี่ยนสถานะของพาร์ทิชันให้สามารถบูตได้เพื่อให้เป็นพาร์ทิชันเริ่มทำงานในครั้งต่อไปสามารถทำได้ด้วยคำสั่งดังนี้

วัตถุ.set_boot()

กลุ่มคำสั่งสำหรับอ่านและเขียนบล็อกข้อมูล (buf) ในบล็อก (block_num) ณ ตำแหน่ง (offset) ที่ต้องภายในพาร์ทิชันที่ต้องการเข้าถึงมีดังนี้

วัตถุ.readblocks( block_num, buf )
วัตถุ.readblocks( block_num, buf, offset )
วัตถุ.writeblocks( block_num, buf )
วัตถุ.writeblocks( block_num, buf, offset )

กรณีที่ต้องการควบคุมการทำงานของพาร์ทิชันต้องสั่งงานผ่าน ioctl( ) ซึ่งการใช้งานเหล่านี้เป็นการขยายความสามารถของคลาส os เพื่อใช้เฉพาะกับไมโครคอนโทรลเลอร์ esp32 ดังรูปแบบการใช้งานต่อไปนี้

วัตถุ.ioctl( cmd, arg )

จากรูปแบบคำสั่ง ioctl( ) มีข้อกำหนดเรื่อง cmd ดังนี้ ซึ่งเมื่อรวมกับการเขียนข้อมูลลงบล็อกทำให้เราสามารถทำ OTA ได้

  • 1 เป็นการสั่งให้เริ่มต้นใช้งาน (initial) พาร์ทิชัน (ไม่ต้องกำหนด arg)
  • 2 เป็นการสั่งให้ปิดการทำงาน (shutdown) พาร์ทิชัน (ไม่ต้องกำหนด arg)
  • 3 เป็นการสั่งซิงค์ (Sync) พาร์ทิชัน (ไม่ต้องกำหนด arg)
  • 4 อ่านค่าจำนวนบล็อกของพาร์ทิชัน (ไม่ต้องกำหนด arg)
  • 5 อ่านค่าจำนวนไบต์ต่อบล็อก ซึ่งค่าปกติจะเป็น 512 ไบต์ (ไม่ต้องกำหนด arg)
  • 6 ลบบล็อกหมายเลข arg

และคำสั่งสำหรับค้นหาพาร์ทิชันถัดไปที่จะถูกเรียกมาทำงานเป็นดังนี้ ซึ่งถ้าไม่มีพาร์ทิชันดังกล่าวจะเกิด OSError: [Errorno 2] ENOENT

วัตถุประเภทrunning .get_next_update()

ตัวอย่างโปรแกรมการใช้งานคลาส esp32.Partition เป็นดังนี้

#############################################################
# demoPartition.py
# (C) 2021, JarutEx
# https://www.jarutex.com
#############################################################
import esp32

def showPartitionInfo( x ):
    part = esp32.Partition(x)
    info = part.info()
    print("Partition information")
    printPartitionInfo(info)
    print("    Number of blocks {}".format(part.ioctl(4,...)))
    print("    block size ..: {} byte(s)".format(part.ioctl(5,...)))
    
def printPartitionInfo( info ):
    print("    Name ........: {}".format(info[4]))
    print("    Type ........: {}".format(info[0]))
    print("    SubType .....: {}".format(info[1]))
    print("    Address .....: {}".format(info[2]))
    print("    Size  .......: {} Bytes".format(info[3]))
    print("    Encrypted ...: {}".format(info[5]))
    
def showPartitions():
    partApp = esp32.Partition.find(type=esp32.Partition.TYPE_APP)
    partData = esp32.Partition.find(type=esp32.Partition.TYPE_DATA)
    print("APP Partition ({})".format(len(partApp)))
    for i in range(len(partApp)):
        print("  {}.{}".format(i+1,partApp[i]))
        printPartitionInfo(partApp[i].info())
        print("    Number of blocks {}".format(partApp[i].ioctl(4,...)))
        print("    block size ..: {} byte(s)".format(partApp[i].ioctl(5,...)))
    print("DATA Partition ({})".format(len(partData)))
    for i in range(len(partData)):
        print("  {}.{}".format(i+1,partData[i]))
        printPartitionInfo(partData[i].info())
        print("    Number of blocks {}".format(partData[i].ioctl(4,...)))
        print("    block size ..: {} byte(s)".format(partData[i].ioctl(5,...)))
    
showPartitions()
showPartitionInfo( "nvs" )
running = esp32.Partition(esp32.Partition.RUNNING)
print("esp32.Partition.RUNNING")
printPartitionInfo(running.info())
try:
    nextRunning = running.get_next_update()
except:
    print("No next update!")

NVS

NVS (Non-Volatile Storage) เป็นหน่วยความจำที่ ESP32 ใช้งาน ซึ่งโครงสร้างการจัดเก็บเป็นลักษณะแบบพาร์ทิชันและระบุพาร์ทิชันด้วยเนมสเปซ (namespace) โดยแต่ละพาร์ทิชันประกอบด้วยกลุ่มของรายการข้อมูลที่ประกอบด้วย คีย์และค่าของคีย์ซึ่งเป็นข้อมูลประเภทตัวเลขจำนวนเต็ม สตริงหรือก้อนข้อมูลแบบไบนารีหรือไบนารีบล็อบ (binary blobs) ปัจจุบันรองรับเฉพาะตัวเลขจำนวนเต็มขนาด 32 บิต และไบนารีบล็อบเท่านั้น

รายการคลาส NVS เป็นดังภาพที่ 6

ภาพที่ 6 รายการของคลาส esp32.NVS

การสร้างวัตถุเพื่อเข้าถึงเนมสเปซของ NVS มีรูปแบบดังนี้

วัตถุ = esp32.NVS( namespace )

คำสั่งสำหรับกำหนดค่าตัวเลขจำนวนเต็มขนาด 32 บิตให้กับคีย์มีรูปแบบดังนี้

วัตถุ.set_i32( key, ค่าตัวเลข )

การอ่านค่าค่าตัวเลขจากคีย์ใช้คำสั่งดังนี้

ข้อมูล = วัตถุ.get_i32( คีย์ )

กรณีของข้อมูลไบนารีบล็อบสามารถสร้างขึ้นได้ด้วยรูปแบบคำสั่งต่อไปนี้

วัตถุ.set_blob( คีย์ )

สำหรับการอ่านค่าไบนารีบล็อบใช้คำสั่งดังนี้

ข้อมูล = วัตถุ.get_blob( คีย์ )

ถ้าไม่ใช้งานคีย์ให้ลบออกด้วยคำสั่งต่อไปนี้

วัตถุ.erase( คีย์ )

แต่อย่างไรก็ดี set_i32( ) และ set_blob( ) เป็นการสร้างข้อมูลขึ้นในหน่วยความจำ ถ้าต้องการบันทึกลง NVS ต้องสั่ง commit() ดังนี้

วัตถุ.commit( )

RMT

รายการของคลาส RMT สำหรับใช้กับเซ็นเซอร์เชื่อมต่อกับรีโมทคอนโทรลผ่านทางเซ็นเซอร์ IR (infra-red) เป็นดังภาพที่ 8

ภาพที่ 8คลาส esp32.RMT

ณ ตอนที่เขียนบทความนี้คลาส RMT รองรับการทำงานที่สัญญาณนาฬิกาความถี่ 80MHz (ดังนั้นจึงไม่สามารถตั้งค่าความถี่ด้วย source_freq ได้) และสามารถตั้งค่าตัวหารสัญญาณนาฬิกาที่เป้นตัวเลขจำนวนเต็ม 8 บิต (0-255) เพื่อให้เหมาะสมกับอุปกรณ์ที่กำลังสื่อสารด้วย ซึ่งคำสั่งสำหรับสร้างวัตถุ RMT มีรูปแบบดังนี้ โดย หมายเลขช่องสัญญาณที่เลือกใช้ได้มี 8 ช่อง (0-7), ค่า idle_level มีค่าเป็น True หมายถึงระดับแรงดัน High และ False คือระดับแรงดัน Low, tx_carrirer เป็นข้อมูลทูเพิลจำนวน 3 สมาชิกที่เป็นตัวเลขจำนวนเต็มที่เป็นค่าบวก ได้แก่ carrier frequency, duty percent (มีค่าอยู่ในช่วง 0 ถึง 100) และค่าระดับแรงดัน 1 (high) หรือ 0 (low)

วัตถุ = esp32.RMT( หมายเลขช่องสัญญาณ, pin=machine.Pin( หมายเลขขา ), clock_div=ค่าตัวหาร, idle_level=False, tx_carrier=None )
วัตถุ = esp32.RMT( หมายเลขช่องสัญญาณ, pin=machine.Pin( หมายเลขขา ), clock_div=ค่าตัวหาร, tx_carrier=(38000, 50, 1) )

เมื่อเลิกใช้งานต้องสั่งยกเลิกการใช้ดังนี้

วัตถุ.deinit()

การอ่านค่าตัวหารสัญญาณนาฬิกามีรูปแบบคำสั่งต่อไปนี้

ค่าตัวหารสัญญาณนาฬิกา = วัตถุ.clock_div()

กรณีที่ต้องการส่งสัญญาณพัลซ์ออกสามารถใช้คำสั่งต่อไปนี้ในการส่งสัญญาณ ซึ่งค่า duration เป็นค่าจำนวนเต็มในค่าหน่วย 100ns และ data คือค่าแรงดันเริ่มต้นของการส่ง โดยสามารถส่งออกได้ 3 ลักษณะ คือ

  • ส่งลิสต์หรือทูเพิลของ duration ในหน่วย 100ns ที่ส่งค่า 0 และ 1 เรียงกันไปตามระยะเวลาที่กำหนดระดับแรงดันเริ่มต้นแก่ data
  • ค่าของ duration เป็นตัวเลขจำนวนเต็ม และ data เป็นลิสต์หรือทูเพิลของแรงดัน
  • ทั้ง duration และ data เป็นลิสต์หรือทูเพิลที่มีจำนวนสมาชิกเท่ากันเพื่อระบุค่าระยะเวลาของข้อมูลแต่ละตัว

วัตถุ.write_pulses( duration, data=True )

ตัวอย่างการสั่งในแบบแรกเป็นดังนี้

write_pulses((1, 20, 2, 40), 0)

หมายถึง ส่งข้อมูล 0 เป็นเวลา 1x100ns, 0 เป็นเวลา 20x100ns, 0 เป็นเวลา 2x100ns และ 1 เป็นเวลา 40x100ns โดยกำหนดแรงดันเริ่มต้นเป็น Low หรือ 0

การตรวจสอบสถานะของการส่งพัลซ์ใช้คำสั่งต่อไปนี้ ถ้าผลลัพธ์เป็น True หมายถึง ช่องสัญญาณนั้นว่าง ถ้าเป็น False หมายถึงกำลังทำ write_pulses

สถานะ=วัตถุ.wait_done(timeout=0)

คำสั่งกำหนดให้ทำการวนรอบมีรูปแบบดังนี้ โดยค่า enable_loop กำหนดเป็น True หมายถึงให้มีการส่งข้อมูลตามที่เรียกด้วย write_pulse อีกรอบ และถ้าเป็น False หมายถึง เมื่อส่งพัลซ์ในรอบนี้เสร็จไม่ต้องส่งข้อมูลซ้ำ แต่อย่างไรก็ดีการวนรอบทำซ้ำนี้ทำได้ไม่เกิน 126 ครั้ง

วัตถุ.loop( enable_loop )

ULP

สำหรับการใช้ ULP (Ultra-Low-Power co-processor) ซึ่งเป็นไมโครคอนโทรลเลอร์ประหยัดพลังงานที่อยู่ภายในระบบของ ESP32 สามารถเข้าถึงและสั่งงานด้วยการส่งไบนารีชุดคำสั่งไปให้ และสั่งรันผ่านคลาส ULP ดังภาพที่ 9

ภาพที่ 9 คลาส esp32.ULP

คำสั่งที่ใช้ตั้งค่าการทำงานของ ULP ให้ทำทุกคาบเวลาที่กำหนดมีรูปแบบการใช้งานดังนี้

exp32.ULP.set_wakeup_period( period_index, ค่าคาบเวลาในหน่วยไมโครวินาที )

การโหลดชุดคำสั่งให้ ULP ทำงานเมื่อถึงเวลาที่ตั้งค่าไว้กระทำด้วยคำสั่งต่อไปนี้

esp32.ULP.load_binary( ตำแหน่งที่ต้องการโหลดไปเก็บไว้, โปรแกรมที่ต้องการโหลด )

การสั่งให้โปรแกรมที่โหลดไปเก็บไว้ทำงานมีรูปแบบคำสั่งดังนี้

esp32.ULP.run( ตำแหน่งเริ่มต้นทำงาน )

สรุป

จากเนื้อหาของบทความนี้จะพบว่า คลาส esp สามารถใช้งานได้กับไมโครคอนโทรลเลอร์ ESP8266 และ ESP32 ยกเว้นการสั่ง deep sleep ของ ESP32 ต้องเรียกผ่าน machine.deepsleep( ) และคลาส ESP32 ที่ใช้งานได้เฉพาะไมโครคอนโทรลเลอร์ ESP32 ซึ่งจะพบว่าชิพตัวนี้มีคุณสมบัติภายในทั้ง NVS/Partition/RMT และ ULP ให้ใช้งาน จึงนับได้ว่าคุณสมบัติต่อราคาของไมโครคอนโทรลเลอร์ตัวนี้น่าใช้งานมาก แต่ถ้าไม่ได้ใช้งานความสามารถเพิ่มเติมเหล่านี้ตัว ESP8266 มีความสามารถที่มากเพียงพอต่อการใช้งาน และมีราคาที่ถูกกว่ามาก สุดท้าย ขอให้สนุกกับการเขียนโปรแกรมครับ

ท่านใดต้องการพูดคุยสามารถคอมเมนท์ไว้ได้เลยครับ

แหล่งอ้างอิง

  1. Micropython, “Quick reference for ESP8266”
  2. Micropython, “Quick Reference for ESP32”

(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-07-15, 2021-07-16, 2021-07-17, 2021-10-22