2016-06-04 2 views
-1

Я пытаюсь взаимодействовать с контроллером двигателя EPOS2 через RS232 Serial с Arduino Duemilanove (потому что это то, что я лежал). Я получил его для работы по большей части - я могу отправлять и получать данные, когда я вручную вычисляю контрольную сумму CRC, но я пытаюсь динамически контролировать скорость двигателя, которая требует изменения данных и, следовательно, изменения контрольной суммы. Документация для вычисления контрольной суммы здесь, на странице 24:Последовательная связь между Arduino и EPOS: проблемы с вычислением CRC

Я скопировал код непосредственно из этой документации, и интегрировать его в свой код, и не вычисления контрольной суммы правильно. Ниже приведена краткая версия моего полного эскиза (проверена, давая 0x527C). Самая странная часть заключается в том, что он вычисляет другое значение в моем полном эскизе, чем в приведенном ниже, но оба ошибочны. Есть ли что-то очевидное, что мне не хватает?

byte comms[6] = { 0x10, 0x01, 0x03, 0x20, 0x01, 0x02 }; // CRC should be 0xA888 

void setup() { 
    Serial.begin(115200); 
} 

void loop() { 
    calcCRC(comms, 6, true); 
    while(1); 
} 

word calcCRC(byte *comms, int commsSize, boolean talkative) { 
    int warraySize = commsSize/2 + commsSize % 2; 
    word warray[warraySize]; 

    warray[0] = comms[0] << 8 | comms[1]; 
    Serial.println(warray[0], HEX); 

    for (int i = 1; i <= warraySize - 1; i++) { 
    warray[i] = comms[i * 2 + 1] << 8 | comms[i * 2]; 
    Serial.println(warray[i], HEX); 
    } 

    word* warrayP = warray; 

    word shifter, c; 
    word carry; 
    word CRC = 0; 


    //Calculate pDataArray Word by Word 
    while (commsSize--) 
    { 
    shifter = 0x8000; 
    c = *warrayP ++; 
    do { 
     carry = CRC & 0x8000; 
     CRC <<= 1; 
     if (c & shifter) CRC++; 
     if (carry) CRC ^= 0x1021; 
     shifter >>= 1; 
    } while (shifter); 
    } 

    if (talkative) { 
    Serial.print("the CRC for this data is "); 
    Serial.println(CRC, HEX); 
    } 

    return CRC; 
} 

Я использовал ссылку ниже, чтобы вычислить контрольную сумму, которая работает для этих данных:

https://www.ghsi.de/CRC/index.php?Polynom=10001000000100001&Message=1001+2003+0201

Спасибо так много !!

ответ

0

С чего начать.

Прежде всего, вы используете commsSize-- для своего цикла, который будет проходить шесть раз, когда у вас есть только три слова в warray. Таким образом, вы получаете доступ за пределами warray и обязательно получите случайный результат (или сбой).

Во-вторых, сборка вашего первого слова происходит от ваших других сборок. Ваш онлайн-CRC испытывает такую ​​же проблему, поэтому у вас, по-видимому, даже нет надежного тестового примера.

В-третьих (не проблема для тестового примера), если у вас есть нечетное количество байтов ввода, вы делаете доступ за пределами диапазона comms, чтобы заполнить последнее слово. И вы выполняете CRC-бит слишком много раз, если спецификация не называет в этом случае какое-то дополнение. (Ваша документальная ссылка повреждена, поэтому я не вижу, что должно произойти.) Даже тогда вы используете случайные данные для заполнения вместо нулей.

В любом случае, конверсия целого слова - пустая трата времени. Вы можете просто сделать это байтом за раз, учитывая правильное упорядочение байтов. Это также позволяет избежать проблемы с нечетным числом байтов. Это произведет 0xa888 от входа вы дали онлайн CRC калькулятор (которые ваши байты в перепутались порядке, но именно так, как вы дали им калькулятор):

unsigned char dat[6] = { 0x10, 0x01, 0x20, 0x03, 0x02, 0x01 }; 

unsigned crc1021(unsigned char *dat, int len) { 
    unsigned crc = 0; 
    while (len) { 
     crc ^= *dat++ << 8; 
     for (int k = 0; k < 8; k++) 
      crc = crc & 0x8000 ? (crc << 1)^0x1021 : crc << 1; 
     len--; 
    } 
    return crc & 0xffff; 
} 
+0

Спасибо! Это было полезно! Ссылка документа работала на нескольких устройствах, я прошу прощения за это. Я сделал это со словами, потому что именно так это сделала документация. Кроме того, порядок байтов был «перепутан», потому что это тот порядок, который EPOS должен получить. Честно говоря, я, вероятно, мог бы лучше прокомментировать мой код ... Еще раз спасибо за помощь! –

Смежные вопросы