ไวยากรณ์
Core syntax: fundamentals, control flow, GPIO, output, math and task/sub/struct/topic.
1. พื้นฐาน (Fundamentals)
หน่วยเวลาพิมพ์เป็นภาษาไทยได้: wait 50 มิลลิวินาที, wait 2 วินาที, wait 1.5 วินาที, wait 3 นาที, wait 1 ชั่วโมง (มิลลิวินาที / วินาที / นาที / ชั่วโมง)
2. โครงสร้างควบคุม (Control Flow)
3. GPIO และ Input/Output
ภาษาไทย: on=เปิด, off=ปิด, make=ทำ, set=ให้, get=รับ, from=จาก, high/low=สูง/ต่ำ
on/off/makeใช้กับตัวแปรขาเท่านั้น (ห้ามใช้กับอ็อบเจกต์ device เช่นon mvที่mvเป็น stepper — check จะฟ้องทันที; servo/buzzer/RGB มีความหมายเฉพาะของตัวเอง) ชื่อ property ภาษาอังกฤษไม่สนตัวพิมพ์เล็ก/ใหญ่ (VALUE=value)
4. เอาต์พุตข้อความ
5. คณิตศาสตร์ / สตริง / ฟังก์ชันในตัว
ฟังก์ชันแบบพาเรนซ์นี้ใช้ได้ทั้งในนิพจน์และเป็นคำสั่ง (ต้องมีวงเล็บ):
- เลข:
abs(x) round(x) int(x) float(x) str(x)pow(x,y) sqrt(x) ceil(x) floor(x)sin(x) cos(x) tan(x) log(x)min(a,b) max(a,b) map(v,min,max,nmin,nmax) constrain(v,a,b)random 1 10(คำสั่ง ไม่ต้องวงเล็บ) - สตริง:
len(s) upper(s) lower(s) trim(s) replace(s,from,to) char_at(s,i) substring(s,a,b)index_of(s,sub) starts_with(s,pre) ends_with(s,suf) split(s,sep) - แปลงฐาน:
hex(x) bin(x) oct(x)to_char(code) to_ascii(ch) - บิต:
bit_set(v,bit)bit_clear(v,bit)bit_read(v,bit)bit_write(v,bit,val)(ไทย: เปิดบิต/ปิดบิต/อ่านบิต/เขียนบิต) - เสียง:
tone(pin,freq)tone(pin,freq,dur)no_tone(pin)(ไทย: เล่นเสียง/หยุดเสียง) - เวลา:
millismicros(คำสั่ง/ค่า ไม่ใช้เครื่องหมายวงเล็บ —now = millis)
ภาษาไทย (mapoThaiMap): ค่าสัมบูรณ์=abs, ปัดทศนิยม=round, จำนวนเต็ม=int, ทศนิยม=float, ข้อความ=str_fn, เลขฐาน16=hex, เลขฐาน2=bin, ยกกำลัง=pow, รากที่สอง=sqrt, ปัดขึ้น=ceil, ปัดลง=floor, ความยาว=len, ตัวใหญ่=upper, ตัวเล็ก=lower, ตัดช่องว่าง=trim, แทนที่=replace, ตัวอักษรที่=char_at, ตัดข้อความ=substring, หาตำแหน่ง=index_of, ขึ้นต้นด้วย=starts_with, ลงท้ายด้วย=ends_with, แยก=split, ฐานแปด=oct, เป็นตัวอักษร=to_char, เป็นรหัส=to_ascii, เปิดบิต=bit_set, ปิดบิต=bit_clear, อ่านบิต=bit_read, เขียนบิต=bit_write, เล่นเสียง=tone, หยุดเสียง=no_tone, แมป=map, จำกัด=constrain, น้อยสุด=min, มากสุด=max
6. Task / Subroutine / Struct / Topic (ROS2-style Pub-Sub)
7. อุปกรณ์แสดงผล (Displays)
7.1 LCD I2C
ชนิด: lcd, lcd16 (16x2), lcd20 (20x4), แอลซีดี, แอลซีดี16, แอลซีดี20, จอข้อความ
C++ ที่ได้: #include <Wire.h> <LiquidCrystal_I2C.h>; LiquidCrystal_I2C screen1(0x27, cols, rows); + screen1_x/y; setup: screen1.init(); screen1.backlight();
7.2 OLED (SSD1306 / SH1106)
ชนิด: ssd, ssd32 (128x32), ssd8x8, ssdspi, sh, sh32, sh8x8, shspi + ภาษาไทย จอ, จอเล็ก, จอspi, เอสเอสดี*, เอสเอช*
SPI variant รับอาร์กิวเมนต์ (cs, dc, rst) ค่าเริ่มต้น 10, 9, 8
7.3 7-Segment
ชนิด: 7seg_ht (HT16K33, I2C), 7seg_tm (TM1650, I2C), 7seg_1637 (TM1637, 2-wire) + ไทย ตัวเลข_ht, ตัวเลข_tm, ตัวเลข_1637
7.4 RGB LED
ชนิด: rgb เท่านั้น (ไม่มีภาษาไทย)
C++: analogWrite ไปทั้ง 3 พิน
7.4b NeoPixel (หลอด addressable WS2812 / SK6812)
ชนิด: neopixel, นีโอพิกเซล
C++: ใช้ไลบรารี Adafruit_NeoPixel (server ติดตั้งให้อัตโนมัติ)
7.5 Stepper Motor
ชนิด: step, stepper, สเต็ป, มอเตอร์สเต็ป
step(p1,p2,p3,p4)→ 4 พิน (ULN2003/28BYJ-48) →Stepper obj(2048, p1, p3, p2, p4)stepper(stepPin, dirPin)→ 2 พิน (A4988/DRV8825)
7.6 Servo
ชนิด: servo, เซอร์โว (ไทย map ยังมี มอเตอร์)
8. เซนเซอร์ (Sensors)
8.1 DHT11
ชนิด: dht11, dth11, ดีเอชที11
C++: #include <DHT.h>; DHT d1(4, DHT11); setup: d1.begin();
8.2 HC-SR04 (เซนเซอร์วัดระยะอัลตราโซนิก)
ชนิด: hcsr04, hc_sr04, sr04, ultrasonic, sonic, sonar, อัลตราโซนิก, เซนเซอร์วัดระยะ, วัดระยะ
C++: สร้างคลาส HC_SR04 และ instance HC_SR04 u1(5, 18);; setup: u1.begin(); อ่านค่า u1.distance() (ใช้ pulseIn วัด echo, timeout 30 ms)
8.3 DS18B20 (เซนเซอร์อุณหภูมิดิจิทัล 1-Wire)
ชนิด: ds18b20, ds18, ds18x20, หนึ่งไวร์, ดิจิตอลอุณหภูมิ, วัดอุณหภูมิ
C++: auto เพิ่ม #include <OneWire.h> + #include <DallasTemperature.h>; สร้างคลาส DS18B20_Sensor และ instance DS18B20_Sensor s(26);; setup: s.begin(); อ่านค่า s.tempC() (requestTemperatures + getTempCByIndex(0)) หรือ s.tempF()
8.4 MPU6050 (เซนเซอร์ IMU 6 แกน — Accelerometer + Gyroscope)
ชนิด: mpu6050, mpu, imu, ไอเอ็มยู, เอ็มพียู, ไจโร, ไจโรสโคป, เซนเซอร์เอียง, วัดเอียง
C++: auto เพิ่ม #include <Wire.h> เท่านั้น (ไม่มีไลบรารีภายนอก ไม่ต้องติดตั้ง MPU6050_light.h); สร้างคลาส MPU6050_IMU + instance MPU6050_IMU imu(21, 22, true);; setup: imu.begin(); (ปลุก + ตั้งค่า reg + calibrate เกียโร 200 ตัวอย่าง); ทุกครั้งที่อ่าน prop จะ update() อ่าน reg 0x3B (accel) + 0x43 (gyro) แบบ 16-bit แล้วแปลงเป็น g / °/s / roll / pitch
8.4 BMP280 (เซนเซอร์อุณหภูมิ + ความดัน + ความสูง)
ชนิด: bmp280, bmp, บีเอ็มพี280, บีเอ็มพี, ความดัน, เซนเซอร์ความดัน, บารอมิเตอร์, วัดความดัน, วัดความสูง
C++: auto เพิ่ม #include <Wire.h> เท่านั้น (ไม่มีไลบรารีภายนอก); สร้างคลาส BMP280_Sensor + instance BMP280_Sensor bmp(21, 22);; setup: bmp.begin(); (หาแอดเดรสอัตโนมัติ + อ่านค่าคาลิเบรชัน + ตั้งค่าโหมด); ทุกครั้งที่อ่าน prop จะ _update() อ่าน raw data จาก reg 0xF7 แล้วแปลงเป็น °C / hPa / เมตร (สูตร datasheet)
8.4 LDR (เซนเซอร์แสง)
ชนิด: ldr, แอลดีอาร์
8.4 LM35 (เซนเซอร์อุณหภูมิ)
ชนิด: lm35, แอลเอ็ม35
C++ helper: mapo_readTempLM35(pin) = (raw * MAPO_VREF / MAPO_ADC_MAX) * 100.0
8.5 Potentiometer
ชนิด: potential, pot, potentiometer, โพเทนชิโอมิเตอร์
8.6 Soil Moisture
ชนิด: soil, moisture, ดิน, วัดความชื้น
8.7 Joystick
ชนิด: joystick, joy, จอยสติ๊ก, จอย
8.8 IR Receiver
ชนิด: irrecv, ir, ไออาร์
irrecv(pin)เรียกIrReceiver.begin(pin, ENABLE_LED_FEEDBACK)ในsetup()ให้อัตโนมัติcodeอ่านIrReceiver.decodedIRData.decodedRawDataและคืน0xFFFFFFFFเมื่อยังไม่มีสัญญาณ (ใช้if c != 4294967295เพื่อกรอง)- ใช้ไลบรารี
z3t0/IRremote(IRremote 4.x) - ทุกครั้งที่อ่าน (
c = ir1.codeหรือget c from ir1.code) ตัวแปลจะสร้างบล็อก inline:เหมือนโค้ด raw.mapo#cที่ใช้มือเขียนทุกประการ (c = ir1.bitsอ่านnumberOfBitsของเฟรมล่าสุด คืน 0 เมื่อยังไม่เคยรับสัญญาณ; อ่านir.codeตามด้วยir.bitsในลูปรอบเดียวกันได้ค่าจากเฟรมเดียวกัน)
8.9 Buzzer
ชนิด: buzzer, ออด, เสียง
8.10 PID Controller
ชนิด: pid, พีไอดี, ตัวควบคุม — ต้องมีวงเล็บเสมอ
C++: class MapoPID ในตัว (integral + derivative + clamping, default limits 0-255)
8.11 PIR (HC-SR501 — จับความเคลื่อนไหว)
ชนิด: pir, hc_sr501, hcsr501, ไพแอาร์, จับความเคลื่อนไหว, เซนเซอร์จับความเคลื่อนไหว
C++: ไม่ต้องใช้ไลบรารีภายนอก — setup เติม pinMode(pin, INPUT) ให้อัตโนมัติ แล้วอ่านด้วย digitalRead(pin)
(เป็นดิจิทัลอินพุตล้วน ๆ ใช้ขา digital ทั่วไป; บน ESP8266 เลี่ยงชื่อขา A1 ขึ้นไป)
โมดูล HC-SR501 จะคงขา OUT เป็น HIGH ตลอดช่วง retrigger (~2.5 วิ ค่าเริ่มต้น) จึงไม่ต้อง latch เพิ่มในโค้ด
one-liner: m = pir(27).motion
9. เครือข่าย (Network) — ESP32/ESP8266 เท่านั้น
9.1 WiFi (STA)
ชนิด: wifi, ไวไฟ
ลำดับใน setup อัตโนมัติ: WiFi.persistent(false) → mode → setHostname → setAutoReconnect(true) → begin (+ mDNS, auto-reconnect ทุก 30s)
9.2 Hotspot (AP)
ชนิด: hotspot, ap, ฮอตสปอต
9.3 NTP (เวลา)
ชนิด: ntp, เอ็นทีพี, นาฬิกา
9.4 MQTT
ชนิด: mqtt, เอ็มคิวทีที — ต้องมี wifi/hotspot ในโปรแกรม
C++: PubSubClient + reconnect อัตโนมัติ (clientID "Mapo-"+MAC)
9.5 HTTP Client
ชนิด: http, เอชทีทีพี — ต้องมี wifi/hotspot
ทำงานบน FreeRTOS task (ESP32) ไม่บล็อก loop
9.6 TCP Server / Client
ชนิด: tcp_server, ทีซีพีเซิร์ฟเวอร์; tcp_client, ทีซีพีไคลเอนต์
9.7 UDP
ชนิด: udp, ยูดีพี
9.8 WebSocket Server
ชนิด: websocket, ws, เว็บซ็อกเก็ต
Auth protocol: client ต้องส่ง AUTH:<pass> หลังเชื่อมต่อ
9.9 Web Server + Routes
ชนิด: webserver, เว็บเซิร์ฟเวอร์
Route อัตโนมัติ: /ping → 200 OK
9.10 JSON (ArduinoJson v7)
ชนิด: json, เจซอน
9.11 ESP32 Camera
ชนิด: camera, cam, espcam, esp32cam, กล้อง, กล้องเอสพี
Preset: default ai_thinker; camera(1)/camera("ESP_EYE") → esp_eye pin map
9.12 Cloud Hub (WebSocket client)
ชนิด: cloud, hub, ศูนย์, เซิร์ฟเวอร์
ใช้ร่วมกับ topic/bridge/pub/recv เหมือน websocket
9.13 Storage (หน่วยความจำถาวร)
ESP32: Preferences namespace "mapo_cfg"; ESP8266/UNO: EEPROM
9.14 TCP Relay (ประตูหน้า / gateway หลายไคลเอนต์)
ชนิด: tcp_relay, รีเลย์ทีซีพี — ESP32 family เท่านั้น
รับหลายไคลเอนต์พร้อมกัน แล้วส่งต่อ (splice) ทุกไบต์ไปยังปลายทางเดียว (protocol-blind — ใช้กับ MQTT หรือ TCP ใดก็ได้)
- Auto-start เมื่อ WiFi พร้อม; host รับทั้ง IP และ domain name (resolve ครั้งเดียว)
- พอร์ตฟัง / พอร์ตปลายทาง / จำนวน slot ต้องเป็นค่าคงที่ (literal)
- 1 slot = 2 sockets — Arduino core ตั้ง
CONFIG_LWIP_MAX_SOCKETS=10ไว้ จึงเกิน 4 slots ไม่ได้ถ้าไม่เพิ่มผ่าน#sdkconfig(ถ้า slots > 4 ระบบจะเติม LWIP config ให้อัตโนมัติ) - ต้องมี
wifiหรือhotspotในโปรแกรม
9.15 Traffic Counter (นับแพ็กเก็ตระดับ lwIP)
ชนิด: traffic_counter, ตัวนับทราฟฟิก — ESP32 family เท่านั้น
นับ B_t / P_t / S_t ที่ชั้น netif — เห็น SYN รวม half-open ที่ชั้น socket มองไม่เห็น (ใช้จับ SYN flood)
ค่าที่อ่านได้คือ delta ตั้งแต่ set cnt.sample ครั้งก่อน — ถ้า sample ทุก 1 วินาที จะได้ B_t = bytes/s, P_t = pkts/s, S_t = syn/s ตรงตามหน้าต่างวัดของงานวิจัย IDS
9.16 #sdkconfig (ตั้งค่า ESP-IDF build config)
ใช้ได้เฉพาะ ESP32 family — ตั้งค่า sdkconfig ของ lwIP/ESP-IDF จากในโค้ด (build config ไม่ใช่โค้ด C)
- บรรทัดต้องเป็น
CONFIG_NAME=value; comment ขึ้นต้น#หรือ;ได้ - ระบบจะสลับไป platform pioarduino (HybridCompile) ให้อัตโนมัติ เพราะ platform ทางการใช้ lwIP แบบ precompiled แก้ค่าไม่ได้ — build แรกจะช้ากว่าปกติ (rebuild จาก source)
- ค่าที่ใช้บ่อย:
CONFIG_LWIP_MAX_SOCKETS,CONFIG_LWIP_MAX_ACTIVE_TCP,CONFIG_LWIP_MAX_LISTENING_TCP,CONFIG_LWIP_TCP_SND_BUF_DEFAULT,CONFIG_LWIP_TCP_WND_DEFAULT,CONFIG_SPIRAM=y+CONFIG_SPIRAM_USE_MALLOC=y(ใช้ PSRAM)
10. Raw C escape (`#c`/`#endc`)
ใช้ #c/#endc เมื่อต้องการเขียนโค้ด Arduino/C โดยตรง ซึ่งจะถูกส่งเข้าไปใน sketch ที่ generate ได้เลย
- โค้ดใน
#c/#endcมองเห็นตัวแปร MAPO ที่ declare ไว้แล้ว (เช่นraw_val,led1) - ใช้
#includeใน#cได้ — เซิร์ฟเวอร์จะ auto-resolve ไลบรารีให้อัตโนมัติ - ใช้ใน task หรือนอก task ก็ได้
11. ตัวอย่างภาษาไทย (Thai Example)
12. สรุปชนิดอุปกรณ์ (ชนิดภาษาอังกฤษ / ภาษาไทย)
| หมวด | ชนิด |
|---|---|
| แสดงผล | lcd/lcd16/lcd20/แอลซีดี*/จอข้อความ, ssd/ssd32/ssd8x8/ssdspi/sh*/จอ*/เอสเอสดี*/เอสเอช*, 7seg_ht/7seg_tm/7seg_1637/ตัวเลข_*, rgb, step/stepper/สเต็ป, servo/เซอร์โว |
| เซนเซอร์ | dht11/dth11/ดีเอชที11, ldr/แอลดีอาร์, lm35/แอลเอ็ม35, potential/pot, soil/moisture/ดิน/วัดความชื้น, hcsr04/hc_sr04/ultrasonic/sonic/อัลตราโซนิก/เซนเซอร์วัดระยะ, ds18b20/ds18/ds18x20/หนึ่งไวร์/ดิจิตอลอุณหภูมิ/วัดอุณหภูมิ, mpu6050/mpu/imu/ไอเอ็มยู/เอ็มพียู/ไจโร/ไจโรสโคป/เซนเซอร์เอียง/วัดเอียง, bmp280/bmp/บีเอ็มพี280/ความดัน/เซนเซอร์ความดัน/บารอมิเตอร์/วัดความดัน/วัดความสูง, joystick/joy/จอยสติ๊ก/จอย, irrecv/ir/ไออาร์, pir/hc_sr501/hcsr501/ไพแอาร์/จับความเคลื่อนไหว/เซนเซอร์จับความเคลื่อนไหว, buzzer/ออด/เสียง, pid/พีไอดี/ตัวควบคุม |
| เครือข่าย | wifi/ไวไฟ, hotspot/ap/ฮอตสปอต, ntp/เอ็นทีพี/นาฬิกา, mqtt/เอ็มคิวทีที, http/เอชทีทีพี, tcp_server/ทีซีพีเซิร์ฟเวอร์, tcp_client/ทีซีพีไคลเอนต์, tcp_relay/รีเลย์ทีซีพี, traffic_counter/ตัวนับทราฟฟิก, udp/ยูดีพี, websocket/ws/เว็บซ็อกเก็ต, webserver/เว็บ/เว็บเซิร์ฟเวอร์, json/เจซอน, camera/cam/espcam/esp32cam/กล้อง/กล้องเอสพี, cloud/hub/ศูนย์/เซิร์ฟเวอร์, #sdkconfig (block) |
13. หมายเหตุการคอมไพล์ (Board Support)
- WiFi/network ทั้งหมด + camera + cloud: ESP32 / ESP8266 เท่านั้น (โยน
#errorถ้าไม่ใช่) - Camera: ต้องการ ESP32 พร้อม PSRAM (AI-Thinker pin map เป็นค่าเริ่มต้น)
- ตัวแปร global ใช้ร่วมกันทุก task; ตัวแปรใน task ที่ declare ใน loop/for จะเป็น
staticต่อ task - Task/Organ/Brain คอมไพล์เป็น state machine (
<name>_state) เรียกแบบ non-blocking ทุกรอบของloop()— คำสั่งwait/await/obj.stepใน task จะ yield และกลับมาทำต่อ (ไม่บล็อก task อื่น)