Передача управляющих команд между ардуиноподобными устройствами

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
Пытаюсь понять работу протокола передачи PJON примерно аналог 1-wire может кто сталкивался?
Пока застрял на составлении передачи события от одного МК по нажатию кнопки к другому МК с выполнение кода по условию приёма сообщения о нажатии кнопки.
В части передатчика что то получилось, а что для приёмника писать вообще не понимаю. Код брал из примеров библиотеки, но дописать не могу, не понимаю.
код передатчика:
#include <PJONSoftwareBitBang.h>

uint8_t adres = 100;
PJONSoftwareBitBang bus(adres);
bool flag_on = false;

void setup() {
  bus.begin();
  pinMode(D6, INPUT);
   Serial.begin(9600);
}

void loop() {

if(!flag_on && digitalRead(D6) == HIGH) {
  bus.strategy.set_pin(D5);
  bus.send(1, "ON", 2);
  Serial.println("from rceiver ON");
  flag_on = true;
}
if(flag_on && digitalRead(D6) == LOW) {
  bus.strategy.set_pin(D5);
  bus.send(1, "OFF", 3);
   Serial.println("from rceiver OFF");
   flag_on = false;
}
  bus.update();

}

Незаконченный код приёмника:
#include <PJONSoftwareBitBang.h>

uint8_t adres = 1;
bool flag_state_relay = false;

PJONSoftwareBitBang bus(adres);

void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info) {
  /* Make use of the payload before sending something, the buffer where payload points to is
     overwritten when a new message is dispatched */
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  bus.strategy.set_pin(D6);
  bus.begin();
  bus.set_receiver(receiver_function);

  Serial.begin(9600);
}

void loop() {
  bus.receive(1000);


  if((payload[0] == 'ON')) {
    Serial.println("from transmitter - ON");
    digitalWrite(LED_BUILTIN, HIGH);
    flag_state_relay = true;
  }
if((payload[0] == 'OFF')) {
    Serial.println("from transmitter -  OFF");
    digitalWrite(LED_BUILTIN, LOW);
    flag_state_relay = false;
  }
}
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
Почему для связи двух МК не использовать готовые решения типа I2C, SPI, Modbus и пр..

Мсье любит извращения? ;)

Или нужно начинать диалог, со слов : "не могу прочесть данные от... " Иначе, это вопрос в никуда... Типа, не могу прочесть данные с Марса...

Это случайно не тот протокол который раз в 234 микросекунду дергает за 35-й пин... Нет? ;)))
 
Изменено:

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
@Nitrogenium, i2c, SPI сложности передачи на большие расстояния, rs485, modbus нужны дополнительные модули и оборудование.
С передачей и приёмом одного байта стало более менее понятно, два и более уже не ясно. В справке описана отправка строки, но как её принять её для сравнения не описано, хотя саму строку посимвольно можно вычленить и пакета. Справка по библиотеке очень скудная.
 
Изменено:

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
@dxf, вы пытаетесь использовать сетевой протокол как канальный. В вашем случае для связи с 2мя устройствами, физически соединенными друг с другом, сетевой протокол вообще не нужен. Используйте обычный serial для связи, примеров как передавать строки/байты навалом.
 

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
Уточню:
master:
#include <PJONSoftwareBitBang.h>
#include <EncButton.h>
EncButton<EB_TICK, A4> btn;

PJONSoftwareBitBang bus(100);
bool flag_on = false;

void setup()
{
  bus.strategy.set_pin(12);
  bus.begin();
  pinMode(A4, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop()
{
  bus.update();
  btn.tick();

  if (flag_on && btn.release())
  {
    flag_on = !flag_on;
    bus.send_packet(1, "ON", 2);
    bus.send(2, "A", 1);
    digitalWrite(LED_BUILTIN, HIGH);
  }
  if (!flag_on && btn.release())
  {
    flag_on = !flag_on;
    bus.send_packet(1, "OFF", 3);
    bus.send(2, "B", 1);
    digitalWrite(LED_BUILTIN, LOW);
  }
}
slave:
#include <PJONSoftwareBitBang.h>
PJONSoftwareBitBang bus(1);
void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info)
{
  if (payload[0] == "ON")
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  if (payload[0] == "OFF")
  {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  bus.strategy.set_pin(12);
  bus.begin();
  bus.set_receiver(receiver_function);
  Serial.begin(9600);
}

void loop()
{
  bus.receive(1000);
}
На приёмнике 1 условие включения светодиода уже не срабатывает. Можно узнать длину полезных данных в пакете через Serial.println(length);
И она как раз равна длине отправляемых данных 2 или 3 байта. Отдельно каждый байт можно считать из всего пакета, полезные данные начинаются с 5 бита пакета bus.data[5]. Но справке, в примере отправки данных, для send указано, что можно отправить несколько байт, а как принять их и сопоставить для срабатывания условия не описано. Возможно для разбирающихся в программировании это пара пустяков, но не для меня.

@vortigont, в сети предполагается разместить десятки устройств, а не 2шт. В приведённом примере 2 ведомых подключено, отлично отрабатывают приём данных по 1 байту.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
в какой сети? Сначала определите как у вас связанны устройства друг с другом на канальном уровне, потом (если нужно) будете подбирать сетевой протокол.

можно отправить несколько байт, а как принять их и сопоставить для срабатывания условия не описано
ну как-то так, например. Но это очень коряво, разве что только потестировать что-то
C++:
void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info)
{
  if (length == 3 && static_cast<char*>(payload) == "ON" )
  {
    return digitalWrite(LED_BUILTIN, HIGH);
  }

  if (length == 4 && static_cast<char*>(payload) == "OFF" )
  {
    digitalWrite(LED_BUILTIN, LOW);
  }
}
 

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
@vortigont, устройства связаны по 1 проводу, не считая земли и питания. Длина проводов 10 - 80 метров. Рассматриваю только проводную связь.

@vortigont, да я тоже думал отлавливать событие по длине пакета, этот вариант рабочий, но как то странно, согласитесь ).
Приведённый пример не сработал, на преобразование типа ругается.
В справке представлена запись
C++:
bus.send(100, "Ciao, this is a test!", 21);
Значит как то эту запись можно получить на стороне приёмника более просто.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
@vortigont, устройства связаны по 1 проводу. Длина проводов 10 - 80 метров.
на этом можно закрывать дискусию. На таких длинах общего провода десятки устройств у вас не будут работать хоть какой протокол вы сверху натяните. Решите сначала задачу канального уровня, потом будете думать о том как в этом канале передавать данные.

@vortigont, да я тоже думал отлавливать событие по длине пакета, этот вариант рабочий, но как то странно, согласитесь )
ну это вы же выбрали себе сетевой протокол PJON - вам решать странно это или нет :)
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
Сеть выполнена витой парой (UTP CAT5).
не обижайтесь, но у вас каша в голове. UTP CAT5 предназначена для передачи данных в сетях типа звезда - от точки до точки. То что она кат5 никак не делает её подходящим решением для организации каналов на "общей шине" для десятков устройств при длиннах до 80 метров. Но дело ваше,
вопрос был про пиджон. Он передает сырые данные произвольной длинны. Какую структуру туда вложить и как её обрабатывать это уже исключительно ваша задача - примеров в библиотеке навалом на разные случаи, начните с SendArbitraryDataType. Делайте свою структуру и кладите туда данные.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,975
635
45
Сеть выполнена витой парой (UTP CAT5).
Причем тут витая пара? Вы определились с топологией сети(шина, кольцо, звезда или что то другое)? На любую топологию есть готовые решения.
И да, на такие расстояния (10 - 80 метров) вы же не додумались подключать напрямую к выводам контроллера? Тогда в любом случае придется использовать соответствующие модули.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
P.S. дабы не быть голословным и считая что все канальные вопросы вы таки решили могу дать один совет по-существу - попробуйте поверх пиджона гонять сообщения в формате MessagePack, снимите все проблемы с "изобретением" своего формата сообщений их разбора, сравнения и т.п.. Сериализация/десериализация месаджпак есть в библиотеке ArduinoJson
 
  • Лойс +1
Реакции: dxf

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
@Геннадий П, по топологии думаю это шина, много устройств подключены по общему проводу к одному головному устройству. 80 метров, наверное я лишку написал, меньше будет раза в 2.К ножкам м/к по какой причине не рекомендуйте подключать? Наводки? Ослабление сигнала? С точки зрения электробезопасности?
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,975
635
45
К ножкам м/к по какой причине не рекомендуйте подключать? Наводки? Ослабление сигнала? С точки зрения электробезопасности?
С таким расстоянием любой перепад напряжения или статические наводки (например после грозы) - и ваши контроллеры подключенные к шине улетят в транзисторный рай.
Я уже не говорю про несогласованность линии, из-за чего скорости будут черепашьи. И куча прочих нюансов.

Не изобретайте велосипед, возьмите готовое решение. Шина CAN вам более чем подойдет, да и по волновому сопротивлению витой пары подходит, только терминаторы на концах не забудьте.
 
Изменено:
  • Лойс +1
Реакции: dxf

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
Про модули CAN, есть для ардуино такие MCP2515, получается у них есть какая то защита от статики перепадов напряжения? А что скажете насчёт GyverBUS, принцип там примерно тот же самый как в PJON? Для чего тогда нужно такое решение как GyverBUS?
Вцелом то, что делаю это всего лишь домашняя автоматизация и не более, датчики выключатели, исполнительные устройства.
 
Изменено:

Bruzzer

★★★✩✩✩✩
23 Май 2020
501
149
Сам не делал. Просто слова.

В распространенных модулях CAN для arduino зашита от статики и наводок есть.
За это отвечает микросхема TJA1050 в даташите приведены "LIMITING VALUES"
Соответствуют ли китайские клоны этим значениям (а может они еще лучше)?
Нужны ли вам дома такие защиты? Тоже лучше узнать у того, кто РЕАЛЬНО делал нечто подобное вашей задаче.

Если вы хотите сделать на 1wire или GyverBUS или еще что то самодельное, то желательно найти в сети аналогичные реализованные проекты, чтобы прочитать про возможные особенности. Так то 1Wire вполне работоспособна на длинах в 200 м (по заверениям производителя) https://www.rototron.info/wp-content/uploads/Vegepod_1Wire_Reliability.pdf
Чем меньше вы делаете сами и чем больше вы используете готовые модули, тем большую ответственность вы "перекладываете " на производителя модулей и разработанную им схему подключения.
Так что если вам это интересно и есть силы, то можно попробовать на 1wire или GyverBUS. Кабеля Cat5e хватит, чтобы если не получится, перейти на CAN без перекладки кабеля.
 
  • Лойс +1
Реакции: dxf

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
Немного запутался, есть протокол CAN, rs485 и др. В тоже время в справке PJON указано "PJON operates on a wide range of media, data links and existing protocols like PJDL, PJDLR, PJDLS, Serial, RS485, USB, ASK/FSK, LoRa, UDP, TCP, MQTT and ESPNOW." Т.е. PJON может работать через другой протокол? Если не сложно поясните пожалуйста кто может.

PS: так то вопрос решил поставленный в первом сообщении темы, через PJON управление сделал тестовые модельки. Благодаря подсказкам участников думаю лучше будет в последующем перейти на CAN, всё таки его явно больше проработали инженеры, но так как пока модулей нет, то запущу первое время на PJON по 1 проводу.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
@dxf, вы путаете протоколы разных уровней. Впрочем это нормально, их напридумывали оч много и часто они перекрывают друг друга. Почитайте основу основ модель OSI, без осознания этого так и будете путаться.

рс485 это физический прокол, он определяет только "провода" и формы сигналов по ним, так же как и 1-wire. Поверх физических протоколов накладываются канальные, сетевые и т.п. Некоторые протоколы включают в себя не только физику но и канальные форматы - тип кадров, поля в них и т.п. CAN такой протокол, в частности он определяет размер полезной нагрузки всего в 8 байт. Кстати учтите это в своей разработке. Если размер сообщений которые вы планируете передавать может быть более 8 байт то вам придется или реализовать нарезку и пересборку сообщений в пакеты самому или подобрать еще какой-то более высокоуровневый протокол который сможет работать поверх CAN.

PJON это что-то вроде легковесного tcp/ip,udp там где не нужен полноценный сетевой стек. Он не зависит от канальных протоколов и ниже т.к. это просто более высокоуровневый протокол. Так же как IP может работать поверх Ethernet, WiFi, LTE, VPN и пр.
Для чего он нужен? Например для того чтобы связать контроллеры в которых нет поддежки сети с теми в которых есть или чтобы связать через мкутт несколько разных контроллеров и т.п.

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

Для чего тогда нужно такое решение как GyverBUS?
гайвербас это частный случай пиджона работающий поверх Stream, т.е. Serial или сырой tcp socket. Не знаю зачем он нужен, может тем кто привык к гайвер либам или не смог найти/освоить более стандартизованное решение.
 

bort707

★★★★★★✩
21 Сен 2020
3,075
915
Отдельно каждый байт можно считать из всего пакета, полезные данные начинаются с 5 бита пакета bus.data[5]. Но справке, в примере отправки данных, для send указано, что можно отправить несколько байт, а как принять их и сопоставить для срабатывания условия не описано.
Слушайте, если вы знаете что данные начинаются в пакете с пятого байта и знаете длину данных - что вам еще нужно для их извлечения? - берете и копируете куда надо.
Приведенный отрывок показывает, простите, что Вы вообще ничего не понимаете в битах, байтах, структурах и как с ними обращаться. Да и код ваш только подтверждает это:
if (payload[0] == "OFF") {
payload - это массив байт, payload[0] - это его первый элемент, то есть один байт. Или один символ. Один символ никак не может равнятся строке "OFF" из трех символов.

Это все я к тому, что с вашими знаниями не стоит лезть в такие дебри, как малораспространенный протокол. Возьмите что-нибудь более ходовое - как уже советовали КАН или rs485 - и не потому что они лучше или проще - а банально потому, что к ним в десятки раз больше примеров использования в среде Ардуино. Возьмете какой-нибудь готовый проект и допилите под свои нужды. Потому как сами вы написать что-то подобное сможете ещё не скоро.
 

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
@bort707, уже разобрался. Спасибо. Всё изучается, не программистами же все рождаются). Модули приедут тогда CAN попробую, а пока изучаю всё и с этим занимаюсь.
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
@vortigont,
@Nitrogenium, нет, пиджн это протокол более высокого уровня, он не дергает никакими ножками
Если этот протокол не реализован в микроконтроллере на аппаратном уровне, у него нет иных способов для передачи данных как только дергать ножками. Если он только не передает данные телепатически :)

Модель OSI тут не работает. Здесь работают вполне конкретные протоколы передачи типа SPI, I2C, ModBus, CAN и пр. Если в вашем микроконтроллере это не реализовано на аппапратном уровне, значит код будет работать софтварно, дерганьем ног.

И прошу заметить, что даже в 328 атмеге, на аппаратных пинах I2C и SPI присутствует, например, подавление помех. Что уже делает их на голову выше, например контроллеров ESP, где зачастую передача на этих протоколах выполнена на софтварном уровне, на обычных пинах.

Очень странно, что столь очевидные вещи, не очевидны...
.
 
Изменено:

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
Если этот протокол не реализован в микроконтроллере на аппаратном уровне, у него нет иных способов для передачи данных как только дергать ножками
а это что? Ножки никто не дергает а данные передаются... чудеса да и только! Похоже таки телепатически!

Модель OSI тут не работает.
если вы заглянете вот сюда, то увидите там табличку с 3мя уровнями из модели ОСИ, где пиджен находится на 2м и на 3м уровне. Можете стоит завести багу о том что модель ОСИ у них не работает?

контроллеров ESP, где зачастую передача на этих протоколах выполнена на софтварном уровне, на обычных пинах.
Вы вообще хотя бы заглядывали в спеки контроллеров ESP? тыц или тыц? если заглянете то найдёте там "софтварный" DMA, "софтварные" прерывания, "софтварные" регистры, можете даже случайно обнаружить (о ужас!)
Supports programmable digital noise filte

P.S. что вы такое курите вообще... дальнейшую дискуссию считаю бессмысленной
 

dxf

✩✩✩✩✩✩✩
17 Апр 2020
47
2
У вас тут целая дискуссия, не думал, что кого то так зацепит). По сути, с библиотекой более менее разобрался если организовывать связь только между arduino и arduino, то работает нормально. Остаётся только проверить в работе на длинных линиях. Вообще занятная библиотека, нашёл по ней бакалаврскую работу, там утверждается, что передачу данных можно осуществлять на расстояние 2 км, и стабильно на 1 км , кому интересно - сайт разработки на основе PJON.
Что очень очень печально не получается заставить работать с ESP8266, которые у меня как раз есть. Данные то она передаёт, но вот ардуинки не воспринимают её. Было раза три что заработало и данные воспринимались, может звёзды сошлись, т.к. закономерности не заметил.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
543
Saint-Petersburg, Russia
@dxf, у "ардуинок" (если вы имеете ввиду атмеги) и у 8266 разный логический уровень - 5 и 3.3. вольта соотвественно. Скорее всего из-за этого у вас они и не работают вместе.