Неправильно работает обработка значения расстояния

к Ардуине подключены несколько ультразвуковых датчиков и она их по очереди опрашивает. В случае если какой-то датчик даст расстояние меньше или равно 40СМ Контроллер считает такие сработки и выводит в вебку через ethernet модуль.
Проблема в том, что сработка происходит не по условию что я задал (40см) а по непонятному мне сценарию. Датчик дает 230 см к примеру а код гордо говорит детект! и считает…
Что я сделал не так?

//Arduino Uno+ W5100 ethernet shield+ AJ_SR04M Ultrasonic sensors
//Система подсчета количества автомобилей
//Блок 1 из 4 Боковой паркинг прием и обработка сигналов от датчиков расстояния на заборе вдоль парковки

//Проблема с определением пример с сериала:
//-----Новый круг-----
//0=228cm
//Skip правильно
//1=226cm
//Skip правильно
//2=212cm  
//Detect! ??????
//3=28cm  
//Detect! правильно
//4=209cm  
//Detect! ?????? 
//5=210cm  
//Detect! ??????


#include <NewPing.h>                                 //Библиотека для сенсора расстояния
#include <SPI.h>                                     //Библиотека для передачи данных между блоками
#include <Ethernet.h>                                //Библиотека для работы с стетью

const int ID = 1;                                    // номер платы
IPAddress ip(192, 168, 1, 101);                      // IP-адрес Arduino
byte mac[] = { 0xFA, 0xFA, 0x01, 0x00, 0x01, 0x71 }; // Мак-адрес Ethernet
#define SONAR_NUM 6                                  // количество сенсоров

void checkEthernetConnection();                      // переменные вотчдога по сети
unsigned long lastEthernetCheckTime = 0;
const unsigned long ethernetCheckInterval = 60000;   // Период проверки сети в миллисекундах (60 секунд)

#define MAX_DISTANCE 250                             // максимальное расстояние пинга 2.5 Mетра
int activatedSensors = 0;                            // установка 0 переменной сработки
long sensors[SONAR_NUM];                             //массив хранения датчиков
byte gateway[] = { 192, 168, 1, 1 };                 // IP-адрес шлюза
byte subnet[] = { 255, 255, 255, 0 };                // Маска подсети
EthernetServer server(80);                           // Порт веб старницы

NewPing sonar[SONAR_NUM] = {                         // Ноги сенсоров 1_знач trig 2_знач Echo
  NewPing(2, 3, MAX_DISTANCE),                       // 1 Пины датчиков с 0 по 9 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 
  NewPing(4, 5, MAX_DISTANCE),                       // 2 перед использованием пина 4 отрезать дорожку на ethernet модуле 
  NewPing(6, 7, MAX_DISTANCE),                       // 3 
  NewPing(8, 9, MAX_DISTANCE),                       // 4
  NewPing(14, 15, MAX_DISTANCE),                     // 5 Цифровые А0 по А5-(14, 15, 16, 17, 18, 19)
  NewPing(16, 17, MAX_DISTANCE),                     // 6
 // NewPing(18, 19, MAX_DISTANCE),                   // 7 --не испольуеться сейчас
};

void setup() {                                       
Ethernet.begin(mac, ip, gateway, subnet);           //Запуск ethernet модуля 
server.begin();                                     //запуск сервера странички
Serial.begin(115200);                               // Open serial monitor at 115200 baud to see ping results.
pinMode(14, OUTPUT);                                // устанавливает режим работы аналоговых портов - выход для TRIG
pinMode(16, OUTPUT);
pinMode(18, OUTPUT);

pinMode(15, INPUT);                                 // устанавливает режим работы аналоговых портов - вход для Echo
pinMode(17, INPUT);
pinMode(19, INPUT);
}

void loop() {
activatedSensors = 0;                                // сброс переменных в начале цикла
Serial.print("-----Новый круг----- \n");

 for (uint8_t i = 0; i < SONAR_NUM; i++) {           // Цикл опроса датчиков
    delay(100);                                      // ожидание между опросами (не менее 29мс)
    Serial.print(i);                                 //отправка растояний в сериал для дебага
    Serial.print("=");
    Serial.print(sonar[i].ping_cm());
    Serial.print("cm");
    sensors[i] = sonar[i].ping_cm(); 
    Serial.println();

    if (sonar[i].ping_cm() <= 40) {                   // условия сортировки ответов от датчиков
       activatedSensors++ ;                           //Прибавляем к числу при положительном результате
        Serial.print("Detect! \n") ; 
    }         
    else {Serial.print("Skip \n");                    // Игнорируем при превышении
    }

  }

  EthernetClient client = server.available();         // Запуск вебки 
  if (client) {
    bool currentLineIsBlank = true;
    while (client.connected()) {                      //Условие чтоб не рисовать без необходимости
      if (client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");          //Сама старница
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println("Refresh: 1");
          client.println("Access-Control-Allow-Origin: *");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head>");
          client.println("<title>");
          client.println("ID: " + String(ID));
          client.println("</title>");
          client.println("</head>");
          client.println("<body>");
          client.println("ID: " + String(ID));
          client.println("Busy Parks: " + String(activatedSensors) + " of " + String(SONAR_NUM));    // Вывод активированных датчиков на страницу
          client.println("</body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();
  }
   delay(1000);                                       // Пауза между обновлениями в миллисекундах и все по новой
  
 }

// Проверка состояния сетевого соединения и перезапуск Ethernet-модуля в случае пропажи сетевого соединения
void checkEthernetConnection() {
  unsigned long currentMillis = millis();

  if (currentMillis - lastEthernetCheckTime >= ethernetCheckInterval) {
    lastEthernetCheckTime = currentMillis;

    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet connection lost. Restarting Ethernet...");
      Ethernet.begin(mac, ip, gateway, subnet);
    }
  }
}

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

Датчики между собой разделены 100мс паузой. Накладывание 2х сигналов возможно только если пауза меньше 29мс. Данные читаться раз. И они сразу выводиться в сериал и они как раз больше 40 см. Не похоже на это. Скорее всего что то в коде не так (

Надо один раз измерить, и потом работать с этим значением sensors[i] , а вы каждый раз делаете новые измерения, и они могут быть разные. в if - один результат измерения, а в print уже другой.

1 лайк

Верно?

for (uint8_t i = 0; i < SONAR_NUM; i++) {           // Цикл опроса датчиков
    delay(100);                                      // ожидание между опросами (не менее 29мс)
    sensors[i] = sonar[i].ping_cm(); 
    Serial.print(i);                                 //отправка растояний в сериал для дебага
    Serial.print("=");
    Serial.print(sensors[i]);
    Serial.print("cm");
    
    Serial.println();

    if (sensors[i] <= 40) {                   // условия сортировки ответов от датчиков
       activatedSensors++ ;                           //Прибавляем к числу при положительном результате
        Serial.print("Detect! \n") ; 
    }         
    else {Serial.print("Skip \n");                    // Игнорируем при превышении
    }

  }

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

1 лайк