Извращение по цифровому входу

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Вообщем немного извращения в ветку...

Имеется - ардуино с одним свободным цифровым входом, и 16 битная, инвертированная шина данных на скорости 4800...

Задача - при поступлении определенного (два пакета) сигнала зажечь (грубо говоря) светодиод сигнализации...

Сигнал

Идеи предложения или хоть направления?!

b707
Offline
Зарегистрирован: 26.05.2017

а название у этой шины есть?

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

Поймал фронт, и пошел проверять с заданной частотой что на входе. Получил 2 байта, сравнил с заданными.

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

" и 16 битная, инвертированная шина данных на скорости 4800..." А это к чему?
Если вам нужен однопроводной канал связи - так и скажите. Но, тут должны быть другие требования.

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

Станислав Пимшин пишет:

Имеется - ардуино 

Какая? И что за свободный пин? На нём есть прерывание, хоть какое-нибудь?

Станислав Пимшин пишет:

Задача - при поступлении определенного (два пакета) сигнала зажечь (грубо говоря) светодиод сигнализации...

Идеи предложения или хоть направления?!

Если ответ на предыдущий вопрос "да", то "как два пальца", даже хороший пример кода есть готовый - в библиотеке SoftwareSerial в той её части, которая занимается чтением Rx.

Общая идея:

1. Считаете длительность бита BIT_DURATION = F_CPU / BAUD / (F_CPU/1000000). Для 16МГц и 4800 bod это 206 микросекунд.

2. Пин притягиваете к уровню противоположному уровню стартового бита.

3. ждёте прерывания на пине (это будет начало стартового бита).

4. Ждёте ровно половину длительности бита BIT_DURATION / 2. В этот момент Вы в середине передачи стартового бита.

5. Заводите таймер на срабатывание (по COMPA, например) с интервалом BIT_DURATION 

Теперь Вы будете получать прерывания от таймера в момент "середины" каждого передаваемого бита.

6. Ловите прерывания и считываете с пина соответствующие биты.

7. Когда всё считали, выключаете прерывание - Вы получили результат.

Следующий байт (слово) читается также.

P.S. Не знаю, что там у Вас за шина, но 90 пудов для неё можно приспособить сам SofwareSerial (может, с минимальными переделками) и ничего писать не надо.

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

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

Если ответ на предыдущий вопрос "да", то "как два пальца", даже хороший пример кода есть готовый - в библиотеке SoftwareSerial в той её части, которая занимается чтением Rx.

Спасибо за конструктив буду курить!

Стандартный uart Arduino поддерживает только восьмибитный пакет данных...
Softwareserial может поддерживать 16 бит?

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

Станислав Пимшин пишет:

...буду курить!

Стандартный uart Arduino поддерживает только восьмибитный пакет данных... Softwareserial может поддерживать 16 бит?


Лучше курите.

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

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

P.S. Не знаю, что там у Вас за шина, но 90 пудов для неё можно приспособить сам SofwareSerial

Шина одна линия из двух стандартных UART с длинной "слова" 16 бит...

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

Дрова.)

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

Станислав Пимшин пишет:
Стандартный uart Arduino поддерживает только восьмибитный пакет данных... Softwareserial может поддерживать 16 бит?
Да, если исправить несколько букв в двух строчках библиотеки. Я же говорю - "с минимальными изменениями".

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

ЕвгенийП пишет:
исправить несколько букв в двух строчках библиотеки. Я же говорю - "с минимальными изменениями".


Сегодня посмотрю, что и как....
Постараюсь разобраться!

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

Несколько букв? Только что то стопа не видать.

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

линия инвертированная... 

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

Ну а если в конец второго байта посмотреть.

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Особенность общения, стоповые в конце передачи пакетов не показываются...  

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

А задачи какие ещё крутятся?

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

Да, плевать на стопы. Лишь бы стартовый был. В #4 я расписал как это делается. SoftSerial делает именно это.

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

К сожалению слабоумием страдаю.... не могу понять SoftSerial от слова совсем... 

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

А вот не лазил бы я в SoftSerial. Что мешает просто принимать по 2 байта им же?

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

Green пишет:

Что мешает просто принимать по 2 байта им же?

Мешает то, что при 16-битной посылке никто не пошлёт стартовый бит в начале второго байта (если я правильно понял протокол).

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

Станислав Пимшин пишет:

К сожалению слабоумием страдаю.... не могу понять SoftSerial от слова совсем... 

Найдите там строки (у меня они №№ 157-165)

// Read each of the 8 bits
    for (uint8_t i=8; i > 0; --i)
    {
      tunedDelay(_rx_delay_intrabit);
      d >>= 1;
      DebugPulse(_DEBUG_PIN2, 1);
      if (rx_pin_read())
        d |= 0x80;
    }

А также выше строку, в которой описана d (у меня она №142).

d нужно переописать как uint16_t, в цикле, вместо i=8 написать i=16. Наконец, вместо "d |= 0x80;" поставить "d |= 0x8000;"

Собственно всё, к концу цикла Вы должны получить все 16 бит.

Дальше надо посмотреть - там идёт участок функции в которой они складывают результат в буфер и пропускают стоповый бит. Оно Вам надо? Или не надо? Разбирайтесь сами и соответственно принимайте решение.

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

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

Мешает то, что при 16-битной посылке никто не пошлёт стартовый бит в начале второго байта (если я правильно понял протокол).

А, ну да, попутал(. На картинке две посылки по 16 бит.

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Я смотрел файл с расширением h а не срр... 
должно получиться так?
 

 uint16_t d = 0;

  // If RX line is high, then we don't see any start bit
  // so interrupt is probably not for us
  if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
  {
    // Disable further interrupts during reception, this prevents
    // triggering another interrupt directly after we return, which can
    // cause problems at higher baudrates.
    setRxIntMsk(false);

    // Wait approximately 1/2 of a bit width to "center" the sample
    tunedDelay(_rx_delay_centering);
    DebugPulse(_DEBUG_PIN2, 1);

    // Read each of the !16 bits
    for (uint16_t i=16; i > 0; --i)
    {
      tunedDelay(_rx_delay_intrabit);
      d >>= 1;
      DebugPulse(_DEBUG_PIN2, 1);
      if (rx_pin_read())
        d |= 0x8000;
    }

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

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

Я бы сделал копию библиотеки и переименовал бы её, чтобы никому другому не мешать.

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

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Спасибо, будем разбираться...

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

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

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

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

Я бы сделал копию библиотеки и переименовал бы её, чтобы никому другому не мешать.

очень сложно! манагер PCINTов отсутствует как класс однако...

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

ua6em пишет:

очень сложно! манагер PCINTов отсутствует как класс однако...

PCINT вообще отсутствует в концепции Ардуино. И именно потому, что просто - не получится.

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

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

"просто" вообще не бывает, а pcint просто часть инструмента, было бы желание /знания.

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

b707 пишет:

а название у этой шины есть?

человек реверсит шину SL-DATA сигнализаций старлайн. Эта шина использовалась на сигнализациях вплоть до А94. Служит для расширения функционала сигнализации до GSM/GPS, посредством подключения внешнего GSM модуля. 

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Желание есть а знания нуль... По этому и хотелось сделать именно прием сообщения не с помощью стандартного UART, а как нибудь по другому... Используя часть кода через прерывание считать пакет данных и сделать вывод из этого авария или всё норм и посылать свои команды...

Понравилось идея ЕвгенийП... Но знаний не хватает от слова совсем... 

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

Станислав Пимшин пишет:

Но знаний не хватает от слова совсем... 

Ну так это совершенно стандартная ситуация.

И из нее также совершенно стандартные 3 варианта выхода:

1. Расширять свои знания и умения до тех пор, пока их не будет хватать.

2. Заказать работу тем, у кого знаний и умений хватает.

3. Забыть об этой задаче.

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

Станислав Пимшин пишет:

Желание есть а знания нуль... По этому и хотелось сделать именно прием сообщения не с помощью стандартного UART, а как нибудь по другому... Используя часть кода через прерывание считать пакет данных и сделать вывод из этого авария или всё норм и посылать свои команды...

Понравилось идея ЕвгенийП... Но знаний не хватает от слова совсем... 

Если SoftwareSerial  не используется в скетче то как рекомендовал Евгений вполне, а если используется придётся править библиотеку, ограничивая используемые  под сериал пины, но переносить правленную в папку скетча, чтобы не затронуть остальные проекты

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

 SoftwareSerial  используется в скетче, с двумя устройствами, SIM800 и периферией... кроме того есть желание подцепить GPS модуль GY-NEO6MV2 (но пока только желание)... 

А собственно возможно написать "деревянный" код не используя функцию UART от слова совсем??? сделать то же самое с получением данных и складыванием... 

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

Станислав Пимшин пишет:

 SoftwareSerial  используется в скетче, с двумя устройствами...

Это порочная практика.

SoftwareSerial работает максимум с одним устройством. И то не без проблем.

Если Вам нужно более одного UART, следует выбирать контроллер, в котором есть соответствующее количество аппаратных портов. 

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Может ли работать такой кот? 

byte slin = 11;               //Назначение входа RX SL-Data
unsigned int rx16bit = 0;     //Назначение переменной данных SL-Data
unsigned int rx16bit1 = 0;      //Назначение переменной первого слова
unsigned int rx16bit2 = 0;      //Назначение переменной второго слова
void setup() {
 pinMode(slin, INPUT);         //Инициализируем вход для приема данных из сигнализации.
  digitalWrite(slin, HIGH);     //притягиваем к плюсу

void loop() {

  if (digitalRead (slin) == LOW) {          //Условие срабатывания считывания кода
    rx16bit = 0;
    if (digitalRead (slin) == HIGH) {       //Ждем стартовый импульс (не уверен что это вообще будет работать)
      delayMicroseconds(312);               //Отсчитываем полтора импульса (208+104мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние первого бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 1;                        //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 2;                        //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 4;                        //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 8;                        //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 16;                       //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 32;                       //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 64;                       //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 128;                      //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 256;                      //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 512;                      //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 1024;                     //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 2048;                     //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 4096;                     //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 8192;                     //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 16384;                    //Если низкий уровень то прибавляем бит в десятичном виде
      }
      delayMicroseconds(208);               //Отсчитываем импульс (208 мкс)
      if (digitalRead (slin) == HIGH) {     //Смотрим состояние следующего бита
        rx16bit + 0;                        //Если высокий уровень то нулик
      } else {
        rx16bit + 32768;                    //Если низкий уровень то прибавляем бит в десятичном виде
        if (rx16bit1 == 0) {
          rx16bit1 = rx16bit;
        } else {
          rx16bit2 = rx16bit;
        }
      }
    }
  }

}

Пинать прошу не сильно...

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

Станислав Пимшин пишет:

Может ли работать такой кот?

Любой код, всегда работает и делает именно то, что написал программист (неисправность аппаратуры мы сейчас не рассматриваем). Так что, да, этот код, вне всякого сомнения, будет работать и будет делать именно то, что в нём написано.

Будет ли он делать то, чего Вы от него ждёте?

Ну, Вы не написали что конкретно Вы ожидаете, но если мои догадки о назначении этого кода верны, то нет - не будет.

Станислав Пимшин пишет:

rx16bit + 1;    //Если низкий уровень то прибавляем бит в десятичном виде

И куда деваем результат "прибавления"?

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

На ум кладём, очевидно...

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Хочу получить следующий результат...

При возникновении сигнала как на картинке в первом сообщении считать его и получить десятичные данные в переменных rx16bit1 и rx16bit2...

Далее планируется сравнивать данные с тем что заложено будет в программе и по результатам "говорить" что пришло...

 

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

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

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

Станислав Пимшин пишет:

Вопрос о работоспособности в начале кода... 

Ответьте сами себе на вопрос из последнего предложения #36

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Если под такой записью

rx16bit + 16;    

ты понимаешь прибавление к переменной числа, то в языке С это записывается иначе:

rx16bit += 16;    

На это и намекали выше, но ты не исправил, следовательно не описка, а печальная реальность.

===========

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

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

Спасибо за подсказку, завтра обязательно поправлю... 

Я и пишу в песочницу... Обижаться и не думал... 

Если внесу данное исправление то получу необходимый результат?

Или же нужно ещё вносить корректировки??? 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Станислав Пимшин пишет:

Или же нужно ещё вносить корректировки??? 

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

Скачай КиР (Керниган и Ричи, к примеру https://www.r-5.org/files/books/computers/languages/c/kr/Brian_Kernighan_Dennis_Ritchie-The_C_Programming_Language-RU.pdf), открой любую онлайн ИДЕ (их - десятки, яндекс первой выдает https://ideone.com - ничем не хуже других),  читай книжку и делай примеры. Нет другого пути.

Станислав Пимшин
Offline
Зарегистрирован: 18.11.2019

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Станислав Пимшин пишет:

Спасибо за подсказку, завтра обязательно поправлю... 

Я и пишу в песочницу... Обижаться и не думал... 

1.Если внесу данное исправление то получу необходимый результат?

2.Или же нужно ещё вносить корректировки??? 

ОК. Давай по твоему.

1. Нет, не получишь.

2. Да, нужно.

-----------------

Ты спросишь: какие? На этот вопрос тебе уже 40 с гаком сообщений ответили, ты их не понимаешь. Об этом я и написал выше.

Я не знаю, в чем ты специалист, но, кажется, придумал универсальную аналогию: НЕВОЗМОЖНО объяснить, как приготовить плов, если человек не умеет жарить даже яичницу.

 

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

почитал тему по диагонали (пока некогда вникать). Спрошу у общественности, а наличие свободного аппаратного UART (взять мегу 2560) облегчит задачу? 

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

MaksVV пишет:

почитал тему по диагонали (пока некогда вникать). Спрошу у общественности, а наличие свободного аппаратного UART (взять мегу 2560) облегчит задачу? 

а то!

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

Какое то? Нестандартный 16-битный UART.

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

MaksVV пишет:

почитал тему по диагонали (пока некогда вникать). Спрошу у общественности, а наличие свободного аппаратного UART (взять мегу 2560) облегчит задачу? 

Вы бы задачу сформулировали. (а то лень тему перечитывать)

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

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