Проблемы с SoftwareSerial

akas
Offline
Зарегистрирован: 16.03.2021

Запускаю простейший код на Arduino Mini Pro Atmega168 3.3V 8мГц (в IDE все это настроил), смотрю монитор порта. Часть символов "теряется", в терминале периодически вылезает то "sleestart", то "tart" и текст появляется с задержками посреди строк, заметно на глаз.
Если закомментировать запись в SoftwareSerial в (строка 12  HC12.write(1)) то работает нормально, строки "start" и  "sleep" появляются "мгновенно".
В чем может быть дело? Может не следует SoftwareSerial на 7 8 пины делать?

#include <SoftwareSerial.h>
#define HC12RX 7
#define HC12TX 8
SoftwareSerial HC12(HC12TX, HC12RX);
void setup(){
  Serial.begin(9600);
  Serial.println("setup");
  HC12.begin(9600);
}
void loop(){
    Serial.println("start");
    HC12.write(1);
    Serial.println("sleep");
    delay(1000);
}    

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Дожидайтесь завершения вывода в Serial, прежде, чем начинать выводить в SoftwareSerial. Для этого (дождаться завершения) там есть метод flush()

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Дожидайтесь завершения вывода в Serial, прежде, чем начинать выводить в SoftwareSerial. Для этого (дождаться завершения) там есть метод flush()

  а может, дополнительно, надо выбрать пины, что бы посадить софтовый сериал на один обработчик, D6 D7 к примеру, а не как сейчас?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Что значит на один обработчик? Там один и есть. На прерывании сидит только Rx (стартовый бит прерыванием ловится). Tx - тупо фигачит делеями - посмотрите текст библиотеки.

Upper
Offline
Зарегистрирован: 23.06.2020

По моему, сама команда HC12.write(1); не должна приводить к заметным глазу задержкам и потерям символов в приведенной программе.

Если на эту команду HC12.write(1) следует довольно длинный ответ, тогда может быть.

Проверить можно физически отключив провода от HC12.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Upper пишет:

сама команда HC12.write(1); не должна приводить к заметным глазу задержкам и потерям символов 

Ещё как может - она же закрывает прерывания и отправляет байт. Т.е. на время отправки одного байта аппаратный сериал не работает. Это и есть потеря символа (а может и двух, если эта отправка на границу между ними наложится)

Upper пишет:

Если на эту команду HC12.write(1) следует довольно длинный ответ

Какой ответ? Даже если какой-то и есть - в приведённом коде его никто не читает. А на саму по себе команду write какие могут быть ответы - она ногой Tx подрыгала и успокоилась - плевать ей на всё.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

всё одно не понятно, USART хардовый, загнали в буфер байты, дальше он должен самостоятельно работать, на уровне контроллера USART, не так ли?

Upper
Offline
Зарегистрирован: 23.06.2020

ЕвгенийП пишет:

Т.е. на время отправки одного байта аппаратный сериал не работает. Это и есть потеря символа (а может и двух, если эта отправка на границу между ними наложится)

Какой ответ? Даже если какой-то и есть - в приведённом коде его никто не читает. А на саму по себе команду write какие могут быть ответы - она ногой Tx подрыгала и успокоилась - плевать ей на всё.

Аппаратный сериал работает всегда. Может быть задержка с загрузкой следующего символа, но глазу она будет не заметна.

Какой может быть ответ я не знаю, но если устройство пошлет в ответ 100500 байт информации, то не важно читаем мы или нет, прерывание по приему будет часто блокировать остальные прерывания.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

всё одно не понятно, USART хардовый, загнали в буфер байты, дальше он должен самостоятельно работать, на уровне контроллера USART, не так ли?

Нет, не так. На уровня контроллера отправляется 1 байт. А отправить следующий - это уже ручками.

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

А ежели вместо write сделать cli, delayMicroseconds() и sei, то тоже теряться символы будут?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Попробуйте

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:

всё одно не понятно, USART хардовый, загнали в буфер байты, дальше он должен самостоятельно работать, на уровне контроллера USART, не так ли?

Нет, не так. На уровня контроллера отправляется 1 байт. А отправить следующий - это уже ручками.

аппаратного буфера в 328 нету?

Green
Offline
Зарегистрирован: 01.10.2015

На передачу 1, на приём 2 байта.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Green пишет:

На передачу 1, на приём 2 байта.

не густо, могли бы и увеличить, хотя бы до 16 байт

akas
Offline
Зарегистрирован: 16.03.2021

ЕвгенийП пишет:
Для этого (дождаться завершения) там есть метод flush()
Спасибо! Seral.flush() обязательно попробую.
Если можно, еще пару вопросов, чтобы разобраться.
Для SoftwareSerisal тоже надо после записи  flush() делать?
Или flush() нужен только когда отправляется более байта?
С проверкой типа if(Serisal.availableForWrite()) Serial.write('A'); тоже после write делать flush ?

Прошу прощения за дурацкие вопросы. Документация не очень внятная, а исходники с регистрами прерываниями я пока не научился читать. 
Upper
Offline
Зарегистрирован: 23.06.2020

Скорее всего у вас идут наводки, т.к. как писал ранее, потери символов при данной программе быть не должно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

akas пишет:

Для SoftwareSerisal тоже надо после записи  flush() делать?

Нет. Там отправка блокирующая, поэтому flush просто не имеет смысла. Хотя, если хотите, поставьте - хуже не будет. Лучше - тоже. Он там вот такой (если Вы не поленитесь в библиотеку заглянуть):

void SoftwareSerial::flush()
{
  // There is no tx buffering, simply return
}

 

akas
Offline
Зарегистрирован: 16.03.2021

Разобрался наконец, жалко столько времени убил. Похоже это глючный USB-UART преобразователь.
Синяя платка с надписью HW-199, у продавца сказано CP2102, недавно купил. Вроде работала и прошивала,  глючила редко, думал что просто контакты, оказалось не только.
Запустил dmesg (Ubuntu), там непрерывно сыплется "cp210x ttyUSB0: failed get req 0x8 size 1 status: -71"
Раскопал потерявшийся USB-UART от "амперки", все заработало стабильно как надо, ошибок в dmesg нет.
Спасибо за помощь, извините, что время отнял, надо было мне сразу dmesg посмотреть.