ตารางคำสั่งเฉพาะ

Note

หน้านี้ใช้กับกล่องเสียงที่เป็นค่าตั้งต้นจากโรงงาน ซึ่งพูดภาษาเฉพาะของผู้ผลิต ไม่ใช่ Modbus

ตัวที่ทางร้านจำหน่ายเป็น Modbus ดูหน้านั้นแทน หน้านี้มีไว้เผื่อเครื่องที่ได้มาจากที่อื่น หรือตอนที่หน้า Modbus ยิงแล้วเงียบ

ตั้งค่าพอร์ต

ค่า

ความเร็ว

9600

ข้อมูล · หยุด · พาริตี้

8 · 1 · ไม่มี

ใช้ได้กับ

RS232 และ RS485

โครงเฟรม

ยาว 7 ไบต์เสมอ ทั้งขาส่งและขาตอบ

  0     1      2        3       4      5     6
┌────┬──────┬────────┬───────┬───────┬─────┬────┐
│ 01 │  51  │โฟลเดอร์│  00   │ความดัง│ XOR │ 02 │
└────┴──────┴────────┴───────┴───────┴─────┴────┘
  │     │        │        │       │      │     │
  │     │        │        │       │      │     └── ไบต์ปิดท้าย ตายตัว
  │     │        │        │       │      └──────── XOR ของไบต์ 0 ถึง 4
  │     │        │        │       └─────────────── 00 ถึง 1C คือ 0-28
  │     │        │        └─────────────────────── ไม่ได้ใช้ ใส่ 00
  │     │        └──────────────────────────────── 00 ถึง FF คือ 0-255
  │     └───────────────────────────────────────── 51 สั่ง · 52 คำตอบ
  └─────────────────────────────────────────────── ไบต์เริ่ม ตายตัว

Important

ส่งโฟลเดอร์กับความดังไปพร้อมกันในเฟรมเดียวจบ

ต่างจาก Modbus ที่ต้องส่งสองเฟรม แบบนี้สั้นกว่าและเร็วกว่า

Warning

🔴 ไม่มีคำสั่งอ่านค่ากลับ

โปรโตคอลนี้สั่งได้อย่างเดียว อ่านไม่ได้ จะรู้ว่าลำโพงตั้งไว้เท่าไร ต้องจำเองในโปรแกรม

ถ้าโปรแกรมรีสตาร์ท จะไม่มีทางรู้ว่าลำโพงกำลังเล่นอะไรอยู่ — ให้สั่งหยุดทันทีที่เริ่มโปรแกรม เพื่อกลับสู่สถานะที่รู้แน่นอน

XOR

เอาไบต์ที่ 0 ถึง 4 มา XOR กันทั้งหมด ได้ไบต์เดียว

def xor8(data):
    v = 0
    for b in data:
        v ^= b
    return v

def frame(folder, volume):
    body = [0x01, 0x51, folder & 0xFF, 0x00, volume & 0xFF]
    return bytes(body + [xor8(body), 0x02])

Tip

XOR ตรวจได้อ่อนกว่า CRC16 มาก — สลับตำแหน่งสองไบต์แล้ว XOR ยังเท่าเดิม จับไม่ได้

บนสายที่ยาวหรือมีสัญญาณรบกวน Modbus จึงน่าเชื่อถือกว่า ถ้าเลือกได้ให้สั่งซื้อแบบ Modbus

ตัวอย่างเฟรม

ทุกเฟรมข้างล่างนี้คำนวณด้วยโปรแกรม ไม่ได้พิมพ์มือ สองอันแรกตรงกับตัวอย่างในคู่มือทุกไบต์

ทำอะไร

ส่ง

ลำโพงตอบ

เล่น AW002 ดัง 28

01 51 02 00 1C 4E 02

01 52 02 00 1C 4D 02

เล่น AW005 ดัง 28

01 51 05 00 1C 49 02

01 52 05 00 1C 4A 02

หยุด

01 51 00 00 1C 4C 02

01 52 00 00 1C 4F 02

🔴 กับดักเสียงสะท้อน

Danger

คำสั่งกับคำตอบต่างกันแค่ไบต์เดียว51 กับ 52

สาย RS485 บางเส้นสะท้อนสิ่งที่เราส่งกลับมาเอง ถ้าโค้ดเช็กแค่ว่า "มีอะไรกลับมาไหม" จะนึกว่าลำโพงตอบแล้ว ทั้งที่ลำโพงอาจไม่ได้ต่ออยู่ด้วยซ้ำ

ต้องเช็กว่าไบต์ที่สองเป็น 52 ถ้าได้ 51 แปลว่าเป็นเสียงสะท้อน ไม่ใช่คำตอบ

def is_real_reply(frame, sent_folder):
    if len(frame) != 7:
        return False
    if frame[1] != 0x52:          # 51 คือคำสั่งเราเอง สะท้อนกลับมา
        return False
    if frame[2] != sent_folder:   # ต้องเป็นโฟลเดอร์ที่เราสั่งไป
        return False
    return frame[5] == xor8(frame[:5])

ตรวจโค้ดก่อนต่อของจริง

พิมพ์เฟรมที่โปรแกรมสร้างออกมาเทียบกับตารางข้างบนก่อนเสียบของจริง

Warning

เลือกภาษาผิดจะเงียบสนิท ไม่มีข้อความผิดพลาด

ถ้ายิงเฟรมจากหน้านี้แล้วไม่มีอะไรตอบ ให้ลองแบบ Modbusดู ก่อนจะไปไล่หาปัญหาที่สายไฟ