[英]Need help deciphering protocol over RS232, SPI, or I2C to talk to controller with Arduino
我有一個電機控制器,希望從Arduino上接收實時遙測。 我在下面發布了寄存器的屏幕截圖以及控制器使用這些協議的方式。 我只是無法使用這三個獲取任何數據? 如果有人知道如何使用這三種協議中的任何一種來獲取數據,將非常感謝您的幫助! 我願意嘗試任何事情:)任何形式的幫助將不勝感激。
更新這是我已經嘗試過的i2c代碼。 我試圖從寄存器6中讀取。代碼僅返回零。 更新了代碼以包含Wire.available。
#include <Wire.h>
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
int k = readRegister(0x08, 0x06);
Serial.println(k, DEC);
delay(500);
}
uint16_t readRegister(uint8_t i2cAddr, uint8_t regAddr) {
// I2C write sequence to address the given read register
Wire.beginTransmission(i2cAddr); // Module address
Wire.write(regAddr); // Register Address
Wire.write(0); // Command Data = dummy zeroes
Wire.write(0);
Wire.write(-regAddr); // Checksum
Wire.endTransmission(); // Finish I2C write sequence
// I2C read sequence to actually get the register value
Wire.requestFrom(i2cAddr, 3);
if (Wire.available() == 3) {
uint16_t regVal = Wire.read();
regVal <<= 8;
regVal |= Wire.read();
if ((Wire.read() + regVal >> 8 + regVal & 0xFF) == 0) {
return regVal; // Checksum OK
}
}
return 0xFFFF; // Checksum error
}
編輯#2
為了使該設備正常工作,我嘗試使用帶有以下代碼的RS232。 串行監視器只顯示“ Hello”消息,什么也沒有顯示。
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Serial1.write(0x0); //write five zeroes to clear the command buffer
Serial1.write(0x0);
Serial1.write(0x0);
Serial1.write(0x0);
Serial1.write(0x0);
}
void loop() {
sendData();
delay(500);
serialE1();
}
void sendData() {
Serial1.write((byte)0x17); //device address
Serial1.write((byte)0x6); //register address
Serial1.write((byte)0x0); //zeroes
Serial1.write((byte)0x0); //zeroes
Serial1.write((byte)-0x1D); //checksum
}
uint16_t serialE1() {
Serial.println("Hello"); //just letting myself know it got here.
while (Serial.available()) {
uint16_t regVal = Serial1.read();
regVal <<= 8;
regVal |= Serial1.read();
if ((Serial1.read() + regVal >> 8 + regVal & 0xFF) == 0) {
Serial.write(regVal); // Checksum OK
}
else {
Serial.write(0xFFFF); // Checksum error
}
}
}
可能需要等待字節才能到達。 因此,在您的代碼中,編寫
while (Wire.available() != 3);
uint16_t regVal = Wire.read();
regVal <<= 8;
regVal |= Wire.read();
if ((Wire.read() + regVal >> 8 + regVal & 0xFF) == 0) {
return regVal; // Checksum OK
}
如果這不起作用,則可以嘗試將i2caddr也添加到初始校驗和(移位1個位置),因為它指出校驗和是Byte0 + Byte1 + ... Byte 3。
還有一件事:如果繼續出現校驗和錯誤,請直接打印字節並嘗試找出正在發生的情況
編輯:
至於您的序列號,有一個錯誤和一些需要改進的地方。
該錯誤是您等待串行(而不是串行1)上的數據(調用可用數據)。
然后,再次應等待三個字節,直到有字節才執行讀取。 因此,請嘗試使用以下代碼:
uint8_t cmd[5] = {0,0,0,0,0};
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
//write five zeroes to clear the command buffer
sendWithChecksum(cmd);
// Initialize the cmd array
cmd[0] = 0x17;
cmd[1] = 0x06;
}
void loop() {
sendWithChecksum(cmd);
Serial.println("Hello");
receiveData();
delay(500); // Wait for some time
}
void sendWithChecksum(uint8_t *array)
{
uint8_t i;
array[4] = 0;
for (i = 0; i < 4; i++)
array[4] -= array[i];
Serial1.write(array,5);
}
void receiveData()
{
// Wait for serial data to become available
while(Serial1.available() < 3);
uint16_t regVal = (((uint16_t)Serial1.read()) << 8) | Serial1.read();
if ((Serial1.read() + regVal >> 8 + regVal & 0xFF) == 0)
{// Checksum OK
Serial.print("Received ");
Serial.println(regVal,HEX);
}
else
{// Checksum wrong
Serial.println("Checksum wrong");
}
// Clear buffer
while (Serial1.available()) Serial1.read();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.