Сбор данных с датчиков до отправки на сервер

Здравствуйте. Подскажите, как лучше организовать сбор информации с 8ми датчиков (герконов) на ардуино? Отправлять данные на сервер можно только раз в 10 секунд. В это время 8 герконов могут включаться, выключаться, давать 1 или 0, что показывает открытие/закрытие дверей и окон.

Данные на внешний сервер отправляются get-запросом.

В итоге нужно собрать информацию, что сработал датчик1 на открытие в такое-то время, потом сработал на закрытие в такое-то время и когда придет время отправки на сервер все данные туда отправить.

Ну сами же алгоритм описали:

Что ешё нужно, не понятно?

Как это лучше реализовать: в массив собирать или в строчку данные записывать?

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

Лично я бы, скорее всего, стал посылать текущее состояние в виде 8-разрядного числа (в 10-чном или 16-чном виде), а также, если с момента предыдущей посылки произошли какие-то события (открытие или закрытие), дополнить его строками с соответствующими событиями. Лучше в формате: время в нужном формате + значение после изменения в виде 8-разрядного числа.

За 10 секунд не так и много событий, думаю, произойдёт. Поэтому сразу в строку GET-запроса и собирать.
В каком формате? Да в любом удобном и понятном вам. Например, мне понравился вариант от @andriano . Но это возможно потому, что я понимаю о чём он написал. А если вы не понимаете - придумайте своё…

1 лайк

если это герконы окон и дверей, а не точной механики, то можно предположить, что данные о времени точнее 1 сек не требуются.
Значит за 10 сек по каждому датчику накопится 10 бит значений был разомкнут- 0 или замкнут - 1. На 8 датчиков - 80 бит. Это 10 байт, или в читаемом формате - 20 шестнадцатеричных знаков. Даже за 20 сек будет 40 знаков. Никаких проблем в GET запрос упаковать, хотя POST запрос все таки выглядит удачнее. Там просто можно JSON собрать с данными по всем датчикам и парсить его на сервере гораздо комфортнее будет.

1 лайк

Не так и не так. И то, и другое приведёт кажущейся простоте, но к разлапистому, трудно отлаживаемому и ещё труднее модифицируемому коду.

Правильно разделить задачу на части и есть слона по частям.

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

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

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

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

Боюсь, только я зря всё это писал. Делать правильно здесь не принято. Скорее, наоборот, иногда поражает к каким усилиям и ухищрениям прибегает человек, только бы не сделать, сдуру, правильно :frowning:

5 лайков

Отправляй текущее состояние каждого геркона и количество изменений каждого геркона с последней передачи. Еще вариант отправляй текущее состояние каждого и историю изменений каждого в миллисекундах с последней отправки. Форматом джейсон, его удобно парсиить. Хотя у GET есть ограничение по длине, POST можно использовать?

В целом подход отличный, а пример кода может еще предложите?

Потому как у меня только вариант со строковым решением есть

void Gercon()                                    // Функция снятия показаний с герконов
{
  if(sig==1)                                     // Если сигнализация включена, проверяем герконы
  {
    for (int n=0; n<8; n++)                      // для всех герконов n<8 
    {
      g[n]=!digitalRead(40-n);                   // Считываем геркон(n) 
      if(g[n]!=g_t[n])                           // Проверяем с предыдущим значением, если оно изменилось, тогда добавляем его
      {
        addr=addr+"&g"+String(n+1)+"[]="+g[n];   // Если сработал геркон n+1, добавляем информацию в запрос вебсерверу, надо еще время сюда добавить
        g_t[n]=g[n];                             // предыдущее значение приравниваем к текущему
      }
    }
    Serial.print("addr=");
    Serial.println(addr);
  }
}

В итоге получаем get запрос add_new.php?g1[]=1&g1[]=0&g1=1 и в php уже работаем с массивом значений по каждому геркону

Можно даже после значение и время сюда писать

add_new.php?g1[]=1&g1[]=”12:20:24”&g1[]=0&g1=”12:20:54”

Какой смысл в таком ответе?

Я предложил свой вариант, да возможно он примитивный и долгий, но он работает.

Поэтому я и спрашиваю, как сделать это лучше

Такой, что ты согласился в подходе описанном @ЕвгенийП и ляпнул совершенно противоположное. Вопрос: зачем?

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

Другая функция будет отправлять собранные данные на сервер, ее мы обсудили в другом чате.

В целом, подход похож на вариант от @ЕвгенийП

Шта??? 0_0
Наркоманам и упоротым тут не помогают. Имей ввиду.

Вово, раскади как ты будешь ранные разбирать на приёмнике. На компе, на есп каким кодом, алгоритмом. Передать данные можно как угодно, а как ты их разбирать будешь?

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

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

если решите получить код за денежку, который сделаю за вас, то я тут)))

Тогда тупо джейсоном отправляй дату, время и состояние каждого геркона если они изменялись за время с последный отправки {и совсем не обязательно за 10 секунд}. А на приёмнике разбирай как хочешь и пиши в базу что нужно.

Кроме шуток, я думаю над платным заказом, только это не отдельно взятый код дб, а итоговое решение моей задачи.

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