Работа с RS485 на микросхеме sp3485

Densl
Offline
Зарегистрирован: 28.11.2018

Здравствуйте. Купил модуль sp3485 https://ru.aliexpress.com/item/32681306095.html?spm=a2g0s.9042311.0.0.557e33edUKbEUe, а он странно работает в полудуплексном режиме. Первое сообщение он как положено присылает, а дальше не работает. На осцилографе потом я вижу график разряжающегося конденсатора после конвертации. Попробовал подтянуть 1к резистором к земле и +3,3 в, но не помогло, все тоже самое. Самое интересное что в одну сторону работает всегда, а обратно только 1 раз. Библиотека работы с UART самописная, для 485 добавил только выставление сигнала RTS.

// Формирование и отправка посылки
void UART_Serial::prepareMessage1(uint8_t dev, uint8_t cmd, long data, uint8_t length1)
{
  digitalWrite(rts, HIGH);
  dtStrOut.dt.dev =dev;
  dtStrOut.dt.command = cmd;
  dtStrOut.dt.data = data;
  dtStrOut.dt.CRC = crc_calc(dtStrOut.b, length1);
  MySerial->write(dtStrOut.b, length1 + 1);
  delay(1);
  digitalWrite(rts, LOW);
}

RS485 соединяет 2 МК STM32. Куда копать в первую очередь?

b707
Онлайн
Зарегистрирован: 26.05.2017

думаю, что в первую очередь надо проверять свою "самописную библиотеку"

dosikus
Offline
Зарегистрирован: 11.03.2017

b707 пишет:

думаю, что в первую очередь надо проверять свою "самописную библиотеку"

 

И чисто на UART без RS485...

Densl
Offline
Зарегистрирован: 28.11.2018

b707 пишет:

думаю, что в первую очередь надо проверять свою "самописную библиотеку"


Проверять буду потом, когда с железом проблемы решу

Densl
Offline
Зарегистрирован: 28.11.2018

dosikus пишет:

b707 пишет:

думаю, что в первую очередь надо проверять свою "самописную библиотеку"

 

И чисто на UART без RS485...


На UARTе вообще-то все работает.

b707
Онлайн
Зарегистрирован: 26.05.2017

Densl пишет:
Проверять буду потом, когда с железом проблемы решу

железячник? - из тех, кому проще всю плату заново переразвести, чем одну строчку в коде поправить? :)

Откуда такая уверенность,  что проблемы именно в железе, а не в коде?

dosikus
Offline
Зарегистрирован: 11.03.2017

Вот с таким адаптером у меня нет ни каких проблем.

https://ru.aliexpress.com/item/33005036745.html?spm=a2g0o.productlist.0.0.708e7a8dqNOQVB&algo_pvid=edb4ffa4-766d-4830-bee7-c0d1201e983b&algo_expid=edb4ffa4-766d-4830-bee7-c0d1201e983b-0&btsid=2d6e58a5-5591-4197-94c7-a3f2fe0e91c8&ws_ab_test=searchweb0_0,searchweb201602_10,searchweb201603_55

 

Единственный но жЫрный минус, маркировка микросхем стерта.

 

Densl
Offline
Зарегистрирован: 28.11.2018

Ок, буду иметь ввиду. А до 2 Mbod разгоняется, не пробовали?

Densl
Offline
Зарегистрирован: 28.11.2018

b707 пишет:

Densl пишет:
Проверять буду потом, когда с железом проблемы решу

железячник? - из тех, кому проще всю плату заново переразвести, чем одну строчку в коде поправить? :)

Откуда такая уверенность,  что проблемы именно в железе, а не в коде?


Ну в коде нет утечек памяти, а с юартом тестировал, все работало.
Смотрел вчера на самом дешёвом китайском осциллографе, посылка идёт куда надо в итоге, но ничего не доходит. Как будто порт RX y STM самопроизвольно вчера отключился. Хотя ТХ работает все равно.

dosikus
Offline
Зарегистрирован: 11.03.2017

Densl пишет:
Ок, буду иметь ввиду. А до 2 Mbod разгоняется, не пробовали?

 

На модбас RTU не было надобности...

Densl
Offline
Зарегистрирован: 28.11.2018

Чего-то странные вещи какие-то. Снял я эти sp3485 и соеденил по UART Первое сообщение СТМка принимает отлично. А дальше чего хочешь делай ничего не видит, но на осциллографе видно что все приходит. Блин, то ли контроллер погорел, то ли программный косяк. На другом конце хорошо работает, поэтому сомневаюсь что прошивка такая.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Дак напиши простую как барабан отправку ( в которой точно не накосячишь) в твой стм, чтобы рх проверить

Densl
Offline
Зарегистрирован: 28.11.2018

В общем я догадался в чем проблема, тему можно закрыть. Походу нехватает копирующего конструктора. Два экземпляра класса типа serial влияют друг на друга.

b707
Онлайн
Зарегистрирован: 26.05.2017

я ж те говорил, что косячит твоя "самописная библиотека" - а ты не верил

FoxJone
Offline
Зарегистрирован: 19.04.2019

Просто после отправки  байтовой строки надо не сразу переключать 485 в режим приема, а подождать пока чип всю эту строку отправит.

Время ожидания: ориентировочно 1200 микросекунд на каждый отправленный байт.

Я это делал вот так:

  i = 0;
  if (Serial.available()) { //если по USB что то пришло
    digitalWrite(2, HIGH); // включаем передачу 485
    pause(5000); //ждем, пока все сообщение загрузится в буфер.
    while (Serial.available()) { //Пока саообщение не кончилось
        rec = Serial.read(); 
        Serial1.write(rec); //отправляет на 232
        Serial2.write(rec); //отправляет на 485
        i++;
      }
    pause(i*1200); //пауза для отправки по 485. Чем больше байт ушло, тем больше надо паузу.
    digitalWrite(2, LOW); // включаем прием 485
  }

 

dosikus
Offline
Зарегистрирован: 11.03.2017

FoxJone, это какая-то несоуразная ж.
У меня на F0 все сделано на DMA, и передача и прием.
Модбас рту...

FoxJone
Offline
Зарегистрирован: 19.04.2019

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

Что не отменяет того факта, что чип 485 не успевает отправить всю посылку, если резко переключить его на прием. Пауза нужна, проверенно экспериментально. Я в первый раз неделю убил на осознание этого факта. Что характерно, нигде в примерах этого нет, но там обычно и посылки в пару байт, максимум "хелло ворлд".

У вас эта пауза есть, но маленькая:  delay(1). Как раз несколько байт уходит и чип переключается на прием.

dosikus
Offline
Зарегистрирован: 11.03.2017

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

FoxJone
Offline
Зарегистрирован: 19.04.2019

Так таки ни одного делая? А в строке 9 что?

Densl пишет:
// Формирование и отправка посылки

void UART_Serial::prepareMessage1(uint8_t dev, uint8_t cmd, long data, uint8_t length1)
{
  digitalWrite(rts, HIGH);
  dtStrOut.dt.dev =dev;
  dtStrOut.dt.command = cmd;
  dtStrOut.dt.data = data;
  dtStrOut.dt.CRC = crc_calc(dtStrOut.b, length1);
  MySerial->write(dtStrOut.b, length1 + 1);
  delay(1);
  digitalWrite(rts, LOW);
}

dosikus
Offline
Зарегистрирован: 11.03.2017

Вы меня с ТС не путайте, ок.
Я подобную ересь в проект ну никак не впихну, в моих реалиях аурдунья табу.
Знаете , простой сишечкой живем...

b707
Онлайн
Зарегистрирован: 26.05.2017

FoxJone пишет:

Так таки ни одного делая? А в строке 9 что?

Densl пишет:
//

FoxJone - у вас прямо в цитировании написано. что это код Densl А отвечаете вы коиу?

 

nik182
Offline
Зарегистрирован: 04.05.2015

https://habr.com/ru/post/279747/ Здесь описана эта ситуация. Я тоже долго бился с RS485. По 232 работало, по 485 нет. Я поставил задержку на переключение на приём. Задержка равна времени передачи одного символа на скорости 115200. Когда разбирался, оказалась что STMка выставляет флаг буфер пуст после передачи символа в аппаратный буфер передачи, а не после полной отправки, а это единственная возможность аппаратно контролировать окончание процесса отправки буфера модбас. 

b707
Онлайн
Зарегистрирован: 26.05.2017

я подозреваю, что микросземы интерфейса rs485 в модулях у ТС и в модуле, на который ссылается dosikus - разные. На sp3485 полудуплекс и его нужно переключать снаружи. В том что у dosikis вполне может быть аппаратный выбор приема-передачи - какая там микруха ведь неизвестно

nik182 - в вашей ссылке на Хабр тоже не ясно на чем постоен интерфейс. Похоже что-то другое, потому что там скорость 115200, а  в даташите sp3485 я что-то выбора скорости не вижу.

 

FoxJone
Offline
Зарегистрирован: 19.04.2019

С телефона легко ники спутать, ошибся.
Думал с ТС общаюсь. И таки да, обычные мах485 или адм485, которые я в свои платы запаиваю, требуют внешнего управления и пауза после отправки нужна, я настаиваю.

nik182
Offline
Зарегистрирован: 04.05.2015

Скорость зависит от того сколько сам поставишь. Это только конвертер. Я когда с модбасом  развлекался на максимум STMки разгонял. На коротких расстояниях работало через 485. У меня сейчас 25 метров витой пары на установке стоит. Максимум 115200. Если больше начинает глючить.  

sadman41
Offline
Зарегистрирован: 19.10.2016

Мозгов нет у людей, а виновата, как всегда, ардуина...

dosikus
Offline
Зарегистрирован: 11.03.2017

nik182, что бы тебе не надумалось вновь какой либо хрени.
Специально для тебя - в F0 аппаратная поддержка модбас рту , в частности контроль окончания транзакции мастера.
Хабр считаю абсолютным г. и не надо ссылаться на него как на аксиому.

b707
Онлайн
Зарегистрирован: 26.05.2017

dosikus пишет:
в F0 аппаратная поддержка модбас рту , в частности контроль окончания транзакции мастера.

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

Какого фига намеренно дурить ТС голову, что мол "задержка не нужна" ? Похвастать, что используете СТМ с ДМА и покрасоваться перед "лохами"?

dosikus
Offline
Зарегистрирован: 11.03.2017

А нука голосарь , обьясни мне чем то что я описываю отличается от полудуплексного режима применительно к модбас рту? Где по протоколу определен конец транзакции именно паузой?
Открой мануал на F0 и узрей об аппаратной поддерже модбас рту и ASCII супротив ваших кривых делаев.

nik182
Offline
Зарегистрирован: 04.05.2015

Давай ты не будешь додумывать за других? Где я сказал что ссылаюсь как аксиому? Я привел пример, что человеку пришлось ставить задержку, что бы модбас с 485 заработал. Поддержка F0 есть, но только на уровне пакета. И даже это хорошо. Вот только у меня нет ни одного F0.   

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Переключать на приём надо по окончании физической передачи последовательного канала. А как вы это сделаете - ваша задача. Это делается довольно просто даже под ардуиновский сериалпорт. Без блокировки.

dosikus
Offline
Зарегистрирован: 11.03.2017

В остальных есть таймеры и IDLE и опять таки каноны протокола а не делаи.
Думай, думай...

b707
Онлайн
Зарегистрирован: 26.05.2017

dosikus пишет:
Где по протоколу определен конец транзакции именно паузой?

пауза нужна не для этого. Обьясняю для "не-ардуинщиков"

Ты положил в буфер Сериал N символов для передачи. Сериал работает не блокирующе, программа пошла дальше. И ты тут же включаешь прием. Но символы то из буфера еще не отправились!

так что пауза - вещь нужная. И длительность ее FoxJone рассчитал весьма похоже для скорости в 9600

dosikus
Offline
Зарегистрирован: 11.03.2017

"Твой софт дерьмо" (c)...
Даже если у ТС не F0 , это элементарно делается на дма.
Если для аурдуньи это проблема, надо что-то менять в этой консерватории...
Думать как авр, это диагноз...

FoxJone
Offline
Зарегистрирован: 19.04.2019

Коллега, а вы ничего не путаете? Модбас - это всего лишь протокол. Порядок байт в сообщении, грубо говоря.
И пересылаются эти байты по линии связи. По двум проводам, в данном случае. И если эти байты не дошли до приемника (а они не дойдут, если вы это не проконтролируете), то хоть какой у вас распрекрасный код, он это сообщение не прочитает.
И большинство бюджетных чипов 485 требуется контролировать.

b707, точно, подбирал экспериментально как раз на 9600. Подбтрал еще на 115200, но ее не помню на память.

dosikus
Offline
Зарегистрирован: 11.03.2017

FoxJone, вам прочитать вслух мануал на модбас?
Читаю вслух, дорого.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Намекну, Serial.availableForWrite(), или как-то так. Проверяем на HARDWARE_SERIAL_BUFFER - 1 (или как-то так) и понимаем, что последний байт ушёл в сдвиговый регистр. Далее, ждём длительность байта (с помощью micros()), возможно ещё 3.5 байта, если Modbus, и вуаля, можно переходить на приём.

nik182
Offline
Зарегистрирован: 04.05.2015

dosikus пишет:
А нука голосарь , обьясни мне чем то что я описываю отличается от полудуплексного режима применительно к модбас рту? Где по протоколу определен конец транзакции именно паузой? Открой мануал на F0 и узрей об аппаратной поддерже модбас рту и ASCII супротив ваших кривых делаев.

Перечитай #21. Это проблема  UART STM. Нет у него никаких аппаратных признаков окончания передачи. Поэтому нужна задержка. Мы тут на BLUEPILL сидим, а он на 103, аппаратной поддержки модбаса неимеет и модули 485 с внешним управлением используем. Не продвинутые мы. 

 

b707
Онлайн
Зарегистрирован: 26.05.2017

dosikus пишет:
"Твой софт дерьмо" (c)... Даже если у ТС не F0 , это элементарно делается на дма. Если для аурдуньи это проблема, надо что-то менять в этой консерватории... Думать как авр, это диагноз...

да понятно, что это можно на ДМА сделать. Асинхронный ДМА с прерыванием по окончанию и в Ардуино можно сделать.

Только ТС спрашивал совсем не об этом

 

sadman41
Offline
Зарегистрирован: 19.10.2016

"Я - Д'Артаньян, а остальные..." - основной лозунг местных стм-фанатиков.

dosikus
Offline
Зарегистрирован: 11.03.2017

Schwarz78, мы же все таки на стм , не так ли?
Со стороны мастера:
Кинули в буфер. Пнули дма , в прерывании по полной транзакции выставили флаг отправки.
Переключились на прием.( С новыми драйверами не надо)
Со стороны слейва.
Не F0 .
Заряжается дма на максимальный размер буфера .
Однако после приема каждого байта запускается таймер на определение конца фрейма.
С F0 также заряжается дма и прерывание по паузе.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Хоть один понял Досика? Принимать можно только окончив передачу. Эта детская ошибка вылезает всегда, вот просто всегда.

dosikus
Offline
Зарегистрирован: 11.03.2017

b707, вы наконец то стали слушать тс?
Я его раньше услышал. И дал дельный совет
А теперь посмотри кто стал, не слушая ТС гнуть пальцы, уводя разговор в дебри.

FoxJone
Offline
Зарегистрирован: 19.04.2019

Schwarz78 пишет:

Намекну, Serial.availableForWrite(), или как-то так. Проверяем на HARDWARE_SERIAL_BUFFER - 1 (или как-то так) и понимаем, что последний байт ушёл в сдвиговый регистр. Далее, ждём длительность байта (с помощью micros()), возможно ещё 3.5 байта, если Modbus, и вуаля, можно переходить на приём.

Ну так а я про что рассказываю весь топик? Надо ждать! И именно через микрос. Единственный делай (от которого так бомбит у стмщиков) в этом топике у ТС в стартпосте.

dosikus
Offline
Зарегистрирован: 11.03.2017

Schwarz78 пишет:

Хоть один понял Досика? Принимать можно только окончив передачу. Эта детская ошибка вылезает всегда, вот просто всегда.


Марш читать мануал.

dosikus
Offline
Зарегистрирован: 11.03.2017

FoxJone, если нужно действительно осознание а не срач, могу помочь.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

dosikus пишет:
Schwarz78, мы же все таки на стм , не так ли? Со стороны мастера: Кинули в буфер. Пнули дма , в прерывании по полной транзакции выставили флаг отправки. Переключились на прием.( С новыми драйверами не надо) Со стороны слейва. Не F0 . Заряжается дма на максимальный размер буфера . Однако после приема каждого байта запускается таймер на определение конца фрейма. С F0 также заряжается дма и прерывание по паузе.

Да какая разница на чём мы? Физический принцип один. Даже на 1816ВЕ31 приходилось дожидаться конца передачи, хоть тресни.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

dosikus пишет:
Schwarz78 пишет:

Хоть один понял Досика? Принимать можно только окончив передачу. Эта детская ошибка вылезает всегда, вот просто всегда.

Марш читать мануал.

На микросхему sp3485? Сам иди.

b707
Онлайн
Зарегистрирован: 26.05.2017

dosikus пишет:
b707, вы наконец то стали слушать тс? Я его раньше услышал. И дал дельный совет А теперь посмотри кто стал, не слушая ТС гнуть пальцы, уводя разговор в дебри.

совет взять другой модуль или переписать все на ДМА - уж слишком "дельный", на уровне лечения мигрени гильотиной. Думаю, добавить задержку ТС будет проще. 

Согласен, что на ДМА все делается, хотя задержки все равно нужны. Оттого, что задержка отрабатывается асинхронно по прерыванию - суть не меняется

dosikus
Offline
Зарегистрирован: 11.03.2017

Дожидаться можно по разному.
Или по дебильному ждать окончания делай, либо в конечном автомате проверять флаг.
И здесь заканчиваются страдания обсасывателей миллис и начинается вменяемый кодинг.

dosikus
Offline
Зарегистрирован: 11.03.2017

Schwarz78 пишет:

dosikus пишет:
Schwarz78 пишет:

Хоть один понял Досика? Принимать можно только окончив передачу. Эта детская ошибка вылезает всегда, вот просто всегда.

Марш читать мануал.

На микросхему sp3485? Сам иди.


На протокол модбас.