Датчик движения перестаёт слать данные

Gelezako
Offline
Зарегистрирован: 23.09.2017

Здравствуйте уважаемые ардуинщики. Столкнулся с проблемой, через некоторый перод времени, бывет через несколько часов, бывает через сутки, датчик движения HC-SR501 перестаёт слать данные о том что есть движение, но возможно и что сам датчик перестаёт  определять сам факт движения (апаратная проблема), но я грешу на код, потому как если перегрузить ардуинку, то всё начинает работать.

Датчик движения HC-SR501 подключён к андуино нано + Ethernet шилд, когда фиксирует движене через mqtt  шлю еденичку.

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

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

Мне ненравится вот эта функция:

void callback(char* topic, byte* payload, unsigned int length)
{
  byte* p = (byte*)malloc(length);
  memcpy(p, payload, length);
  client.publish("data/HCSR501", p, length);
  free(p);
}

Не очень понятно для чего запрашивается память, почему нельзя просто передать client.publish прямо payload, зачем его обязательно копировать. Но, это Бог с ним, может и нельзя, я не знаю что там с этим буфером делает client.publish.

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

Gelezako
Offline
Зарегистрирован: 23.09.2017

Спасибо за ответ Евгений, на самом деле функция callback из стандартного примера работы с mqtt и я в ней поменял только название топика куда паблишить. Погуглил про функцию malloc, нашёл что если она не сможет выделить нужное количество, то возвращает NULL. И добавил вот такую проверку:

  byte* p = (byte*)malloc(length);
  if(p==NULL) {
    digitalWrite(LedPin, HIGH);
    delay(50000);
    digitalWrite(LedPin, LOW);
    delay(50000);
    digitalWrite(LedPin, HIGH);
    delay(50000);
    digitalWrite(LedPin, LOW);
    delay(50000);
    digitalWrite(LedPin, HIGH);
    delay(50000);
    digitalWrite(LedPin, LOW);
    delay(50000);
  }

Сама ардуино не подключена у меня постоянно к ноуту, поэтому нет смысла в сериал порт выводить дебаг информацию, я её не увижу и мониторить так долго (может проявится только через сутки) тоже нет возможности. Поэтому всё что я мог придумать это мигать 3 раза диодом раз в пол секунды если память не выделилпсь. Залил скеч - ждуя сбоя :)

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

 

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

Gelezako пишет:

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

Есть, если у Вас есть свободный пин (светодиод) который для других целей никак не используется.

Тогда в самом начале настраиваете пин на OUTUТ и гасите светодиод. В случае же аварии (нехватки памяти или в будущем любой другой), просто включаете светодиод и замираете, т.е. делаете

cli();
while(true);

Программа ничего делать не будет, а светодиод будет гореть и ждать Вас даже если Вы подойдёте посмотреть на него через неделю.

Gelezako
Offline
Зарегистрирован: 23.09.2017

понял,спасибо