ZX-BLE มินิบอร์ดสื่อสารข้อมูลอนุกรมไร้สายผ่านบลูทูธกำลังงานต่ำ
คุณสมบัติของ ZX-BLE
- ใช้ไมโครคอนโทรลเลอร์ ESP32-C3 ให้ทำงานในโหมดบลูทูธพลังงานต่ำหรือ BLE (Bluetooth Low Energy)
- ติดต่อกับบอร์ดไมโครคอนโทรลเลอร์ได้ทุกรุ่นที่มีพอร์ตสื่อสารข้อมูลอนุกรม UART
- อัตราบอด 115,200 บิตต่อวินาที ในรูปแบบข้อมูล 8N1 (8 บิตข้อมูล, ไม่มีการตรวจสอบบิตพาริตี้ และ 1 บิตหยุด)
- ใช้ไฟเลี้ยง 3.3V ต้องการกระแสไฟฟ้า 20mA ขณะรับส่งข้อมูล
- มีจุดต่อ RxDและ TxDเป็นคอนเน็กเตอร์ JST ตัวผู้ 2.0 มิลลิเมตร 3 ขา
- มี LED แสดงสถานะไฟเลี้ยงและการสื่อสารข้อมูล
- มีจุดต่อพอร์ต USB-C สำหรับติดต่อกับคอมพิวเตอร์เพื่อตั้งค่าอัตราบอดและชื่ออุปกรณ์สำหรับการจับคู่อุปกรณ์ BLE
รูปที่ 1 แสดงส่วนประกอบของมินิบอร์ด
แนะนำแอปพลิเคชั่น V7RC
V7RC เป็นแอปพลิเคชั่นสำหรับการควบคุมอุปกรณ์ระบบสมองกลฝังตัวผ่านคลื่นวิทยุด้วยบลูทูธพลังงานต่ำหรือ BLE บนสมาร์ตโฟน ที่พัฒนาโดย V7 Media จากไต้หวัน โดยใช้งานเป็นได้ทั้งรีโมตคอนโทรลแบบไร้สาย ส่วนแสดงผลภาพนิ่งและวิดีโอระยะไกล และยังรองรับการพัฒนาระบบควบคุมด้วยเทคโนโลยีปัญญาประดิษฐ์ผ่านฮาร์ดแวร์ของสมาร์ตโฟนสมัยใหม่ ช่วยให้ผู้เรียนและผู้ใช้งานสามารถเรียนรู้ เขียนโค้ด และทดลองใช้งานเทคโนโลยี AI ได้ทุกที่ ทุกเวลา ด้วยฟังก์ชันที่ครบถ้วนและใช้งานง่าย มีหน้าต่างหลักแสดงดังรูปที่ 2
รูปที่ 2 หน้าต่างหลักของแอปพลิเคชั่น V7RC
รูปแบบข้อมูลปุ่มกดของแอปพลิเคชั่น V7RC
ชุดข้อมูลหรือแพ็กเก็ตข้อมูลของ BLE มีขนาด 20 ไบต์ ในแอปพลิเคชั่น V7RC กำหนดรูปแบบของชุดข้อมูลดังนี้
รูปที่ 3 รูปแบบของชุดข้อมูล
- 3 ไบต์แรกเก็บข้อมูลโหลดการทำงาน มีด้วยกัน 3 รหัสคือ
- SRV สำหรับโหมด CAR ควบคุมมอเตอร์ขับเคลื่อน 2 ตัว
- SRT สำหรับโหมด TANK ควบคุมมอเตอร์ขับเคลื่อน 4 ตัว
- SS8 สำหรับโหมด PRO ควบคุมมอเตอร์ขับเคลื่อน 2 ตัว, เซอร์โวมอเตอร์หลัก 2 ตัว, มอเตอร์ไฟตรงเสริม (AUX) 2 ตัว และเซอร์โวมอเตอร์เสริม 2 ตัว รวมสูงสุด 8 ตัว
- 16 ไบต์ต่อมาสำหรับคำสั่ง SRV และ SRT เป็นข้อมูลสำหรับนำไปใช้สร้างสัญญาณ PWM ให้กับวงจรขับมอเตอร์บนไมโครคอนโทรลเลอร์
- ไบต์ที่ 4 ถึง 7 ข้อมูลสำหรับสร้างสัญญาณ PWM ให้กับวงจรขับมอเตอร์ช่องที่ 1
- ไบต์ที่ 8 ถึง 11 ข้อมูลสำหรับสร้างสัญญาณ PWM ให้กับวงจรขับมอเตอร์ช่องที่ 2
- ไบต์ที่ 12 ถึง 15 ข้อมูลสำหรับสร้างสัญญาณ PWM ให้กับวงจรขับมอเตอร์ช่องที่ 3
- ไบต์ที่ 16 ถึง 19 ข้อมูลสำหรับสร้างสัญญาณ PWM ให้กับวงจรขับมอเตอร์ช่องที่ 3
- สำหรับ 16 ไบต์ต่อมาสำหรับคำสั่ง SS8 ข้อมูลที่ใช้ในการกำหนดค่าสัญญาณ PWM จะเป็นเลขฐานสิบหก 8 ชุด ชุดละ 2 ไบต์
- ไบต์สุดท้ายเป็นรหัสปิด ซึ่งใช้อักขระ #
รูปที่ 4 ตัวอย่างรูปแบบชุดข้อมูลและหน้าต่างของแอป V7RC ในแต่ละโหมด
การตั้งค่าและชื่ออุปกรณ์บลูทูธให้กับมินิบอร์ด ZX-BLE
- สิ่งที่ต้องเตรียม
- มินิบอร์ด ZX-BLE
- สาย USB-C สำหรับเชื่อมต่อกับคอมพิวเตอร์
- คอมพิวเตอร์ที่ติดตั้งระบบปฏิบัติการวินโดวส์ และติดตั้งโปรแกรม ZX-BLE Config ( ดาวน์โหลดได้ที่ https://inex.co.th/store/ZXBLE_Config.zip )
- ขั้นตอนการตั้งชื่ออุปกรณ์บลูทูธให้กับมินิบอร์ด ZX-BLE
- ดาวน์โหลดโปรแกรมจาก https://inex.co.th/store/ZXBLE_Config.zip
- แตกไฟล์ .zip แล้วดับเบิ้ลคลิกไฟล์ ZX-BLE_Config.exe
- หน้าต่างของโปรแกรม ZX-BLE Config ปรากฏขึ้นมาดังรูปที่ ทำการกำหนดชื่อที่ต้องการตั้งให้กับมินิบอร์ด ZX-BLE ที่ช่อง BLE Name โดยกำหนดชื่อเป็นภาษาอังกฤษได้ยาวถึง 15 ตัวอักษร ในทีนี้ตั้งชื่อเปฌน ZX-BLE ID-001
รูปที่ 5 แสดงส่วนประกอบของโปรแกรม ZX-BLE Config
-
- เชื่อมต่อมินิบอร์ด ZX-BLE เข้ากับพอร์ต USB ของคอมพิวเตอร์โดยใช้สาย USB-C ดังรูปที่ 6
- รอครู่หนึ่ง เพื่อให้การเชื่อมต่ออุปกรณ์ USB สำเร็จ
รูปที่ 6 แสดงการเชื่อมต่อมินิบอร์ด ZX-BLE กับคอมพิวเตอร์
-
- ตรวจสอบตำแหน่งพอร์ต COM PORT ของมินิบอร์ด ZX-BLE โดยคลิกเมาส์ปุ่มขวาที่เครื่องหมาย Windows แล้วเลือก Device Manager ดังรูปที่ 7
- ที่หน้าต่าง Device Manager คลิกเลือกหัวข้อ Port (COM & LPT) จะเห็นรายการ USB Serial Device (COM xx) จำหมายเลข COM ไปใช้ในการตั้งค่าที่โปรแกรม ZX-BLE Config จากตัวอย่างคือ COM18
-
- กลับมายังโปรแกรม ZX-BLE Config เลือกพอร์ตเชื่อมต่อเป็น COM18 ดังรูป
- กดปุ่ม Read ที่หน้าต่างของโปรแกรมจะแสดงหมายเลข COM Port ที่เชื่อมต่ออยู่ ดังรูป แสดงข้อความ ZX-BLE name read ครู่หนึ่ง หมายความว่าโปรแกรมสามารถอ่านชื่ออุปกรณ์ของ ZX-BLE สำเร็จ
-
- ทดลองเปลี่ยนเป็นชื่ออื่นๆ จากนั้นกดปุ่ม Write เพื่อบันทึกชื่อใหม่ให้กับมินิบอร์ด ZX-BLE
- เมื่อตั้งค่าสำเร็จจะแจ้งด้วยข้อความ Write completed
- ทำการทดสอบให้มั่นใจ ว่ามินิบอร์ด ZX-BLE ได้ถูกทำการเปลี่ยนชื่อโดยการกดปุ่ม Read อีกครั้ง ชื่อของอุปกรณ์จะกลับมาแสดงที่ช่อง BLE Name
- ชื่อที่ปรากฏยังคงเป็น ZX-BLE 108 แสดงว่าการเปลี่ยนชื่อเสร็จสมบูรณ์
- นำมินิบอร์ด ZX-BLE ไปเชื่อมต่อกับบอร์ด ไมโครคอนโทรลเลอร์ที่ต้องการใช้งาน ในที่นี้คือบอร์ด POP32i
- เมื่อทำการค้นหามินิบอร์ด ZX-BLE ในแอป V7RC จะพบชื่อของอุปกรณ์บลูทูธตามที่ตั้งชื่อไว้ ทำการจับคู่ เพื่อเริ่มต้นการใช้งาน
วิธีการใช้งาน ZX-BLE ร่วมกับ POP-BOT32i : Rover Kit Plus
1. เตรียมอุปกรณ์
-
- ชุด POP-BOT32i : Rover Kit Plus และ ZX-BLE
- สาย USB สำหรับเชื่อมต่อบอร์ดกับคอมพิวเตอร์
- ซอร์ฟแวร์ Arduino IDE สำหรับเขียนและอัพโหลดโค้ด
- แอปพลิเคชั่น V7RC ( คลิกเพื่อติดตั้ง Android / IOS )
- ไลบรารี่ที่เกี่ยวข้อง
- POP32.h สำหรับสั่งงานบอร์ด POP32i (สามารถติดตั้งได้ที่ https://inex.co.th/store/manual/POP32i-Sheet230316-re.pdf )
2. เชื่อมต่อ ZX-BLE กับแอปพลิเคชั่น V7RC
-
- เชื่อมต่อมินิบอร์ด ZX-BLE กับบอร์ด POP-32i ที่ใช้ในชุดหุ่นยนต์ POP-BOT32i Rover Kit Plus โดยต่อขา RxD ของ ZX-BLE เข้าที่จุดต่อ TxD และต่อขา TxD ของ ZX-BLE เข้าที่จุดต่อ RxD ดังรูปที่ 2.1
รูปที่ 2.1 เชื่อมต่อ ZX-BLE กับบอร์ด POP-32i
-
- เปิดแอปพลิเคชั่น V7RC แล้วแตะที่ไอคอนฟันเฟืองเพื่อเข้าสู่หน้าต่าง CONTROL CENTER
- ที่หน้าต่าง CONTROL CENTER สังเกตที่กรอบข้อความหลังคำว่า LANGUAGE ให้เลือกภาษา ENGLISH ดังรูปที่ 2.2
รูปที่ 2.2 ตั้งค่าภาษาของแอปพลิเคชชั่น V7RC
-
- จากนั้นที่หน้าต่าง CONTROL CENTER ตรวจสอบที่ช่อง NETWORK จะแสดงตัวเลือก BLE และ WIFI ให้เลือก BLE
- และสังเกตในช่อง DEVICE ให้แตะเข้าไปที่ช่อง No device ดังรูปที่ 2.3
รูปที่ 2.3 เชื่อมต่อ Device ของ ZX-BLE
-
- จากนั้นจะแสดงหน้าต่าง BLUETOOTH โดยจะแสดงรายละเอียดของอุปกรณ์ สังเกตชื่อของอุปกรณ์ที่ตรงกับที่ตั้งค่าไว้ ในที่นี้คือ ZX-BLE ID-001 จากนั้นกดปุ่ม LINK เพื่อเริ่มการเชื่อมต่อ ระบบจะแสดงสถานะกำลังเชื่อมต่อด้วยการแสดงไอคอนรูปเฟือง จากนั้น ไอคอนจะหายไปหากการเชื่อมต่อไม่สำเร็จ ให้กดปุ่ม LINK ซ้ำจนกว่าการเชื่อมต่อจะสำเร็จ
- เมื่อเชื่อมต่อได้สำเร็จ ให้กดปุ่มย้อนกลับ 2 ครั้ง เพื่อกลับไปยัังหน้าต่าง CONTROL CENTER
- ที่หน้าต่าง CONTROL CENTER จะแสดงสถานะการเชื่อมต่อสำเร็จ โดยดูที่ช่อง Device จะปรากฎชื่อของอุปกรณ์ ZX-BLE ที่เชื่อมต่อได้ ดังรูปที่ 2.4 แล้วกดปุ่มย้อนกลับอีกครั้ง
- หน้าต่างหลักของแอป V7RC ปรากฎขึ้น ที่ช่อง Device name จะแสดงชื่ออุปกรณ์ตรงกันกับที่แสดงในเมนู Device ในหน้าต่าง CONTROL CRETER ถ้าได้ตามนี้ แอป V7RC จะเชื่อมต่อกับ ZX-BLE เรียบร้อยพร้อมใช้และทำงานร่วมกัน ดังรูปที่ 2.4
รูปที่ 2.4 หน้าต่างหลักของแอป V7RC ที่แสดงชื่ออุปกรณ์ที่เชื่อมต่อสำเร็จ
3. เชื่อมต่อมอเตอร์และเซอร์โวเข้ากับบอร์ด POP-32i
-
- เชื่อมต่อมอเตอร์ฝั่งซ้าย เข้าที่ช่อง Motor 1 และเชื่อมต่อมอเตอร์ฝั่งขวา เข้าที่ช่อง Motor 2 ดังรูปที่ 3.1
- เชื่อมต่อเซอร์โวส่วนสำหรับยกและวางของ Gripper-X เข้าที่ช่อง Servo 1 และเชื่อมต่อเซอร์โวส่วนแขนจับของ Gripper-X เข้าที่ช่อง Servo 2 ดังรูป 3.1
รูปที่ 3.1 เชื่อมต่อมอเตอร์และเซอร์โวเข้ากับบอร์ด POP-32i
ตัวอย่างโปรแกรมสำหรับบอร์ด POP-32i เพื่อทำงานร่วมกับ ZX-BLE ในการติดต่อกับแอปพลิเคชั่น V7RC
// // Mode CAR 2 motors : M2 = Left , M1 = Right // Mode TANK 4 motors : M3 M4 = Left , M2 M1 = Right // Mode PRO Drive 2 motors : M2 = Left , M1 = Right , Main 2 servos : S1 S2 = P2 P3, // Aux. 2 motors M3 M4 = P4 P5 control , Aux. 2 servos S3 S4 = P6 P7 // #include <POP32.h> //#define DEBUG // Remove // remark when Debuggung V7RC Command bytes #define SERVO_DEFAULT_VALUE 1500 #define SERVO_DEFAULT_MAX_VALUE 2000 #define SERVO_DEFAULT_MIN_VALUE 1000 #define PACKET_LENGTH 20 #define SERIAL_BAUDRATE 115200 #define DEFAULT_PERIOD_TIME 30 #define LOST_SIGNAL_MAX_TIME 500 // Maximum signal loss time; #define DEFAULT_LOOP_TIMES 33 //const int failSaveLED = 8; // Fail status shown (not used) long startProcessTime = 0; long endProcessTime = 0; int currentLostSignalTime = 0; char readBuffer[PACKET_LENGTH]; int bufferIndex = 0; long loopStart, loopEnd; static boolean ledStatus = LOW; static int loopProcessCheck = 0; static int failSafeCheckTime = 0; // Check if the information has been received static bool ifLostSignal = true; int leftWheel = 0; int rightWheel = 0; #define SERIAL2_RX PB7 #define SERIAL2_TX PB6 HardwareSerial Serial2(SERIAL2_RX, SERIAL2_TX); void setup() { Serial.begin(SERIAL_BAUDRATE); Serial2.begin(SERIAL_BAUDRATE); delay(100); Serial2.println("AT+RESET"); delay(1000); oled.text(0, 0, "V7RC ZX-BLE"); oled.show(); String str; if (Serial2.available() > 0) { Serial2.readStringUntil('N'); Serial2.readStringUntil('A'); Serial2.readStringUntil('M'); Serial2.readStringUntil('E'); Serial2.readStringUntil('='); str = Serial2.readStringUntil('#'); const char* cc = str.c_str(); oled.text(2, 0, "Name:"); oled.text(2, 5, cc); oled.show(); Serial.print(cc); } } void loop() { loopStart = millis(); if (loopProcessCheck > DEFAULT_LOOP_TIMES) { // Serial.println("init loopProcessCheck:" + String(loopProcessCheck)); // Serial.println("loopProcessCheck:" + String(loopProcessCheck)); if (ledStatus == LOW) { ledStatus = HIGH; } else { ledStatus = LOW; } if (ledStatus) { pinMode(PC13, OUTPUT); digitalWrite(PC13, LOW); } else { pinMode(PC13, INPUT_PULLUP); } // digitalWrite(led, ledStatus); loopProcessCheck = 0; } int bufferLength = Serial2.available(); while (bufferLength > 0) { char tempBuffer[bufferLength]; Serial2.readBytes(tempBuffer, bufferLength); // Serial.print("getValue:"); // Serial.println(bufferLength); for (int i = 0; i < bufferLength; i++) { readBuffer[bufferIndex] = tempBuffer[i]; bufferIndex++; //Data length = 20 if (bufferIndex >= PACKET_LENGTH) { //convert char[] to String if (readBuffer[19] == '#') { String command = String(readBuffer); //Command Process V7RCCommand(command); #ifdef DEBUG // DEBUG command bytes Serial.print(command); Serial.print(" "); #endif ifLostSignal = false; failSafeCheckTime = 0; //digitalWrite(failSaveLED, HIGH); } else { #ifdef DEBUG Serial.print("invaild Value :"); Serial.println(readBuffer[19]); #endif } bufferIndex = 0; } if (i == bufferLength - 1) { bufferIndex = 0; } } bufferLength = Serial2.available(); } loopEnd = millis(); //if delay time less then 30 microsecond int needDelay = loopEnd - loopStart; needDelay = DEFAULT_PERIOD_TIME - needDelay; failSafeCheckTime += DEFAULT_PERIOD_TIME; // Serial.print("failSafeCheckTime:"); // Serial.println(failSafeCheckTime); if (failSafeCheckTime > LOST_SIGNAL_MAX_TIME) { processFailSave(); failSafeCheckTime = LOST_SIGNAL_MAX_TIME; ifLostSignal = true; } else { } if (needDelay > 0) { delay(needDelay); } loopProcessCheck += 1; } void V7RCCommand(String bufferString) { // Serial.println(bufferString); String P0str; String P1str; String P2str; String P3str; String P4str; String P5str; String P6str; String P7str; int P0Value = 1500; int P1Value = 1500; int P2Value = 1500; int P3Value = 1500; int P4Value = 1500; int P5Value = 1500; int P6Value = 1500; int P7Value = 1500; int Value0, Value1, Value2, Value3, Value4, Value5, Value6, Value7; if (bufferString.substring(0, 3) == "SRV") // CAR, Game pad , Game pad 2 Mode { P0Value = (bufferString.substring(3, 7)).toInt(); P1Value = (bufferString.substring(7, 11)).toInt(); P2Value = (bufferString.substring(11, 15)).toInt(); P3Value = (bufferString.substring(15, 19)).toInt(); Value0 = map(P0Value, 1000, 2000, -100, 100); Value1 = map(P1Value, 1000, 2000, -100, 100); if (Value1 == 0) // spin { leftWheel = Value1 - Value0; leftWheel = constrain(leftWheel, -50, 50); rightWheel = Value1 + Value0; rightWheel = constrain(rightWheel, -50, 50); } else if (Value1 > 0) // forward { leftWheel = Value1 - Value0; leftWheel = constrain(leftWheel, 0, 100); rightWheel = Value1 + Value0; rightWheel = constrain(rightWheel, 0, 100); } else // Backward { leftWheel = Value1 + Value0; leftWheel = constrain(leftWheel, -100, 0); rightWheel = Value1 - Value0; rightWheel = constrain(rightWheel, -100, 0); } POP32_ModeCAR(leftWheel, rightWheel); } else if (bufferString.substring(0, 3) == "SRT") { // TANK Mode int Tank0 = 1500; int Tank1 = 1500; P0Value = (bufferString.substring(3, 7)).toInt(); P1Value = (bufferString.substring(7, 11)).toInt(); P2Value = (bufferString.substring(11, 15)).toInt(); P3Value = (bufferString.substring(15, 19)).toInt(); Value0 = map(P0Value, 1000, 2000, -100, 100); Value1 = map(P1Value, 1000, 2000, -100, 100); if (Value1 == 0) // spin { leftWheel = Value1 - Value0; leftWheel = constrain(leftWheel, -50, 50); rightWheel = Value1 + Value0; rightWheel = constrain(rightWheel, -50, 50); } else if (Value1 > 0) // forward { leftWheel = Value1 - Value0; leftWheel = constrain(leftWheel, 0, 100); rightWheel = Value1 + Value0; rightWheel = constrain(rightWheel, 0, 100); } else // Backward { leftWheel = Value1 + Value0; leftWheel = constrain(leftWheel, -100, 0); rightWheel = Value1 - Value0; rightWheel = constrain(rightWheel, -100, 0); } POP32_ModeTANK(leftWheel, leftWheel, rightWheel, rightWheel); } else if (bufferString.substring(0, 3) == "SS8") // PRO , BOT , BOT 2 Mode { P0str = bufferString.substring(3, 5); P0Value = strtol(P0str.c_str(), nullptr, 16); P1str = bufferString.substring(5, 7); P1Value = strtol(P1str.c_str(), nullptr, 16); P2str = bufferString.substring(7, 9); P2Value = strtol(P2str.c_str(), nullptr, 16); P3str = bufferString.substring(9, 11); P3Value = strtol(P3str.c_str(), nullptr, 16); P4str = bufferString.substring(11, 13); P4Value = strtol(P4str.c_str(), nullptr, 16); P5str = bufferString.substring(13, 15); P5Value = strtol(P5str.c_str(), nullptr, 16); P6str = bufferString.substring(15, 17); P6Value = strtol(P6str.c_str(), nullptr, 16); P7str = bufferString.substring(17, 19); P7Value = strtol(P7str.c_str(), nullptr, 16); #ifdef DEBUG Serial.print(P0Value, DEC); Serial.print(" "); Serial.print(P1Value, DEC); Serial.print(" "); Serial.print(P2Value, DEC); Serial.print(" "); Serial.print(P3Value, DEC); Serial.print(" "); Serial.print(P4Value, DEC); Serial.print(" "); Serial.print(P5Value, DEC); Serial.print(" "); Serial.print(P6Value, DEC); Serial.print(" "); Serial.print(P7Value, DEC); Serial.println(" "); #endif Value0 = map(P0Value, 100, 200, -100, 100); Value1 = map(P1Value, 100, 200, -100, 100); Value2 = map(P2Value, 100, 200, 0, 180); Value3 = map(P3Value, 100, 200, 0, 180); Value4 = map(P4Value, 100, 200, -100, 100); Value5 = map(P5Value, 100, 200, -100, 100); Value6 = map(P6Value, 100, 200, 0, 180); Value7 = map(P7Value, 100, 200, 0, 180); if (Value1 == 0) // spin { leftWheel = Value1 - Value0; leftWheel = constrain(leftWheel, -50, 50); rightWheel = Value1 + Value0; rightWheel = constrain(rightWheel, -50, 50); } else if (Value1 > 0) // forward { leftWheel = Value1 - Value0; leftWheel = constrain(leftWheel, 0, 100); rightWheel = Value1 + Value0; rightWheel = constrain(rightWheel, 0, 100); } else // Backward { leftWheel = Value1 + Value0; leftWheel = constrain(leftWheel, -100, 0); rightWheel = Value1 - Value0; rightWheel = constrain(rightWheel, -100, 0); } POP32_ModePRO(leftWheel, rightWheel, Value2, Value3, Value4, Value5, Value6, Value7); } else { // Serial.write("ERROR"); } } void POP32_ModeCAR(int Wheel1, int Wheel2) { motor(1, Wheel1); motor(2, Wheel2); } void POP32_ModeTANK(int Wheel1, int Wheel2, int Wheel3, int Wheel4) { motor(1, Wheel1); motor(2, Wheel2); motor(3, Wheel3); motor(4, Wheel4); } void POP32_ModePRO(int Wheel1, int Wheel2, int Arm1, int Arm2, int Wheel3, int Wheel4, int Arm3, int Arm4) { motor(1, Wheel1); motor(2, Wheel2); servo(1, Arm1); servo(2, Arm2); motor(3, Wheel3); motor(4, Wheel4); servo(3, Arm3); servo(4, Arm4); } // When no data is received, return to the preset value; void processFailSave() { // Stop all motors; AO(); }
อธิบายโปรแกรม
โปรแกรมนี้ถูกออกแบบมาเพื่อใช้กับบอร์ด POP32 สำหรับรับคำสั่งควบคุมจากแอปพลิเคชัน V7RC ผ่านบลูทูธ โดยเมื่อเริ่มทำงานจะแสดงชื่ออุปกรณ์ที่เชื่อมต่อผ่านหน้าจอ OLED และเข้าสู่ระบบการรอรับชุดข้อมูลขนาด 20 ตัวอักษรอย่างต่อเนื่อง
หัวใจหลักของโปรแกรมคือฟังก์ชัน V7RCCommand ที่ทำหน้าที่แยกแยะโหมดการทำงานตามที่ผู้ใช้เลือกในแอป หากเลือกโหมด CAR หรือ TANK โปรแกรมจะเน้นไปที่การคำนวณทิศทางเพื่อควบคุมมอเตอร์ขับเคลื่อนให้เดินหน้า ถอยหลัง หรือหมุนตัว แต่หากเลือกโหมด PRO โปรแกรมจะปลดล็อกการควบคุมที่ละเอียดขึ้น โดยสามารถสั่งการมอเตอร์ได้ 4 ตัว และเซอร์โวมอเตอร์ได้อีก 4 ตัวพร้อมกัน ซึ่งเหมาะสำหรับหุ่นยนต์ที่มีระบบแขนกลหรืออุปกรณ์เสริมหลายส่วน
นอกจากนี้ โปรแกรมยังมีระบบความปลอดภัยที่เรียกว่า Fail-Safe ซึ่งจะคอยตรวจสอบสัญญาณอยู่ตลอดเวลา หากสัญญาณขาดหายเกิน 0.5 วินาที โปรแกรมจะสั่งหยุดการทำงานของมอเตอร์ทั้งหมดทันที
ในการทดลองนี้จะเลือกใช้โหมด PRO เนื่องจากที่หน้าต่างควบคุมของโหมด PRO สามารถควบคุมมอเตอร์ได้ 4 ตัว และเซอร์โวมอเตอร์ได้อีก 4 ตัวเช่นกัน จึงเหมาะในการนำมาใช้งานเพื่อควบคุมการทำงานของชุด POP-BOT32i Rover Kit Plus













