Python与KEYENCE传感器ASCII通信代码异常排查求助
Problem Description
我使用的是KEYENCE品牌的传感器,需通过ASCII协议进行通信。根据传感器规格书给出的示例,发送ASCII格式的「SR, 06,101 CRLF」(对应十六进制数据:0x53, 0x52, 0x2C, 0x30, 0x36, 0x2C, 0x31, 0x30, 0x31, 0x00, 0x0A)即可被传感器正常接收。我首次使用Python编写ASCII数据传输代码,参照上述示例编写并发送数据后,虽检测到信号传输,但传感器触发报警,未正常接收数据。
User's Code
import serial import time ser = serial.Serial('/dev/ttyS0', 9600) senddata = [0x53, 0x52, 0x2C, 0x30, 0x31, 0x2C, 0x31, 0x30, 0x31, 0x0D, 0x0A] send_binary = bytes(senddata) ser.write(send_binary) ser.close()
Root Cause Analysis & Fixed Solution
Let's break down the issues in your code and fix them step by step:
Mismatched Command Parameter
The spec says the command isSR, 06,101, but your code sendsSR, 01,101(the hex0x30,0x31corresponds to "01" instead of "06"). Sensors reject invalid parameters immediately, which is likely triggering the alarm.Incorrect Terminator
You mentioned the spec uses0x00, 0x0A(NULL + LF) as the terminator, but your code uses0x0D, 0x0A(CR + LF). KEYENCE sensors are strict about protocol details—this mismatch alone can cause communication failures.Missing Transmission Delay
Closing the serial port right after writing cuts off the transmission prematurely, especially at 9600 baud. We need to give the sensor time to receive all data.
Here's the corrected code that addresses all these issues:
import serial import time # Initialize serial port with full matching parameters (critical for KEYENCE sensors) ser = serial.Serial( port='/dev/ttyS0', baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1 # Add timeout to avoid infinite blocking on read ) # Strictly follow the spec's command and terminator senddata = [0x53, 0x52, 0x2C, 0x30, 0x36, 0x2C, 0x31, 0x30, 0x31, 0x00, 0x0A] send_binary = bytes(senddata) try: ser.write(send_binary) # Wait for data to fully transmit (9600 baud: ~1ms per byte, add extra buffer) time.sleep(0.05) # Optional: Read sensor response to confirm success response = ser.readline() if response: print(f"Sensor Response: {response.decode('ascii')}") else: print("No response received. Check wiring and sensor settings.") finally: ser.close()
Additional Troubleshooting Tips
- Verify Serial Parameters: Double-check that your sensor's baud rate, parity, stop bits, and data bits exactly match the code. Any mismatch will break communication.
- Test with Serial Tools: Use a tool like
minicomor PuTTY to manually send the spec's command. If the sensor responds, the issue was in your code; if not, check hardware connections or sensor mode. - Confirm Sensor Mode: Ensure the sensor is set to ASCII communication mode—some KEYENCE models default to binary mode, which needs manual switching via their setup software.
内容的提问来源于stack exchange,提问作者toratora25

