- การสื่อสารข้อมูลที่ตรวจสอบความถูกต้องและแม่นยำด้วย CRC
- ความสำคัญของ CRC กับการสื่อสารข้อมูล
- หลักการทำงานของ CRC
- ตัวอย่างการใช้ Python และ pyserial ในการสื่อสารผ่าน RS-232 และ RS-485
- การประยุกต์ใช้ CRC ใน Python
- การทดสอบการสื่อสาร 100 ครั้ง
- การตั้งบัฟเฟอร์เพื่อการจัดการข้อมูล
- ตัวอย่างการคำนวณ CRC สำหรับ MODBUS
- การสื่อสารผ่านโปรโตคอล MQTT ด้วยการตรวจสอบ CRC
- การใช้งาน CRC ในโปรโตคอล MQTT
- ฝั่งผู้ส่ง (Broker)
- ฝั่งผู้รับ (Subscriber)
- การใช้งาน CRC ใน Arduino
- สรุป
การสื่อสารข้อมูลที่มุ่งเน้นการตรวจสอบความถูกต้องและแม่นยำมีความสำคัญอย่างยิ่งในระบบอิเล็กทรอนิกส์และไมโครคอนโทรลเลอร์ (MCU) โดยใช้เทคนิค CRC (Cyclic Redundancy Check) เพื่อป้องกันข้อผิดพลาดที่อาจเกิดขึ้นระหว่างการสื่อสาร วิธีการนี้ช่วยให้มั่นใจว่าข้อมูลที่ส่งไปยัง MCU และข้อมูลที่รับกลับมามีความถูกต้อง
ความสำคัญของ CRC กับ การสื่อสารข้อมูล
การสื่อสารข้อมูลที่เชื่อถือได้ในระบบอิเล็กทรอนิกส์เป็นสิ่งจำเป็น CRC เป็นเทคนิคที่ใช้ตรวจสอบความถูกต้องของข้อมูลที่รับส่งเพื่อป้องกันข้อผิดพลาดที่อาจเกิดขึ้น
หลักการทำงานของ CRC
CRC ใช้ในการคำนวณค่าเช็คซัมของข้อมูลที่ส่งไปและเพิ่มค่า CRC ไปยังข้อมูลนั้น เมื่อข้อมูลถูกส่งไปยังปลายทาง ปลายทางจะคำนวณค่า CRC ของข้อมูลที่ได้รับมาอีกครั้งและเปรียบเทียบกับค่า CRC ที่แนบมา หากค่า CRC ตรงกัน ข้อมูลที่รับถือว่าถูกต้อง
ตัวอย่างการใช้ Python และ pyserial ในการสื่อสารผ่าน RS-232 และ RS-485
เพื่อให้มั่นใจว่าการรับส่งข้อมูลถูกต้องและครบถ้วน คุณสามารถใช้ Python และไลบรารี pyserial สำหรับการสื่อสารกับ Inverter ต่อไปนี้คือตัวอย่างโค้ด :
python
import serial import time
# กำหนดพอร์ตอนุกรมและ baudrate ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
def send_command(command): ser.write(command) time.sleep(0.1)
def read_response(expected_length): buffer = bytearray() while True: if ser.in_waiting: buffer.extend(ser.read(ser.in_waiting)) if len(buffer) >= expected_length: break time.sleep(0.01) return buffer
if __name__ == '__main__': # ตัวอย่างคำสั่งสำหรับ Inverter command = b'\x01\x03\x00\x00\x00\x10\x14\x0B' # ตรวจสอบคำสั่งให้ถูกต้องตามโปรโตคอลของ Inverter expected_length = 37 # กำหนดความยาวข้อมูลที่คาดว่าจะได้รับ
send_command(command) response = read_response(expected_length) if response: print(f'Received data: {response}') else: print('No data received')
ser.close()
|
การประยุกต์ใช้ CRC ใน Python
การใช้ Python และไลบรารี pyserial เราสามารถสร้างฟังก์ชันสำหรับคำนวณและตรวจสอบค่า CRC เพื่อรับรองความถูกต้องของข้อมูล ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการเพิ่มค่า CRC ไปยังข้อมูลที่ส่ง และตรวจสอบค่า CRC ของข้อมูลที่รับกลับมา:
python
import serial import time
# กำหนดพอร์ตอนุกรมและ baudrate ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
def calculate_crc(data): crc = 0xFFFF for pos in data: crc ^= pos for _ in range(8): if crc & 1: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc
def append_crc(data): crc = calculate_crc(data) return data + bytes([crc & 0xFF, (crc >> 8) & 0xFF])
def check_crc(response): received_crc = (response[-1] << 8) | response[-2] calculated_crc = calculate_crc(response[:-2]) return received_crc == calculated_crc
def send_command_with_crc(command): command_with_crc = append_crc(command) ser.write(command_with_crc)
def read_response(expected_length): buffer = bytearray() while len(buffer) < expected_length + 2: if ser.in_waiting: buffer.extend(ser.read(ser.in_waiting)) time.sleep(0.01) return buffer
if __name__ == '__main__': command = b'COMMAND' # คำสั่งที่ต้องการทดสอบ success_count = 0 total_tests = 100
for _ in range(total_tests): send_command_with_crc(command) response = read_response(len(command)) if check_crc(response): if response[:-2] == command: success_count += 1
print(f'Successful transmissions: {success_count}/{total_tests}') ser.close()
|
สรุป
การใช้ CRC ในการสื่อสารข้อมูลช่วยเพิ่มความน่าเชื่อถือและความถูกต้องของข้อมูลที่รับส่งผ่านพอร์ตอนุกรม โดยเฉพาะในระบบที่ต้องการความมั่นใจในความถูกต้องของข้อมูลที่ส่งและรับ
การใช้ CRC ในการสื่อสารข้อมูลผ่านพอร์ตอนุกรม
การใช้ CRC ในการตรวจสอบความถูกต้องของข้อมูลเป็นวิธีที่มีประสิทธิภาพในการเพิ่มความน่าเชื่อถือของระบบสื่อสาร โดยเฉพาะอย่างยิ่งในการสื่อสารผ่านพอร์ตอนุกรม (Serial Port) ที่มีการใช้งานอย่างแพร่หลายในระบบอิเล็กทรอนิกส์และไมโครคอนโทรลเลอร์ (MCU)
ความสำคัญของการตรวจสอบความถูกต้องในข้อมูลการสื่อสาร
การสื่อสารข้อมูลที่มีความถูกต้องและแม่นยำเป็นสิ่งจำเป็นสำหรับระบบอิเล็กทรอนิกส์และไมโครคอนโทรลเลอร์ โดยเฉพาะเมื่อมีข้อกำหนดในการส่งและรับข้อมูลที่ต้องไม่มีข้อผิดพลาด การใช้ CRC ช่วยเพิ่มความมั่นใจในการสื่อสารข้อมูล ลดโอกาสเกิดข้อผิดพลาด และ ทำให้ระบบมีความน่าเชื่อถือมากขึ้น
ตัวอย่างการใช้ CRC ใน Python
การใช้ CRC ในการสื่อสารผ่านพอร์ตอนุกรมในภาษา Python สามารถทำได้โดยการคำนวณค่า CRC ของข้อมูล เพิ่มค่า CRC ไปยังข้อมูลที่ส่ง และตรวจสอบค่า CRC ของข้อมูลที่รับกลับมา ต่อไปนี้คือตัวอย่างโค้ดที่แสดงให้เห็นถึงวิธีการคำนวณและตรวจสอบค่า CRC:
python
import serial import time
# กำหนดพอร์ตอนุกรมและ baudrate ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
def calculate_crc(data): crc = 0xFFFF for pos in data: crc ^= pos for _ in range(8): if crc & 1: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc
def append_crc(data): crc = calculate_crc(data) return data + bytes([crc & 0xFF, (crc >> 8) & 0xFF])
def check_crc(response): received_crc = (response[-1] << 8) | response[-2] calculated_crc = calculate_crc(response[:-2]) return received_crc == calculated_crc
def send_command_with_crc(command): command_with_crc = append_crc(command) ser.write(command_with_crc)
def read_response(expected_length): buffer = bytearray() while len(buffer) < expected_length + 2: if ser.in_waiting: buffer.extend(ser.read(ser.in_waiting)) time.sleep(0.01) return buffer
if __name__ == '__main__': command = b'COMMAND' # คำสั่งที่ต้องการทดสอบ success_count = 0 total_tests = 100
for _ in range(total_tests): send_command_with_crc(command) response = read_response(len(command)) if check_crc(response): if response[:-2] == command: success_count += 1
print(f'Successful transmissions: {success_count}/{total_tests}') ser.close()
|
การทดสอบการสื่อสาร 100 ครั้ง
เพื่อให้มั่นใจว่าการสื่อสารมีความถูกต้องและเสถียร สามารถทำการทดสอบโดยการส่งคำสั่งไปยัง MCU และรับข้อมูลกลับมา 100 ครั้ง พร้อมตรวจสอบความถูกต้องของข้อมูลในแต่ละครั้ง วิธีนี้ช่วยให้คุณสามารถประเมินและปรับปรุงระบบสื่อสารของคุณได้อย่างมีประสิทธิภาพ
การตั้งบัฟเฟอร์เพื่อการจัดการข้อมูล
ในการสื่อสารผ่านพอร์ตอนุกรม การตั้งบัฟเฟอร์เป็นสิ่งสำคัญเพื่อจัดการข้อมูลที่รับเข้ามาและป้องกันการสูญหายของข้อมูล นอกจากนี้ การใช้การตรวจสอบค่าควบคุม (checksum) หรือการตรวจสอบความถูกต้องของข้อมูล (error checking) เช่น CRC สามารถช่วยให้มั่นใจได้ว่าข้อมูลที่รับส่งมีความถูกต้องและไม่มีข้อผิดพลาดในการสื่อสาร
ตัวอย่างการคำนวณ CRC สำหรับ MODBUS
การคำนวณ CRC สำหรับโปรโตคอล MODBUS ซึ่งใช้กันอย่างแพร่หลายใน Inverter หลายรุ่น:
python
การสื่อสารผ่านโปรโตคอล MQTT ด้วยการตรวจสอบ CRC
การตรวจสอบความถูกต้องของข้อมูลเมื่อใช้โปรโตคอล MQTT สามารถทำได้โดยใช้การยืนยันความถูกต้องของข้อมูล (data integrity) ที่จัดเตรียมโดย MQTT เอง แม้ว่า MQTT ไม่ได้มีการตรวจสอบ CRC ในตัว แต่คุณสามารถเพิ่มการตรวจสอบ CRC ในข้อมูลเพย์โหลด (payload) ก่อนที่จะส่งไปยังโบรกเกอร์ MQTT
ตัวอย่างโค้ดใน Python สำหรับ MQTT
Broker
python
import paho.mqtt.client as mqtt import struct
def calculate_crc(data): crc = 0xFFFF for pos in data: crc ^= pos for _ in range(8): if crc & 1: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc
def on_connect(client, userdata, flags, rc): print("Connected with result code " + str(rc)) payload = b'Hello, MQTT!' crc = calculate_crc(payload) payload_with_crc = payload + struct.pack('<H', crc) client.publish("test/topic", payload_with_crc)
client = mqtt.Client() client.on_connect = on_connect client.connect("mqtt.eclipse.org", 1883, 60) client.loop_forever()
|
Subscriber
python
import paho.mqtt.client as mqtt import struct
def calculate_crc(data): crc = 0xFFFF for pos in data: crc ^= pos for _ in range(8): if crc & 1: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc
def on_message(client, userdata, msg): payload = msg.payload received_crc = struct.unpack('<H', payload[-2:])[0] data = payload[:-2] calculated_crc = calculate_crc(data) if received_crc == calculated_crc: print("Received valid data:", data) else: print("Received data with invalid CRC")
client = mqtt.Client() client.on_message = on_message client.connect("mqtt.eclipse.org", 1883, 60) client.subscribe("test/topic") client.loop_forever()
|
สรุป
การใช้ CRC ในการสื่อสารข้อมูลผ่านพอร์ตอนุกรมและโปรโตคอล MQTT เป็นวิธีที่มีประสิทธิภาพในการตรวจสอบและรับรองความถูกต้องของข้อมูล ช่วยให้ระบบมีความน่าเชื่อถือและเสถียรมากขึ้น
การตรวจสอบความถูกต้องของข้อมูลในระบบอิเล็กทรอนิกส์และไมโครคอนโทรลเลอร์
การตรวจสอบความถูกต้องของข้อมูลที่ส่งและรับเป็นสิ่งสำคัญอย่างยิ่งในระบบอิเล็กทรอนิกส์และไมโครคอนโทรลเลอร์ (MCU) ไม่ว่าจะเป็นการสื่อสารผ่านพอร์ตอนุกรม (Serial Port) หรือโปรโตคอลการสื่อสารอื่นๆ การใช้เทคนิคต่างๆ เช่น CRC (Cyclic Redundancy Check) ช่วยเพิ่มความน่าเชื่อถือของข้อมูลและลดโอกาสเกิดข้อผิดพลาดได้
ตัวอย่างการใช้งาน CRC ในการสื่อสารข้อมูล
การทดสอบการสื่อสารด้วยการตรวจสอบความถูกต้องของข้อมูลสามารถทำได้หลายวิธี เช่น การส่งข้อมูลหลายครั้งและตรวจสอบความถูกต้องของข้อมูลที่รับกลับมา ในส่วนนี้จะสรุปตัวอย่างการใช้งาน CRC ในการสื่อสารข้อมูลผ่านพอร์ตอนุกรม
ตัวอย่างการคำนวณและตรวจสอบ CRC สำหรับการสื่อสารผ่านพอร์ตอนุกรม
python
import serial import time
# กำหนดพอร์ตอนุกรมและ baudrate ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
def calculate_crc(data): crc = 0xFFFF for pos in data: crc ^= pos for _ in range(8): if crc & 1: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc
def append_crc(data): crc = calculate_crc(data) return data + bytes([crc & 0xFF, (crc >> 8) & 0xFF])
def check_crc(response): received_crc = (response[-1] << 8) | response[-2] calculated_crc = calculate_crc(response[:-2]) return received_crc == calculated_crc
def send_command_with_crc(command): command_with_crc = append_crc(command) ser.write(command_with_crc)
def read_response(expected_length): buffer = bytearray() while len(buffer) < expected_length + 2: if ser.in_waiting: buffer.extend(ser.read(ser.in_waiting)) time.sleep(0.01) return buffer
if __name__ == '__main__': command = b'COMMAND' # คำสั่งที่ต้องการทดสอบ success_count = 0 total_tests = 100
for _ in range(total_tests): send_command_with_crc(command) response = read_response(len(command)) if check_crc(response): if response[:-2] == command: success_count += 1
print(f'Successful transmissions: {success_count}/{total_tests}') ser.close()
|
การใช้งาน CRC ในโปรโตคอล MQTT
การตรวจสอบความถูกต้องของข้อมูลในโปรโตคอล MQTT สามารถทำได้โดยการเพิ่มการตรวจสอบ CRC ในข้อมูลเพย์โหลด (payload) ก่อนที่จะส่งไปยังโบรกเกอร์ MQTT โดยมีตัวอย่างโค้ดดังนี้:
ฝั่งผู้ส่ง (Broker)
python
import paho.mqtt.client as mqtt import struct
def calculate_crc(data): crc = 0xFFFF for pos in data: crc ^= pos for _ in range(8): if crc & 1: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc
def on_connect(client, userdata, flags, rc): print("Connected with result code " + str(rc)) payload = b'Hello, MQTT!' crc = calculate_crc(payload) payload_with_crc = payload + struct.pack('<H', crc) client.publish("test/topic", payload_with_crc)
client = mqtt.Client() client.on_connect = on_connect client.connect("mqtt.eclipse.org", 1883, 60) client.loop_forever()
|
ฝั่งผู้รับ (Subscriber)
python
import paho.mqtt.client as mqtt import struct
def calculate_crc(data): crc = 0xFFFF for pos in data: crc ^= pos for _ in range(8): if crc & 1: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc
def on_message(client, userdata, msg): payload = msg.payload received_crc = struct.unpack('<H', payload[-2:])[0] data = payload[:-2] calculated_crc = calculate_crc(data) if received_crc == calculated_crc: print("Received valid data:", data) else: print("Received data with invalid CRC")
client = mqtt.Client() client.on_message = on_message client.connect("mqtt.eclipse.org", 1883, 60) client.subscribe("test/topic") client.loop_forever()
|
การใช้งาน CRC ใน Arduino
สำหรับการสื่อสารระหว่าง Arduino และ Inverter หรืออุปกรณ์อื่นๆ การใช้ CRC ช่วยให้การสื่อสารมีความถูกต้องและเสถียรมากขึ้น โดยสามารถใช้งานได้ดังนี้:
ตัวอย่างโค้ดบน Arduino
cpp
#include <SoftwareSerial.h>
// กำหนดพอร์ตอนุกรม SoftwareSerial mySerial(10, 11); // RX, TX
// ฟังก์ชันคำนวณ CRC unsigned int calculateCRC(byte *array, int length) { unsigned int crc = 0xFFFF; for (int pos = 0; pos < length; pos++) { crc ^= (unsigned int)array[pos]; for (int i = 8; i != 0; i--) { if ((crc & 0x0001) != 0) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } return crc; }
// ฟังก์ชันส่งคำสั่งพร้อม CRC void sendCommand(byte *command, int length) { unsigned int crc = calculateCRC(command, length); command[length] = crc & 0xFF; command[length + 1] = (crc >> 8) & 0xFF; mySerial.write(command, length + 2); }
// ฟังก์ชันอ่านและตรวจสอบ CRC bool checkCRC(byte *response, int length) { unsigned int receivedCRC = (response[length - 1] << 8) | response[length - 2]; unsigned int calculatedCRC = calculateCRC(response, length - 2); return receivedCRC == calculatedCRC; }
void setup() { Serial.begin(9600); mySerial.begin(9600);
// คำสั่งตัวอย่างสำหรับ Inverter byte command[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x10}; sendCommand(command, sizeof(command));
delay(1000); byte response[37]; int index = 0;
// รับข้อมูล while (mySerial.available() && index < sizeof(response)) { response[index++] = mySerial.read(); }
// ตรวจสอบ CRC if (checkCRC(response, index)) { Serial.println("Received valid data:"); for (int i = 0; i < index; i++) { Serial.print(response[i], HEX); Serial.print(" "); } Serial.println(); } else { Serial.println("Received data with invalid CRC"); } }
void loop() { // ว่างเปล่า }
|
สรุป
การตรวจสอบความถูกต้องของข้อมูลด้วย CRC เป็นวิธีที่มีประสิทธิภาพในการเพิ่มความน่าเชื่อถือและเสถียรภาพของการสื่อสารข้อมูลในระบบอิเล็กทรอนิกส์และไมโครคอนโทรลเลอร์ การใช้ CRC สามารถนำมาใช้ได้ในหลายโปรโตคอลการสื่อสาร เช่น พอร์ตอนุกรม (Serial Port), MQTT, และการสื่อสารกับอุปกรณ์อื่นๆ ผ่าน Arduino ซึ่งจะช่วยให้ระบบมีความมั่นใจในความถูกต้องของข้อมูลที่รับและส่ง