我有一个电机控制器,我希望从我的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
}
}
}
答案 0 :(得分:0)
可能你必须等待字节到达。所以,在你的代码中,写一下
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 + ...字节3。
还有一件事:如果你继续得到校验和错误,请直接打印字节并尝试弄清楚发生了什么
编辑:
至于你的序列号,有一个bug和一些需要改进的地方。
错误是您在Serial而不是Serial1上等待数据(调用可用)。
然后,再次应该等待三个字节到达,直到有字节才执行读取。所以..尝试使用此代码:
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();
}