Чтение-запись SoftwareSerial mySerial

Misha2066
Offline
Зарегистрирован: 18.09.2018

Да, собираюсь. Вход из SoftwareSerial, выход TVout. Думаете не получится?

Misha2066
Offline
Зарегистрирован: 18.09.2018

sadman41 пишет:

А из реальной жизни несколько пакетов как выглядят? Какой-то хидер у них есть общий?

Все пакеты выглядят как я показал, меняются числа внутри пакета, всего 12 цифр, но каждое число всегда на своем месте и принимает определенные значения. Первая цифра всегда "0", но и другие тоже могут быть равны  "0", в зависимости от положения органов управления. Также числа могут быть одинаковыми, т.е. кроме самого числа необходимо знать его место в пачке. Например, на 4-м месте температура слева, на 5-м справа, числа на 2-м и 10-м месте определяют скорость вентилятора.

А вот как определить это "место" в котором находится нужное число?

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

Вы бы лучше оперу не перепевали... Просто потыкайте в свой девайс, дамп с шины покажите. 

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

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

 

Misha2066
Offline
Зарегистрирован: 18.09.2018

sadman41 пишет:

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

Длительность паузы ~ 13 мс, что приблизительно 125 (или около того) нолей при скорости 9600 бод, длительность посылки ~ 7,5 мс. Если в посылке 12 чисел, то получается каждое число из 6 знаков.

Misha2066
Offline
Зарегистрирован: 18.09.2018

sadman41 пишет:

дамп с шины покажите. 

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

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

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

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

Misha2066 пишет:

sadman41 пишет:

дамп с шины покажите. 

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

Это и есть дамп. 

Возможно, что пакет всегда начинается с... например 0x00 0x12 0xFF  - тогда надо эту последовательность и ловить

Misha2066
Offline
Зарегистрирован: 18.09.2018

Длительность паузы ~ 13 мс, что приблизительно 128 (или около того) бит при скорости 9600 бод, длительность информационной посылки ~ 7,5 мс. 

Одна посылка так и есть ~ 100 мкс (в литературе 104 для скорости 9600).

Misha2066
Offline
Зарегистрирован: 18.09.2018

sadman41 пишет:

Это и есть дамп. 

Возможно, что пакет всегда начинается с... например 0x00 0x12 0xFF  - тогда надо эту последовательность и ловить

Спасибо!

Пакет начинается с нулей, например 128 нулей. Подскажите, как это число в скетч записать с оператором "if"? 

А потом как определять позицию каждого из других чисел?

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

Странное начало. Как тогда удаленной системе отличить первый нуль в "0 1 A0 28 28 14 4E 5A A1 19 3 C" от предшествующих? Или этот нуль не меняется в посылке из 12 байт и всегда нуль? Для того, чтобы система проснулась - должен быть какой-то "перепад", как мне представляется. Она же может начать слушать с середины префикса и тогда не отсчитает 128 нулей. 

Я бы действовал так: начал считать нули в переменную. Если нуль, то +1, не нуль - смотрим на счетчик. Счетчик больше длины пакета в 12 символов - значит начался новый пакет, ставим перевод строки. После того, как поймали не нуль - счетчик сбрасываем (т.е. находимся внутри пакета и делать ничего не надо).

 

Misha2066
Offline
Зарегистрирован: 18.09.2018

sadman41 пишет:

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

Вообще-то это единица, если четко следовать стандарту uart, а страртовый нуль. Я выше привел осциллограмму сигнала, перед посылкой идет высокий уровень, потом уже сообщение которое начинается с "0", потом снова высокий уровень перед сообщением, и так по кругу пока не выключишь. Все как в учебнике https://ru.wikipedia.org/wiki/Универсальный_асинхронный_приёмопередатчик

Как разделить сообщение по байтам?

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

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

По байтам делить ничего не надо. Serial.read() уже дает ровно один байт.

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

не претендую чтобы работало, ибо на коленке


#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

bool     pausetimerON = 0;
uint32_t prevmillis = 0;

byte findheader = 0; 

#define MESSAGE_SIZE 11   //длина сообщения без учета ноля

void setup() {
  Serial.begin (9600);
  mySerial.begin(9600);
 
}

void loop() { 

uint32_t currenttime = millis();          //снимок текущего времени

if (digitalRead(10) && !pausetimerON) {pausetimerON = 1; prevmillis = currenttime;} // если высокий уровень на шине, включаем таймер
else pausetimerON = 0;                                             // иначе выключаем таймер

// если таймер был включен и кончился, значит нашли заголовок, таймер выключаем
if (pausetimerON && (currenttime - prevmillis>=12) && (currenttime - prevmillis<=14)){findheader = 1; pausetimerON = 0;}

//проверяем чтобы первый байт был ноль
if (mySerial.available() && findheader == 1) {if (mySerial.read()==0x00) findheader = 2;}

//ниже принимаем все байты сообщения
if (findheader == 2 && mySerial.available())
{
  delay (2);
  byte RXmessage[MESSAGE_SIZE] = {0};
 for (byte i = 0; i<MESSAGE_SIZE; i++) 
        {
          RXmessage[i] = mySerial.read(); 
         delay (2); 
         Serial.print(RXmessage[i],HEX); Serial.print (" ");
        }
  Serial.println();
  findheader = 0; // в конце сбрасывая флаг найденного заголовка
}

  
}

 

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

Интересно, а если ISR по RISING перехватывать - это снесет башку софтсериалу? А так было бы просто - запомнил, когда обработчик дернулся, а потом, когда байты появились в буфере - просто прошедшее время глянул и усе.

Misha2066
Offline
Зарегистрирован: 18.09.2018

Спасибо! Буду пробовать, что получится напишу!

Misha2066
Offline
Зарегистрирован: 18.09.2018

Неожиданная командировка внесла некоторую задержку в реализацию планов. Однако продолжаем наши эксперименты.

Скетч уважаемого MaksVV, не работает, в мониторе тишина. Но, если добавить такие куски кода 

unsigned char buf;

и

 while (mySerial.available())
    buf = mySerial.read();
    if (buf == 41) Serial.println("20,5 градусов");

то при установке температуры 20,5 градуса, начинает бесконечно выводить "20,5 градусов". Это конечно хорошо, но такое же значение есть когда скорость вентилятора равна 4 деления, т.е. надо еще разделить числа по положению в пакете.

Misha2066
Offline
Зарегистрирован: 18.09.2018

Может можно сделать так, например, при установившемся значении сообщения никакой информации не выводится, а при изменении, выводится только то число/числа, которые изменились?

Misha2066
Offline
Зарегистрирован: 18.09.2018

Думаю надо как-то String использовать.

Logik
Offline
Зарегистрирован: 05.08.2014

Misha2066 пишет:

Да, собираюсь. Вход из SoftwareSerial, выход TVout. Думаете не получится?

Ниче не выйдет. Оба жестко требуют верного формирования временных интервалов и будут конфликтовать. Разве что разнести их типа пока обмен по SoftwareSerial не работает TVout и наоборот. Но сомниваюсь что такое устроит кого. Там даже с железным сириалом не просто.

Misha2066
Offline
Зарегистрирован: 18.09.2018

Logik пишет:

Разве что разнести их типа пока обмен по SoftwareSerial не работает TVout и наоборот. 

Это как раз таки не плохо. Мне не нужно чтобы TVout постоянно что-то выдавал, достаточно нарисовать картинку на 3-5 сек. при изменении положений органов управления. Этого достаточно.

Logik
Offline
Зарегистрирован: 05.08.2014

О чем вы, какие 3-5сек! На видеовыход необходимо постоянно выводить сигналы синхронизации и изображения, строчная развертка, по памяти - 15КГц, т.е. каждые 60мксек импульс синхронизации, а между ними собственно строку изображения. Прозевали, не вывели - картинка на экране исказилась. Вобщем читайте - https://ru.wikipedia.org/wiki/Видеосигнал Пока контролер генерит эту лабуду он не может прерватся на софтсириал, значить потеряет инфу. А если прервется - пропустит время генерации сигнала. Это и есть конфликт.

Misha2066
Offline
Зарегистрирован: 18.09.2018

Logik!

Чё так нервничать? Никто никуда не торопится. В том "проекте", что я пытаюсь сделать, по софтсериальному входу постоянно циклически идет информация в пакетах чисел, и если один пакет потеряется, ничего страшного не произойдет. То же самое и с видео выходом. Нужно выводить изображение не постоянно, а на короткое время, в момент, когда в пакете изменилось какое-то число/несколько чисел. 

А про видеосигнал я вам могу такую лекцию прочесть, ваша педивикия отдыхает.

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

Misha2066 пишет:

Скетч уважаемого MaksVV, не работает, в мониторе тишина.

На будущее, если скетч не работает как надо, нужно хоть немного приложить усилия для выявления причины некорректной работы. Например, вставкой в различные части кода Serial.print, чтобы узнать "заходит" ли сюда программа. Так можно проверить выполняются ли ифы. 

В вашем случае, возможно пауза не 13мс, поэтому он её не детектирует. (может нужно диапазон значений паузы подрегулировать). Вставил сюда вывод в терминал, обнаруживает ли паузу.

Также после паузы может НЕ ноль в терминал идёт и т.д. 

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

bool     pausetimerON = 0;
uint32_t prevmillis = 0;

byte findheader = 0; 

#define MESSAGE_SIZE 11   //длина сообщения без учета ноля

void setup() {
  Serial.begin (9600);
  mySerial.begin(9600);
 
}

void loop() { 

uint32_t currenttime = millis();          //снимок текущего времени

if (digitalRead(10) && !pausetimerON) {pausetimerON = 1; prevmillis = currenttime;} // если высокий уровень на шине, включаем таймер
if (!digitalRead(10)) pausetimerON = 0;                                             // иначе выключаем таймер

// если таймер был включен и кончился, значит нашли заголовок, таймер выключаем
if (pausetimerON && (currenttime - prevmillis>=12) && (currenttime - prevmillis<=14)){findheader = 1; pausetimerON = 0; Serial.println ("Pause is detected!!!");}

//проверяем чтобы первый байт был ноль
//if (mySerial.available() && findheader == 1) {if (mySerial.read()==0x00) findheader = 2;}

//ниже принимаем все байты сообщения
//if (findheader == 2 && mySerial.available()) 
  if (findheader != 0 && mySerial.available())    // здесь мы не обращаем внимания на первый байт , может он не ноль 
{
  delay (2);
  byte RXmessage[MESSAGE_SIZE] = {0};
 for (byte i = 0; i<MESSAGE_SIZE; i++) 
        {
          RXmessage[i] = mySerial.read(); 
         delay (2); 
         Serial.print(RXmessage[i],HEX); Serial.print (" ");
        }
  Serial.println();
  findheader = 0; // в конце сбрасывая флаг найденного заголовка
}

  
}

 

Misha2066
Offline
Зарегистрирован: 18.09.2018

Принято! Учту. Спасибо за помощь, просто это мой первый опыт...

Logik
Offline
Зарегистрирован: 05.08.2014

Misha2066 пишет:

Logik!

Чё так нервничать? Никто никуда не торопится. В том "проекте", что я пытаюсь сделать, по софтсериальному входу постоянно циклически идет информация в пакетах чисел, и если один пакет потеряется, ничего страшного не произойдет. То же самое и с видео выходом. Нужно выводить изображение не постоянно, а на короткое время, в момент, когда в пакете изменилось какое-то число/несколько чисел. 

А про видеосигнал я вам могу такую лекцию прочесть, ваша педивикия отдыхает.

Понял, продолжайте, успеха ;) 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Misha2066 пишет:

А про видеосигнал я вам могу такую лекцию прочесть, ваша педивикия отдыхает.

Это замечательно!

Не будете ли столь любезны, чтобы ответить на вопросы:

1. Что показывает телевизор в отсутствие видеосигнала?

2. Через какое время (или через сколько кадров) после появления видеосигнала на телевизоре появится изображение?

Misha2066
Offline
Зарегистрирован: 18.09.2018

andriano пишет:

Не будете ли столь любезны

Не буду. Ваши вопросы к теме ветки форума не имеют ни какого отношения. Хватит флудить.

Misha2066
Offline
Зарегистрирован: 18.09.2018

Logik пишет:

Понял, продолжайте, успеха ;) 

Конечно продолжу и всё что задумал сделаю. Ваш сарказм не понятен, такое впечатление, что некоторые из здешних завсегдатаев сразу умными родились. 

Logik
Offline
Зарегистрирован: 05.08.2014

Не сразу, но койчего кумекаем. Иногда других слушали, иногда ручками ковыряли и учились. Вы не желаете понять что пишут вам другие - ну ковыряйте. Умнейте практическим путем. Бум считать о неявных особенностях TVout и софтсириала вы в курсе, о их взаимодействии проинформированы. Дерзайте, чё еще сказать.

Misha2066
Offline
Зарегистрирован: 18.09.2018

andriano пишет:

ответить на вопросы:

1. Что показывает телевизор в отсутствие видеосигнала?

2. Через какое время (или через сколько кадров) после появления видеосигнала на телевизоре появится изображение?

Кстати, большинство ответов на ваши вопросы (практически на все) в ссылке на Википедию у вашего товарища Logikа в посте http://arduino.ru/forum/programmirovanie/chtenie-zapis-softwareserial-myserial?page=2#comment-400961

читайте Википедию и учитесь у гуру программирования.

Misha2066
Offline
Зарегистрирован: 18.09.2018

Logik пишет:

Иногда других слушали, иногда ручками ковыряли и учились. Вы не желаете понять что пишут вам другие 

Вы пишите нормально, без подъ...к и все будет понятно. А так конечно, кто может и хочет помочь, тот помогает, а кто так, поумничать, того и понимать нет желания. 

На данный момент у меня не стоит проблема с выводом ТВ сигнала, она решаема в принципе, если не на одной плате Ардуины, то на двух. Я сейчас хочу разделить полученный пакет uart на составные части. В этом вопросе от вас лично помощи нет, что я еще должен понять?

Logik
Offline
Зарегистрирован: 05.08.2014

Вы реально считаете что о проекте, в котором изображение на экране присутствует пару секунд, затем картинка исчезает идут шумы, и/или синий экран, и/или надпись "нет сигнала", а затем через полсекунды-секунду снова картинка выводится можна без подъ...к? Это проект по борьбе с эпилептиками?

Решаемо "в принципе" - так это человек на Марсе и термоядерный синтез и мир во всем мире с полным комунизмом решаемо. В принципе. Гадости в мелочах.

Logik
Offline
Зарегистрирован: 05.08.2014

Я бы, если бы судьба меня так прикрутила, что и TVout и софтсириала, смотрел бы в сторону реализации приема уарта на основе тактовых импульсов таймера из TVout. Недостатки - скорост низкая, перепахать кучу кода из либ, собсвенно софтсириал самому писать. Преимущества - ну даже не знаю, наверно железо проще. Я бы забил на такое, проще железный сириал  "найти" .

Misha2066
Offline
Зарегистрирован: 18.09.2018

Вы или не внимательно читали, что я писал раньше, или одно из двух. Я хочу вывести параметры климат-контроля авто вместо штатного монохромного дисплея на экран Андроид-ГУ. На экране Андроида постоянно есть картинка -- навигация, или радио, или музыка, или еще какое-то порно, показания климата (температура, скорость вентилятора, заслонки, etc.) постоянно там не нужны. Достаточно всплывающей или кратковременно появляющейся картинки в момент изменений параметров. Например захотелось потеплее, увеличил температуру, появился экран климата, постоял несколько секунд и переключился на основной экран.

Misha2066
Offline
Зарегистрирован: 18.09.2018

Logik пишет:

и TVout и софтсириал

Я же написал, одновременно и очень быстро не нужно. Что мешает принимать и расшифровывать uart на одной Ардуине и передавать в другую Ардуину (а может и в Raspberry, если Ардуина не справляется или захочется красивую картинку), в которой будет генериться ТВ картинка?

Misha2066
Offline
Зарегистрирован: 18.09.2018

andriano пишет:

А Вы всерьез полагаете, что все рождаются дураками?

Вы внимательно ознакомились с ссылкой на Вики, что я вам посоветовал? Прочитайте еще раз и заканчивайте флудить не по теме.

Logik
Offline
Зарегистрирован: 05.08.2014

Misha2066 пишет:

Logik пишет:

и TVout и софтсириал

Я же написал, одновременно и очень быстро не нужно. Что мешает принимать и расшифровывать uart на одной Ардуине и передавать в другую Ардуину (а может и в Raspberry, если Ардуина не справляется или захочется красивую картинку), в которой будет генериться ТВ картинка?

Неопределенность и подробности мешают. Хотяб определится нужно Raspberry или Ардуина (какая именно Ардуина кстати). У Raspberry и сириалов железных больше и видеовыход родной и плюшек в софт еще пол жизни добавлять можна будет. Может сразу на неё перепрыгнуть и закрыть эту тему ?)))

У построение системы на нескольких контрлллера - свой набор гадостей. 

Misha2066
Offline
Зарегистрирован: 18.09.2018

Logik пишет:

Хотяб определится нужно Raspberry или Ардуина 

Для начала Ардуина. У меня есть Мега и на днях придут еще две заказанные Мини. Для понимания процесса думаю начать с малого. А дальше развитие как получится.

Misha100500
Offline
Зарегистрирован: 01.11.2018

И снова здравствуйте! Раньше я сюда заходил под ником Misha2066, но честно не знаю почему, меня какой-то нехороший человек забанил. Ну да черт с ним с этим человеком! Спасибо интернетам это не единственный и прямо скажем далеко не лучший ресурс по теме Ардуино, скорее всего благодаря вот таким нехорошим людям. К счастью в интернетах есть достаточно нормальных, адекватных людей, с незашкаливающим ЧСВ, но они в основном увы не здесь. Хотя раскрученное имя должно способствовать наличию толковых специалистов готовых прийти на помощь новочкам вроде меня. Но увы...

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

Поделюсь готовым результатом. Была полностью прочитана и расшифрована информация, которая передаётся из блока климата в дисплей, из полученных данных с помощью библиотеки TVOut сформирована видеокартинка, которая выводится на экран ГУ. Для этого использована Arduino Mega pro. Для облегчения работы был разработан имитатор сигналов блока климата на Arduino-nano, который позволил все работы проводить в тепле и уюте на столе.

Ну и пара фото, стенда и готового результата в автомобиле

Ну как-то так. Всем удачи. Если что-то заинтересовало ищите меня на Драйве, скоро выложу всё там с подробным описанием.

Misha100500
Offline
Зарегистрирован: 01.11.2018

Ну таки у меня всё получилось. На встраеваемой Меге про.

vlad072
Offline
Зарегистрирован: 01.08.2017

V-max VL пишет:

Если нужно подцепить на Uno 2 устройства по Serial, используем для 1-го устройства библиотеку Software Serial, дальше как по учебнику, а для 2-го устройства подключаем еще одну библиотеку AltSoft Serial, и запускаем устройство через эту библиотеку. Оба устройства живут одновременно и без перекрестных ошибок и сбоев. 

Про совместную работу ALT и SOFT вычитал здесь вот такое:

Using Both SoftwareSerial and AltSoftSerial
...
 
AltSoftSerial can tolerate almost 1 bit time latency, so its baud rate must be at least 10 times less than the baud rate used for SoftwareSerial.
 
If the baud rates are chosen wisely, all 3 can work together reliably!

Т.е. если я правильно понял, для устойчивой работы скорость AltSoftSerial должна быть как минимум в 10 раз ниже скорости SoftwareSerial. У кого есть опыт совместного использования двух библиотек?

 

vlad072
Offline
Зарегистрирован: 01.08.2017

Ветки конкретно по altsoft не нашёл, спрошу здесь.

1. Возможно ли в библиотеке AltSoftSerial инвертировать только TX, что бы передачу сделать через транзисторный ключ? 

2. Возможно ли освободить пин, используемый для TX, если передача не нужна?