Проблема с oneWire

kostyamat
Offline
Зарегистрирован: 16.11.2017

Ребята, помогите, пожалуйста.

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

1. Протокол связи односторонний. Прибор только передает информацию на 

    устройство индикации.

2. Данные передаются пакетами по 7 байт с периодичностью примерно раз 

    в полсекунды. Но не реже 1 раза в 6 секунд, потому что индикатор высвитит

    сообщение о потере связи с прибором.

Структура пакета:

- 1-й байт всегда 0хС9 - заголовок пакета;

- 2-й и 3-й байт одинаковы. Каждый бит байта представляет собой 

                  состояние шлейфов: 0 - норма шлейфа, 1 - тревога (обрыв или КЗ). 

                  Самый младший бит - 1-й шлейф, следующий - 2-й и т.д.

- 4-й и 5-й байты тоже одинаковы. Самый младший бит байта - состояние

                  сети 220 (норма - 0, отсутствие - 1). Следующий бит байта - состояние 

                  аккумулятора (0 - в норме и заряжен, 1 - отсутствует или разряжен). 

                  Пятый бит байта - всегда равен 1.

- 6-й и 7-й байты одинаковы и показывают уровень сигнала сети GSM 

                  от 1(самый слабый) - до 8(максимальный).

3. Неиспользуемые биты в байтах лучше ставить равными 0 .

 

вот так собираю пакет

void statistic() {
  byte _service = 0;
  printState = false;

  for (int8_t i = 0; i < 4; i++) {
    if (!inAlarm) {
      if (digitalRead(input[i])) _service |= (1 << i);
    } else {
      if (zona[i]) _service |= (1 << i);
    }
    if (!digitalRead(pins[i]))_service |= (1 << 4+i);
  }

  if (service[1] != _service) printState = true;
  service[1] = _service;
  _service = 0;


  if (power220) _service |= (1 << 0);
  if (powerState) _service |= (1 << 1);
  _service |= (1 << 5);

  if (service[2] != _service) printState = true;
  service[2] = _service;
  _service = 0;


  _service = signalLevel / 4;

  if (service[3] != _service) printState = true;
  service[3] = _service;
  _service = 0;

  if (alarmOn) _service |= (1 << 0);
  if (inAlarm) _service |= (1 << 1);
  if (connectOk) _service |= (1 << 2);
  if (gprsOk) _service |= (1 << 3);
  if (inCall) _service |= (1 << 4);

  if (service[4] != _service) printState = true;
  service[4] = _service;
  _service = 0;


  _service = timeWait;

  if (service[5] != _service) printState = true;
  service[5] = _service;
  _service = 0;

}

вот так отправляю


#include <OneWire.h>

OneWire ds(10);

byte service[6] {201, 0, 0, 0, 0, 0};
unsigned long tReader;

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


void loop() {


  statistic();
    if (((millis() - tReader) >= 400)) {
    talkToReader(false);
    tReader = millis();
  }
}

void talkToReader() {

  ds.reset();

  ds.write(service[0], 1);
  ds.write(service[1], 1);
  ds.write(service[1], 1);
  ds.write(service[2], 1);
  ds.write(service[2], 1);
  ds.write(service[3], 1);
  ds.write(service[3], 0);
  
  Serial.print(service[0], HEX);
  Serial.print(service[1], HEX);
  Serial.print(service[1], HEX);
  Serial.print(service[2], HEX);
  Serial.print(service[2], HEX);
  Serial.print(service[3], HEX);
  Serial.println(service[3], HEX);

}

Резистор 4к7 на +5 с вывода 10 я кинул. А лыжи не едут. Индикатор данных не видит и все тут.

Я в ступоре. Что я делаю не так?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Не знаю как там ваш индикатор работет. Но обычно в конце посылки данных шлется CRC. Может и индикатор его хочет? А не получив считает полученные данные неверными.

kostyamat
Offline
Зарегистрирован: 16.11.2017

спасибо за подсказку, сам как то не подумал об этом. НО! Не помогло, увы... :(

Что я еще мог сделать не так?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ccылка на даташит индикатора есть? Ну или любую доку про него.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

В строке 5 кода передатчика - дичь, пропущен знак "равно". В строке 18 - вызов функции с параметром, при этом сама функция объявлена как функция без параметров. Где правда, Зин? Этот код не должен компилироваться. Зачем service имеет размерность в 6 байт, если при отсылке данных на индикатор используются всего 4? Я вижу, что заполнение массива идёт в функции statistic, однако последние два байта этого массива - на индикатор не уходят, так и было задумано?

Далее, что интересно: вы никак не анализируете результат reset() - а вдруг там на линии - никого? Любой имплементатор протокола 1-Wire обязан откликнуться на импульс reset() - это простейший способ проверить, есть ли устройства на линии, заодно сбросив их конечные автоматы в режим ожидания команд от мастера. Далее - возможно, после вызова reset() надо бы позвать skip(), чтобы пропустить поиск ROM на линии - хотя вы и сказали, что у слейва нет ROM, но кто его знает, какая последовательность команд будет для него правильной?

Короче - надо бы даташит на девайс, а то гадать можно до посинения, что ему не нравится.

kostyamat
Offline
Зарегистрирован: 16.11.2017

DIYMan пишет:

Стандарт языка вполне позволяет не ставить знак = в 5-ой строке, Вы этого не знали? Текст программы несколько вырван из контекста, поэтому да там функция с параметром, а там нет., когда вырезал - упустил этот нюанс. Байтов собирается больше чем передается потому, что они кроме передачи еще используются в других местах программы. По сути функция делает именно то, что следует из ее название -собирает статистику, но тут это к делу не относится.

Ресет не анализирую потому, что индикатор единственное устройстов на линии, и поверте - никак и ни на что не отзывается, от слова совсем. Даташита у него нет.  Вообще пропьетарщина от именитого в Украине производителя сигнализаций.

Функцию skip() вставлял, никакой реакции, CRC передавал - тоже самое. Магия :(

Подключил другую ардуину как слейв - читает все аж бегом, четко и красиво.

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

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

А есть устройство в котором этот индикатор работает? Если да, то подключить логический анализатор, да посмотреть, что и как там передается. 

kostyamat
Offline
Зарегистрирован: 16.11.2017

Нет ни устройства, ни логик-анализатора.
Сейчас возникла другая проблема: индикациа состояния "на охране" там осуществляется двумя светодиодами включенными последовательно, и подсоединенными паралельно линии, между виводом data и землёй. Тупой digitalRead ноги data всегда возвращает высокий уровень, хотя я при передаче выставляю состояние паразитного питания соответственно состояния "охрана". Это видно из кода выше. Оригинальный индикатор реагирует четко - светодиоды почти гаснут, если снято с охраны, и ярко светят, если на охране.
Вопрос: как считать состояние ноги, ведь на ней реально присутствует высокий или низкий уровень в эти моменты. Есть ли обходной путь считать ногу, обойдя библиотеку?

Пс. Если сделать ногу pinMode INPUT то библиотека вешает контроллер.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

kostyamat пишет:

Стандарт языка вполне позволяет не ставить знак = в 5-ой строке, Вы этого не знали? 

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

З.Ы. Посмотрел вот тут: https://en.cppreference.com/w/c/language/array_initialization - не нашёл ничего про опускание знака "равно". Если не затруднит - киньте ссылкой на пункт стандарта, где описывается, что можно так.

kostyamat
Offline
Зарегистрирован: 16.11.2017

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

Пс. 2.86 вольта на ноге, при типа "низком" паразитном питании и с включенными паралельно шине двумя последовательными светодиодами. :(
Я так понимаю что Атмел 2.86 вольта в 1-цу зачисляет?

Пришлось оставить светодиоды, и спаралелить вход data OneWire с аналоговым входом A0. Соответственно при отключенном паразитном питании имею с него около 650, а при включенном больше 850. Придется так и оставить, или у кого-то
другие идеи есть?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

kostyamat пишет:
Что вам стоит убедится, что все прекрасно компилируется, опустив знак "=" в любом примере?

Вы сами упомянули про стандарт, не я. Я просто попросил вас указать - где в стандарте такое прописано. То, что оно компилируется - это одно, речь сейчас только про стандарт. Мне самому стало интересно - что я пропустил.

Я проверил, да - компилируется и работает. Мне чисто информационно, для расширения кругозора, интересно было бы найти указание в стандарте, чтобы почитать. Заранее спасибо за указание пункта, если вас не затруднит.

З.Ы. Всё, нашёл, спасибо, новая фича С++11 (как я стар :)), синтаксический сахарок: https://en.cppreference.com/w/cpp/language/aggregate_initialization

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

kostyamat пишет:

Я так понимаю что Атмел 2.86 вольта в 1-цу зачисляет?

 

"Чукча не читатель?".

 

kostyamat
Offline
Зарегистрирован: 16.11.2017

wdrakula пишет:

kostyamat пишет:

Я так понимаю что Атмел 2.86 вольта в 1-цу зачисляет?

 

"Чукча не читатель?".

Ага!

судя по графику - таки зачисляет :(

kostyamat
Offline
Зарегистрирован: 16.11.2017

Итак, - "Хьюстон, у нас проблемы!"

Проделав кучу экспериментов, установил пренепреятнейший факт. Наша всеми любимая бибиотека OneWireSlave2 оказалась несколько странной, да и OneWire от Ардуино - тоже. Судя по всему, ни та, ни другая не следуют стандарту или следуют очень приближенно. Похоже что-то с таймингами.

Написав простенький код, убеедился что все работает между двумя ардуинами, даллас темп.датчики тоже, но на этом все. Данные, которые выдает мастер не видит ни одно устройство (не ардуино), которые прекрасно работают между собой, и с другими устройствами, даже других производителей. А библа слейв еле еле отлавливает команды от этих же устройст. Байти принимаются очень не стабильно, с постоянными ошибками. Платы ардуино менял, резисторы подбирал,  - результат плачевный. Наверно именно это является причиной, что фейк-iButton на OneWireSlave не заработал ни в одном домофоне. А у меня оно не работает с двумя проф.сигнализациями, которые прекрасно видят iButton и т.п. 

В начале єкспериментов, Slave ловила только мусор, уменьшив delay в коде библы удалось 70\30% получать правильные данные, но 70% в таких системах, как сигнализация, меня не устраивает.

Сушу голову, что делать? Нашел OneWireHUB но таки не понял как им правильно пользоватся, что-то наворотили там "не па-децки".

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а логическим анализатором тайминги посмотреть не судьба?

kostyamat
Offline
Зарегистрирован: 16.11.2017

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

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

Почему же сразу "не судьба"?

Просто небольшой таймаут до того момента, когда это досадное недоразумение будет разрешено.

-NMi-
Offline
Зарегистрирован: 20.08.2018

DetSimen пишет:

а логическим анализатором тайминги посмотреть не судьба?

Дед, ты чо матом ругасси?  Ты сам-то хоть понял, чо написал?

Логический, блее (ана)котолизатр... :))

kostyamat
Offline
Зарегистрирован: 16.11.2017

andriano пишет:

Почему же сразу "не судьба"?

Просто небольшой таймаут до того момента, когда это досадное недоразумение будет разрешено.


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

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

Если надо разрешить до 10-го, то курьерская служба ЛА за дня три доставит. Ну, или напрячься и сделать что-то типа LA из ардуины. А потом написать идеальную библиотеку.

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013
регистратор данных можно собрать на ft232rl 150р.
 
А вот прога анализатор  протоколов для нее так же она поддерживает  и регистраторы на чипе CY7C68013 (USBee seleae )
Очень приятная  несмотря на глюки
 
kostyamat
Offline
Зарегистрирован: 16.11.2017

Ну ясно, начали за дравие, а докатились до...

Короче, 10-е прошло, уже не интересно. А библы таки фуфло. :(