简体   繁体   English

需要帮助通过RS232,SPI或I2C解密协议以与Arduino的控制器进行通讯

[英]Need help deciphering protocol over RS232, SPI, or I2C to talk to controller with Arduino

I have a motor controller which I want to receive live telemetry from on my Arduino. 我有一个电机控制器,希望从Arduino上接收实时遥测。 I have posted screenshots of the registers below and the way the controller uses these protocols. 我在下面发布了寄存器的屏幕截图以及控制器使用这些协议的方式。 I just can't get any data using either three? 我只是无法使用这三个获取任何数据? If anyone knows how I can get the data using any of these three protocols your help would be much appreciated!! 如果有人知道如何使用这三种协议中的任何一种来获取数据,将非常感谢您的帮助! I am willing to try anything :) Any form of help would be much appreciated. 我愿意尝试任何事情:)任何形式的帮助将不胜感激。

RegisterRS232SPII2C

UPDATE Here is the code for i2c that I have already tried. 更新这是我已经尝试过的i2c代码。 I was trying to read from register 6. The code simply returns zeroes. 我试图从寄存器6中读取。代码仅返回零。 Updated code to include Wire.available. 更新了代码以包含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
}

EDIT #2 编辑#2
In my attempts to get this device to work I have tried using RS232 with the code below. 为了使该设备正常工作,我尝试使用带有以下代码的RS232。 The serial monitor shows nothing at all but they "Hello" message. 串行监视器只显示“ 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
    }
  }
}

Probably you will have to WAIT for the bytes to arrive. 可能需要等待字节才能到达。 So, in your code, write 因此,在您的代码中,编写

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
}

If this does not work, you can try to add also the i2caddr to the initial checksum (shifted by 1 position), since it states that the checksum is Byte0 + Byte1 + ... Byte 3. 如果这不起作用,则可以尝试将i2caddr也添加到初始校验和(移位1个位置),因为它指出校验和是Byte0 + Byte1 + ... Byte 3。

One more thing: if you continue getting a checksum error, print directly the bytes and try to figure out what's happening 还有一件事:如果继续出现校验和错误,请直接打印字节并尝试找出正在发生的情况

EDIT: 编辑:

As for your serial code, there is a bug and some things to improve. 至于您的序列号,有一个错误和一些需要改进的地方。

The bug is that you wait for data (call to available) on Serial instead of Serial1. 该错误是您等待串行(而不是串行1)上的数据(调用可用数据)。

Then, again you should WAIT for three bytes to arrive, not execute the reading until there are bytes. 然后,再次应等待三个字节,直到有字节才执行读取。 So.. Try using this code: 因此,请尝试使用以下代码:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM