Данные с аналоговых пинов.

Тема в разделе "Arduino & Shields", создана пользователем user999, 8 фев 2017.

  1. user999

    user999 Гик

    Добрый день!
    Как то странно работает китайский датчик влажности почвы. Решил провести простой эксперимент - считать данные с цифровых пинов без подключения к ним чего либо.

    Код (C++):
    void setup() {
      Serial.begin(9600);
      pinMode(A0, INPUT);
      pinMode(A1, INPUT);
      pinMode(A2, INPUT);
    }
    void loop() {
      float h0, h1, h2;
      h0 = analogRead(A0);
      h1 = analogRead(A1);
      h2 = analogRead(A2);
      Serial.println(String(h0, 0)+" | "+String(h1, 0)+" | "+String(h2, 0));
      delay(2000);
    }
    Вот какие данные получил:
    Почему аналоговые порты выдают такие данные без подключенных к ним устройств и почему такие скачки?
     
  2. rkit

    rkit Гуру

    Потому что на висячих пинах все равно есть электрический заряд, и он изменяется от воздействия электромагнитного поля.
     
  3. Securbond

    Securbond Гуру

    Потому что висят в воздухе, это наводки. Подключите к GND и увидите 0.
     
  4. user999

    user999 Гик

    Почему глючит простейший скетч?
    Код (C++):
    float h0;
     
    void setup() {
      Serial.begin(9600);
      pinMode(A0, INPUT);
      pinMode(8, OUTPUT);
    }
    void loop() {
      digitalWrite(8, HIGH);
      h0 = analogRead(A0);
      Serial.println(h0);
      delay(1000);
      digitalWrite(8, LOW);
      delay(2000);
    }
    Выдает какие то символы
    И реле, подключенное к 8-му пину щелкает не всегда каждую минуту. Какие то сбои слышны (по 2 щелчка сразу, бывает просто остановится цикл)
     
  5. ostrov

    ostrov Гуру

    Первый вопрос, зачем float?
     
  6. CryNET

    CryNET Гик

    Контакт фиговый, не надежный. Проверьте на отсутствие "соплей" в подключении.
    float бесполезный, т.к. analogRead возвращает int от 0 до 1023, а я замечал, что компилятор не проверяет этот момент. Так что вполне реально, что ложные значения вызваны из-за разности типов данных.

    Если сильно не заморачиваться, то просто измените float на int в вашем скетче.
     
  7. Securbond

    Securbond Гуру

    Скорее всего подключено всё на соплях, отсюда и сбои.
    Реле бывают разные. Необходим подтягивающий резистор для исключения дребезга и ложных срабатываний.
     
  8. user999

    user999 Гик

    далее была формула: h0 = (1.0 - h0 / 1023.0) * 100.0; с двумя знаками после запятой
    с int тоже самое. цикл останавливается через определенное время
     
  9. user999

    user999 Гик

    1. Реле такое: [​IMG]
    На другом проекте 3 штуки таких уже 2 недели без сбоя работают. Резисторы вроде уже на плате есть
    2. Сопли могут быть. Ардуинка помятая пришла.
    Проверю на меге вечером
     
  10. rkit

    rkit Гуру

    Скачки по питанию из-за реле. Зачем оно там? Электричества на делителе напряжения вы так не сэкономите.
     
  11. user999

    user999 Гик

    не рекомендуется датчик почвы оставлять запитанным, что бы он не окислялся. Поэтому переодически с помощью реле подаю нагрузку. Пробовал без реле(A0+gnd+8пин) питать с пина, но результаты не достоверные. При питании с 5v показывает 1023, а с пина 1008. Врет
     
  12. rkit

    rkit Гуру

    Ну тут надо разбираться с питанием с пина.
     
  13. user999

    user999 Гик

    Короче разобрался.
    Все дело было в реле. Оно просто не правильно отрабатывает на таких малых периодах - это раз и два с запозданием подает питание на датчик.
    Поэтому задержку я перенес сразу после включения питания на реле и увеличил задержки для реле
    (без реле задержки датчику не нужны, проверил)
    Код (C++):
    void loop() {
      digitalWrite(8, HIGH);
      delay(2500);
      h0 = analogRead(A0);
      Serial.println(h0);
      digitalWrite(8, LOW);
      delay(2500);
    }
     
  14. user999

    user999 Гик

    Все равно реле иногда подглючивает с питанием. (контакты проверял, все туго)
    Решил брать среднее из 100 значений, вроде получше стало.
    Может кому понадобится:
    Код (C++):
    float h0, h1;
    int i;
    void setup() {
      Serial.begin(9600);
      pinMode(A0, INPUT);
      pinMode(8, OUTPUT);
    }
    void loop() {
      digitalWrite(8, HIGH);
      delay(2500);
      hum();
      h1 = (1 - h1  / 102300) * 100;
      Serial.println(h1);
      h1 = 0;
      i = 0;
      digitalWrite(8, LOW);
      delay(2500);
    }
    void hum() {
      if(i < 100) {
        h0 = analogRead(A0);
        delay(10);
        h1 += h0;
        i++;
        hum();
      }
    }