| Форум РадиоКот https://radiokot.ru/forum/ |
|
| Arduino RS485 управление двигателем и обратная связь. https://radiokot.ru/forum/viewtopic.php?f=66&t=179241 |
Страница 1 из 1 |
| Автор: | anatoliydenisenko44 [ Чт окт 21, 2021 12:30:40 ] |
| Заголовок сообщения: | Arduino RS485 управление двигателем и обратная связь. |
Доброго времени суток! Не так давно занимаюсь электроникой и низкоуровневым программированием а с промышленными протоколами дела совсем не имел. Есть двигатель он работает по протоколу rs-485, у меня связка ардуино уно + модуль rs-485 + мотор. Я ним могу управлять и на него команды приходят, а вот обратной связи я добиться не могу. В тему добавлю код своего скетча. Я не очень силен в работе с битами и регистрами, если есть хорошая литература которая даст понять как мне это все использовать - я буд только признательным. Потому что в данном протоколе есть старшие и младшие биты и я кое как понять как мне сделать скетч. Добавлю фото с инструкцией к протоколу. Спойлер![]() ![]() Код: const int PIN_DIR = 2; byte servoID_1 = 0x01; //byte servoALL = 0x uint16_t a=0; void setup() { pinMode(PIN_DIR,OUTPUT); Serial.begin(115200); digitalWrite(PIN_DIR,LOW); Serial.flush(); } void loop() { a = analogRead(A0); a= map(a,0,1023,0,360); delay(100); //moveServo4(a); torque(a); // moveServo_temp(a); //delay(1000); // torque_pol(0); delay(1000); printBuffer(); //delay(2000); } void printBuffer(){ unsigned char buf[5]; uint8_t tem[1]; uint16_t volt[1]; uint16_t sp[1]; uint16_t enc[1]; byte notchecksum = (0xDC); digitalWrite(PIN_DIR,HIGH); buf[0]=0x3E; buf[1]=0x9C; buf[2]=0x01; buf[3]=0x00; buf[4]=0xDB; Serial.write(buf,5); Serial.flush(); digitalWrite(PIN_DIR,LOW); while(Serial.available()>0){ tem[1]=Serial.read(); delay(300); volt[1]=Serial.read(); delay(300); sp[1]=Serial.read(); delay(300); enc[1]=Serial.read(); delay(300); } Serial.print(tem[1],HEX); Serial.print(" "); Serial.print(volt[1],HEX); Serial.print(" "); Serial.print(sp[1],HEX); Serial.print(" "); Serial.print(enc[1],HEX); Serial.print(" "); Serial.println(""); } void torque(int Position){ unsigned char buf[8]; char Position_H = Position >> 8; char Position_L = Position % 256; byte notchecksum = (Position_L+Position_H); digitalWrite(PIN_DIR,HIGH); buf[0]=0x3E; buf[1]=0xA1; buf[2]=0x01; buf[3]=0x02; buf[4]=0xE2; buf[5]=Position_L; buf[6]=Position_H; buf[7]=notchecksum; Serial.write(buf,8); Serial.flush(); delay(100); digitalWrite(PIN_DIR,LOW); } void moveServo(){ digitalWrite(2,HIGH); delay(100); Serial.write(0x3E); Serial.write(0xA4); Serial.write(0x01); Serial.write(0x0C); Serial.write(0xEF); Serial.write(0x10); Serial.write(0x27); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0xA0); Serial.write(0x8C); Serial.write(0x00); Serial.write(0x00); Serial.write(0x63); Serial.flush(); digitalWrite(2,LOW); delay(100); } void moveServo4(int Position){ char Position_H = Position >> 8; char Position_L = Position % 256; byte notchecksum = (Position_L+Position_H+0x00+0x00+0x00+0x00+0x00+0x00+0xA0+0x8C+0x00+0x00); //byte notchecksum = (0xA0+0x8C+0x00+0x00+0x00+0x00+0x00+0x00+0xA0+0x8C+0x00+0x00); digitalWrite(PIN_DIR,HIGH); delay(100); Serial.write(0x3E); Serial.write(0xA4); Serial.write(0x01); Serial.write(0x0C); Serial.write(0xEF); Serial.write(Position_H); // Serial.write(Position_L); Serial.write(Position_L); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0xA0); Serial.write(0x8C); Serial.write(0x00); Serial.write(0x00); Serial.write(notchecksum); Serial.flush(); delay(100); digitalWrite(2,LOW); //Serial.println(Position_H); // Serial.println(Position_L); } void moveServo2(){ byte notchecksum = (0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0xA0+0x8C+0x00+0x00); digitalWrite(2,HIGH); delay(100); Serial.write(0x3E); Serial.write(0xA4); Serial.write(0x01); Serial.write(0x0C); Serial.write(0xEF); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0xA0); Serial.write(0x8C); Serial.write(0x00); Serial.write(0x00); Serial.write(notchecksum); Serial.flush(); digitalWrite(2,LOW); delay(100); } void moveServo3(){ digitalWrite(2,HIGH); delay(100); Serial.write(0x3E); Serial.write(0xA4); Serial.write(0x01); Serial.write(0x0C); Serial.write(0xEF); Serial.write(0xA0); Serial.write(0x8C); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0xA0); Serial.write(0x8C); Serial.write(0x00); Serial.write(0x00); Serial.write(0x58); Serial.flush(); digitalWrite(2,LOW); delay(100); } void moveServo_temp(int Position){ unsigned char ab; char Position_H = Position >> 8; char Position_L = Position % 256; byte notchecksum = (0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00); //byte notchecksum = (0xA0+0x8C+0x00+0x00+0x00+0x00+0x00+0x00+0xA0+0x8C+0x00+0x00); digitalWrite(2,HIGH); delay(100); Serial.write(0x3E); Serial.write(0xA4); Serial.write(0x01); Serial.write(0x07); Serial.write(0xEA); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(0x00); Serial.write(notchecksum); Serial.flush(); digitalWrite(2,LOW); delay(100); //ab=Serial.read(); //Serial.print("ab - "); //Serial.println(ab); } |
|
| Автор: | oleg110592 [ Чт окт 21, 2021 13:22:29 ] |
| Заголовок сообщения: | Re: Arduino RS485 управление двигателем и обратная связь. |
Для чтения state вы передаете команду из 5 байт. DATA[4] - контрольная сумма, как она вычислялась (0xDB)? Наверное без правильной контрольной суммы ответа не будет. Зачем массивы из одного элемента 16 бит? Код: uint8_t tem[1]; uint16_t volt[1]; uint16_t sp[1]; uint16_t enc[1]; Serial.read() принимает 1 байт (8 бит). После команды чтения state должно быть получено 13 байт. Сделать массив из 13 байт типа unsigned char rxbuf[13]; И принять можно типа так: Код: i = 0; while(Serial.available()>0){ rxbuf[i]=Serial.read(); i++; if(i >=13) break; } Потом разбирать байты на составляющие. з.ы. мог и ошибиться - надо проверять |
|
| Автор: | parovoZZ [ Чт окт 21, 2021 13:30:54 ] |
| Заголовок сообщения: | Re: Arduino RS485 управление двигателем и обратная связь. |
RS-485 - это интерфейс, а не протокол. Зачем столько сериалврайтов? Неужели нельзя передать по указателю на массив? Тайминги между отправкой и приёмом надо выдерживать? |
|
| Автор: | BOB51 [ Чт окт 21, 2021 13:45:15 ] |
| Заголовок сообщения: | Re: Arduino RS485 управление двигателем и обратная связь. |
Без корректной контрольной суммы ответа не будет. Блок обработки на моторе со своей "головой" - про ту cheksum должно быть где-то описано - иначе и с управлением не справится. Раз можете управлять - значит где-то уже расчет контрольного байта был (иначе и управление не пропустит). Напоминает вариации на тему интел хексов... При соответствующей скорости можно на ходу анализировать как в парсере бутлоадера котуинки... |
|
| Автор: | oleg110592 [ Чт окт 21, 2021 14:24:30 ] |
| Заголовок сообщения: | Re: Arduino RS485 управление двигателем и обратная связь. |
при управлении видно, какие то потуги с контрольной суммой проглядываются типа: Код: byte notchecksum = (0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0xA0+0x8C+0x00+0x00); ... Serial.write(0x8C); Serial.write(0x00); Serial.write(0x00); Serial.write(notchecksum); это просто сумма и похоже может быть > 255, может такое и прокатит |
|
| Автор: | BOB51 [ Чт окт 21, 2021 14:47:21 ] |
| Заголовок сообщения: | Re: Arduino RS485 управление двигателем и обратная связь. |
Может самый простой вариант - считается сумма всех байт, далее ее инверсия и +1 (дополнение до 2) как у интел хекса? Для каждой строки КС своя должна быть. |
|
| Автор: | anatoliydenisenko44 [ Чт окт 21, 2021 14:48:23 ] |
| Заголовок сообщения: | Re: Arduino RS485 управление двигателем и обратная связь. |
Для чтения state вы передаете команду из 5 байт. DATA[4] - контрольная сумма, как она вычислялась (0xDB)? Наверное без правильной контрольной суммы ответа не будет. Зачем массивы из одного элемента 16 бит? Код: uint8_t tem[1]; uint16_t volt[1]; uint16_t sp[1]; uint16_t enc[1]; Serial.read() принимает 1 байт (8 бит). После команды чтения state должно быть получено 13 байт. Сделать массив из 13 байт типа unsigned char rxbuf[13]; И принять можно типа так: Код: i = 0; while(Serial.available()>0){ rxbuf[i]=Serial.read(); i++; if(i >=13) break; } Потом разбирать байты на составляющие. з.ы. мог и ошибиться - надо проверять Спасибо буду пробовать, всегда решение где то на поверхности лежит. Сумму я считаю нормально, без сумм мотор бы не работал. там что в шапке сумма что в конце кадра. Может есть какие то материалы или книги по теме байтов битов, старших, младших. потому что я доолго мучался с передачей данных в мотор, так как делятся на старший и младший биты. |
|
| Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|




