Подключение конвертера RS-485 в TTL к Arduino
- Войдите на сайт для отправки комментариев
Доброго всем дня,
возникла задача передавать небольшое количество данных на расстояние до 50-70 метров. Решил организовать это с помощью RS-485 интерфейса. Не мудурствую лукаво повторил схему указанную ниже:
http://adatum.ru/podklyuchenie-konvertera-rs-485-v-ttl-k-arduino.html
Все хорошо, но принимаемый байт не соответсвует отправленному.
К примеру (отправка по байтно в HEX):
отправил: 0x01 получил: 0x7F
отправил: 0x01 0x02 0x03 получил: 0x7F 0xBF 0x00
отправил: 0x01 0x02 0x03 0x04 получил: 0x7F 0xBF 0xF7 0x00
отправил: 0x01 0x02 0x03 0x04 0x05 получил: 0x7F 0xBF 0xF7 0xF5 0x00
Результаты повторяемы: что на куске кабеля 20 см, что на бухте в 30 метров. При отправке одной о той же посылки, получаю в ответ один и тот же результат. Т.е. помех и наводок нет. Переписал программу для отправки одного байта - тот же самый результат, те же самые занчения.
Использкю я правда другу андруину: Mega2560, в качестве порта передачи/приема использую serial1.
Подскажите, в чем может быть ошибка.
Линии А и В не перекручены случайно....?
А к А подключено; В к B подключено, сами линии перекручены (использую типовую витую пару)
Если результаты повторяемы, то возникают сомнения в программной части. Покажите-ка скетчи передатчика и приёмника.
и приемник и передатчик - это терминальная программа на ПК.
Ардуино работает в качестве эхо. Прежде чем связывать две ардуины я решил проверить на всякий случай.
// Объявляем переменные и константы:
const uint8_t CONTROL_TX_RX = 10; // указываем номер вывода arduino, к которому подключены выводы RE и DE
byte test;
void setup()
{
pinMode(CONTROL_TX_RX, OUTPUT);
digitalWrite(CONTROL_TX_RX, LOW); // устанавливаем «0» - режим приёма данных
Serial1.begin(9600);
while (!Serial1) { } // ожидаем открытия порта
Serial1.println("Port_1 open");
}
void loop(){
if (Serial1.available()) {
test = Serial1.read();
delay(100);
digitalWrite(CONTROL_TX_RX, HIGH);
delay(100);
Serial1.write(test);
digitalWrite(CONTROL_TX_RX, LOW);
}
}
P.S. Похоже китайский модуль RS-485 дохлый. Я убираю один из проводов (RX/TX) между ардуиной и модулем, а в ответ получаю те же значения. Вопрос пока снимается, буду заказывать новые конверторы.
digitalWrite(CONTROL_TX_RX, HIGH);
delay(100);
Serial1.write(test);
digitalWrite(CONTROL_TX_RX, LOW);
Не совсем понятен сей текст.
Что бы не повторятся чиать тут: http://arduino.ru/forum/programmirovanie/modbus-rs485-gotovyi-shild#comm...
Что бы попробовать ЭХО1 байта попробовать поставить после Serial1.write(test); еще delay
И еще раз - по нормальному переключение на прием нужно делать после передачи последнего байта по флагу из соотвествующего регистра.
Вопрос решился, действительно был дохлый китайский модуль RS485, поэтому даже отправка одного байта не осуществлялась. Заменил, сейчас все просто летает в обе стороны между UNO и Mega.
И еще раз - по нормальному переключение на прием нужно делать после передачи последнего байта по флагу из соотвествующего регистра.
Не пошел по этому пути. Пакеты, которые передаются всегда одной длины, поэтому примерно посчитал на калькуляторе время отправки пакета, проверил все на практике и добавил delay() после передачи, но перед переключением из режима передачи в режим чтения, чтобы посылки уходили полностью.
Ещё учтите такой тонкий момент при работе с RS-485: допустим, мастер периодически шлёт в шину пакеты фиксированной длины. При этом слейв может включиться и начать слушать шину в произвольное время. Как следствие - слейв может начать получать данные не с начала пакета. Т.е. надо предусмотреть ситуацию, когда пакет вычитывался не сначала ;) Обычно для таких целей юзают заголовки пакета, по которым определяют его начало.
Передача данных потребовалась в рамках проекта "подводный телеуправляемый аппарат". Проект больше для души, чем для коммерции.
http://arduino.ru/forum/proekty/podvodnyi-teleupravlyaemyi-apparat
Еще месяц передача шла только от пульта управления к роботу. Поэтому одна из ардуин всегда слушала, вторая всегда только говорила.
Но в процессе реализации обнаружились некоторые особенности (к примеру разные значения мощности двух одинаковых регуляторов). для решения потребовалось вводить возможность калибровки прямо с пульта управления. Затем захотелось иметь понимание о своем положении под водой (глубина) и параметрах движения (эти пакеты уже идут в обратную сторону, от робота к пульту управления) И вот тут появилась необходимость двунаправленной отправки пакетов. И тут как раз столкнулся именно с тем, что написал многоуважаемый DIYMan.
Первым делом ввел заголовок пакета, который указывает только на начало пакета и байт идентификации пакета (передача данных управления моторами, передача калибровочных данных, передача телеметрии). Ну и чтобы было понимание, что получаем именно то, что нужно, заканчивается пакет контрольной суммой.
А чтобы разделить очередность передач и не связываться с какими-то серьезными протоколами я решил сделать следующее: приоритетным отправителем является пультр управления, он в нормальном режиме установлен в режим передачи. Но после передачи пакета он переключается в режим "слушать шину" на длительность в 2 длины пакета. Так же и подводная часть всегда в нормальном состоянии находится в режиме "слушать шину", но после приема пакета (и именно только в этот момент), если у нее есть что сказать, она переходит в режим передачи и отправляет данные к пульту управления.
Частота импульсов ESC регуляторов моторов 50 HZ, это 20 мсек. Скорость передачи данных 57600, длина посылки 20 байт. Т.е. время передачи одной посылки 3 мсек от пульта управления к роботу и потом 6 мсек слушает в ответ. По таймингу пролез, поэтому дальше рыть не стал.
Для управления подводным аппаратом передаете по RS485 только один байт? Или я не правильно вас понимаю.
Нет, в настоящее время передается три разных типа пакетов: 20 байт, 5 байт, 57 байт. Вопрос передачи по rs485 решился. Проблема была в usb-rs485 конвертере, пришел с Али дохлый.
Ранее пользовался этими модулями https://ru.aliexpress.com/item/FREE-SHIPPING-MAX485-module-RS485-module-TTL-turn-RS-485-module-MCU-development/32348768435.html?spm=2114.10010208.1000014.18.Df8zAV&scm=1007.13338.47322.0&pvid=5ddcc12a-3a8c-4f94-b535-3ecaf41acca0&tpp=1 , передавал данные с одной уно на другую уно. Скетчи не сохранились, какие использовал библиотеки точно не помню. Сейчас возникла снова необходимость передавать данные по RS485 c уно в нано. Попробовал как здесь https://www.youtube.com/watch?v=6pirdFDzWzA. Побайтно все передается. А как во второй части видео, три байта не получается. Сначала была ошибка при компиляции, исправил ошибку заменив файл ld.exe ide 1.6.4 на аналогичный из более старой ide 1.0.6. Пока не получилось передавать несколько байт. Как вы решили эту задачу?
железо использую абсолютно такое же. Никаких библиотек, использую физические порты
Вот пример передачи. 13 байт. Первый 0xAA - идентификатор пакета, последний CRC, 11 байт внути информационных
А вот прием этой же посылки на втором устройстве:
Если не ставлю delay(3), то поступающая посылка не успевает полностью заскочить в буфер порта
Спасибо.
Пример из видео тоже заработал со старой 1.0.6.
Я тоже раньше страдал фигней, придумывая свои протоколы для каждой новой железяки. А потом один раз написал библиотечку по MODBUS и получил кучу профитов. Не зря этот протокол есть промышленным стандартом по управлению удаленным оборудованием. Он и достаточно прост в реализации и расширяем по ходу развития проекта. Особенно мне понравилось, когда я связал по этому протоколу железку с LabView и нарисовал в этой проге пульт управления и индикации. Там и графики изменения параметров, и различный анализ, и автоматические команды понаделывал. Так что мой совет - уходите от велосипедов, пользуйтесь готовыми проверенными разработками.
Кстати тут получился готовый слейв:
http://arduino.ru/forum/programmirovanie/modbus-rs485-gotovyi-shild#comm...