Странное поведение при использовании Serial.println

noKraps
Offline
Зарегистрирован: 15.10.2021

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

Делаю обработку логики для бесключевого доступа в авто. Ручки (с датчиками) подключены напрямую в аналоговые входы А0, А1 и тд. Сами пины в состоянии OUTPUT / HIGH. Логика датчиков в самой ручке такая - при подаче питания происходит калибровка (значения с пинов схожи с показаниями открыти/закрытие), далее начинают работать в обычном режиме. Я пошел по пути просто мониторить просадку напряжения на пинах.

Собственно с самой логикой я разобрался, но вот есть странность при фильтровании этой "калибровки". Алгоритм у меня такой: датчик в ручке выдает определенный сигнал (просадку при analogRead) и вот если убрать Serial.println то код сразу прыгает в условие, где делает calibration = false, при этом если вернуть Serial.println, то код начинает отрабатывать корректно. CALIBRATION_VAL это сумма значений с пина, получается всегда одинаковым, то есть я на него и ориентируюсь.

У меня пока такая мысль, что без использования Serial.println код либо быстрее отрабатывает либо раньше (до включения ручки) отсюда и завышенное значение. Но возможно я написал бред) Помогите пожалуйста. 

Вот кусок скетча
 

const byte DOORS[] = {A0,A1,A2,A3};
const byte OPERATING[] = {4,5};

const int unsigned CHECK = 20;
const int unsigned SLEEP_PIN = 3;
const int unsigned TRIGGER_VALUE = 1000;
const unsigned long CALIBRATION_VAL = 258000;

void setup() {
  for (byte i = 0; i < sizeof(DOORS); i++) {
    pinMode(DOORS[i], OUTPUT);
    digitalWrite(DOORS[i], HIGH);
  }

  for (byte i = 0; i < sizeof(OPERATING); i++) {
    pinMode(OPERATING[i], OUTPUT);
    digitalWrite(OPERATING[i], LOW);
  }


  Serial.begin(9600);
}

bool calibration = true;

void loop() {
  volatile unsigned long cVal = 0;

  while (calibration) { // calibration handle
    cVal = cVal + analogRead(DOORS[0]);
    // Serial.println(cVal);
    if (cVal > CALIBRATION_VAL) {
      calibration = false;
      cVal = 0;
    }
  }

  for (byte i = 0; i < sizeof(DOORS); i++) { // handle doors
    int unsigned val = analogRead(DOORS[i]);
    if (val < TRIGGER_VALUE) handle(DOORS[i]);
  }
}

 

noKraps
Offline
Зарегистрирован: 15.10.2021

К слову если использовать Serial.println до цикла, то тоже отрабатывает корректно

rkit
Offline
Зарегистрирован: 23.11.2016

Естественно быстрее. Ты думал, println - эльфийская магия и времени не занимает?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Паузу поставьте на место Serial.println(cVal); 50 миллисекунд и все заработает.

Слишком шустро опрашиваете ИМХО.

noKraps
Offline
Зарегистрирован: 15.10.2021

Да с паузой работает, но дольше. Тогда надо новый алгоритм придумать. Потому с delay играться или Serial юзать не идеально получается. В любом случае спасибо что ткнули носом, пойду думать.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Если нужна скорость и нормальный АЦП - используйте другой контроллер. Например STM32 - с ардуинкой это предел.

noKraps
Offline
Зарегистрирован: 15.10.2021

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

b707
Offline
Зарегистрирован: 26.05.2017

noKraps пишет:

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

задержку можете понизить раз в десять, как минимум. 50мс это перебор. Ардуина междленная, но не настолько :)

noKraps
Offline
Зарегистрирован: 15.10.2021

Я 5мс поставил, все довольно прогнозируемо)