Arduino неправильно считает

astray
astray аватар
Offline
Зарегистрирован: 21.02.2019

Здравствуйте!

Тема в следующем: запилил алгоритм антидребезга, но у него ложные сработки/несработки.

Сделал трассировку переменных с выводом на экран и получил странные результаты:

 DP11.drebezg: 1 DP11.counter: 1 && 100
 DP11.drebezg: 1 DP11.counter: 2 && 100
 DP11.drebezg: 1 DP11.counter: 3 && 101
 DP11.drebezg: 1 DP11.counter: 4 && 100
 DP11.drebezg: 1 DP11.counter: 5 && 100
 DP11.drebezg: 1 DP11.counter: 6 && 100

Последние 3 цифры проверка условий. Третья результат логического умножения двух первых.

Обратите внимание

DP11.counter: 3 && 101 

Логическое умножение 1 и 0 не может быть 1!

Код вывода строки такой:

      SerialMon.print(" DP11.drebezg: " + String(DP11.drebezg) + " DP11.counter: " + String(DP11.counter) + " && ");
      SerialMon.print(DP11_current_state);
      SerialMon.print(!DP11.state); 
      SerialMon.println((DP11_current_state & !DP11.state));

Следующий пример:

 DP12.drebezg: 1 DP12.counter: 3 && 100
 DP12.drebezg: 1 DP12.counter: 4 && 100
 DP12.drebezg: 1 DP12.counter: 5 && 111
 DP12.drebezg: 1 DP12.counter: 6 && 100

Строки DP12.counter: 5 && 111 не должно быть! Алгоритм исключает её печать! Ну хоть логическое умножение правильно посчитал.

Кто-нибудь может сказать, как такое происходит?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

А где меняется DP11.state? Не в прерывании часом? И, кстати, DP11_current_state & !DP11.state это не логическая операция

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

astray пишет:

Здравствуйте!
Тема в следующем:
Arduino неправильно считает

Здравствуйте!
Тема в следующем:
astray неправильно пишет программу.

Сколько ни старался, но никакого 

astray пишет:

логического умножения

там не нашёл.

astray
astray аватар
Offline
Зарегистрирован: 21.02.2019

ЕвгенийП пишет:

astray пишет:

Здравствуйте!
Тема в следующем:
Arduino неправильно считает

Здравствуйте!
Тема в следующем:
astray неправильно пишет программу.

Сколько ни старался, но никакого 

astray пишет:

логического умножения

там не нашёл.

Коньюнкция

Извините, я не знал, как вы это называете

astray
astray аватар
Offline
Зарегистрирован: 21.02.2019

asam пишет:

А где меняется DP11.state? Не в прерывании часом? И, кстати, DP11_current_state & !DP11.state это не логическая операция

Чтобы сильно не позориться приведу участок кода. Может проясниться что-нибудь:

#define DP11_PIN  2
/* -Класс-------------------------------------- */
class DigitalPin {
  public:
    boolean bounce;    // прыг
    boolean state;     // сейчас
    boolean current;   // сейчас
    volatile uint32_t counter; // сколько
    volatile uint32_t drebezg; // сколько
    byte bouncer;      // время
    void setPin(byte pin);
    const uint8_t bounces = 100;

  private:

    byte _pin;         // номер вывода
};
/* -------------------------------------------- */

Недописанный класс обьекта, из которого берутся переменные

void setup() {
  DP11.setPin(DP11_PIN);
  Timer1.initialize(1000); // 1 ms
  Timer1.attachInterrupt(readS);
}

Запуск по таймеру

void loop() {
  readS();
}

Туловище

void readS() {
   bool DP11_current_state = digitalRead(DP11_PIN);
  /*
     Антидребезг по исправленной технологии Винни-Пуха
  */
  if (DP11_current_state & !DP11.state) { // если прошел фронт изм на выводы
    DP11.bounce = true;                   // запоминаем это
    DP11.bouncer = millis();              // запоминаем, когда
  } else {
    if (DP11_current_state & DP11.bounce && millis() - DP11.bouncer > DP11.bounces ) {
      DP11.bounce = false;                // сброс события изм
      DP11.counter++;                     // засчитываем событие
      
      SerialMon.print(" DP11.drebezg: " + String(DP11.drebezg) + " DP11.counter: " + String(DP11.counter) + " && ");
      SerialMon.print(DP11_current_state);
      SerialMon.print(!DP11.state); 
      SerialMon.println((DP11_current_state & !DP11.state));
      DP11.drebezg = 0;
    }
    DP11.drebezg += 1 * int(!DP11_current_state & DP11.state); // Считаем дребезг только по спадающему фронту
  }
}

И, собственно, сам участок кода, в котором ошибки срабатывания. Как буд-то ячейки памяти меняют свои показания с "0" на "1" в случайный момент времени, из-за этого полезный счетчик 

DP11.counter

выдает ошибки

sadman41
Offline
Зарегистрирован: 19.10.2016

Насколько я понимаю - выводится два одних числа, а результат - от действия над другими двумя.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ТС следует различать это & от этого &&.  Си есть различия в = и == , + от ++  ну и так далее.

 if (DP11_current_state & DP11.bounce && millis() - DP11.bouncer > DP11.bounces ) { // <-  А тут ТС это явно показал 

https://docs.microsoft.com/en-us/cpp/cpp/logical-and-operator-amp-amp?view=vs-2017

https://docs.microsoft.com/en-us/cpp/cpp/bitwise-and-operator-amp?view=v...

 

astray
astray аватар
Offline
Зарегистрирован: 21.02.2019

qwone пишет:

ТС следует различать это & от этого &&.  Си есть различия в = и == , + от ++  ну и так далее.

 if (DP11_current_state & DP11.bounce && millis() - DP11.bouncer > DP11.bounces ) { // <-  А тут ТС это явно показал 

Мне понятна разница между логическим умножением и логическим И. Но для типа данных boolean результат

DP11_current_state & DP11.bounce 

и

DP11_current_state && DP11.bounce

Будет идентичным, не так ли?

 

astray
astray аватар
Offline
Зарегистрирован: 21.02.2019

Нашел ошибку в алгоритме - виноват двойной вызов подпрограммы  readS();

в процедуре setup пот таймеру Timer1 и в процедуре loop.  Лишнее удалил. Тему можно удалять.

Всем спасибо!!!

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

astray пишет:
Будет идентичным, не так ли?

DP11.drebezg: 1 DP11.counter: 1 && 100
DP11.drebezg: 1 DP11.counter: 2 && 100
DP11.drebezg: 1 DP11.counter: 3 && 101
DP11.drebezg: 1 DP11.counter: 4 && 100
DP11.drebezg: 1 DP11.counter: 5 && 100
DP11.drebezg: 1 DP11.counter: 6 && 100

Смотрим начальный топик и удивляемся . Ну да , это что на форуме в подкидного дурака играете, а потом из под полы кидаете козырного туза или джокера.