Вычисление времени между включением сигнала и выключением сигнала

class Channel 
{
    private:
        uint8_t _pin;
        uint8_t _state;
        uint32_t _rise;
        uint32_t _fall;
        uint8_t _count;
        uint8_t _channel;

        static uint8_t channelCount;

        void display() 
        {
            uint32_t diff = (_fall - _rise) / 1000;
            uint32_t secs = diff % 60;
            uint32_t mins = diff / 60;
          // Serial.print(",");
            Serial.print(_channel);
            Serial.print(",");
            Serial.print(mins);
            Serial.print(",");
            Serial.print(secs-4);
            Serial.print(",");
            Serial.println(_count);
        }

    public:
        Channel(int pin) : _pin(pin), _count(0) 
        {
            _pin = pin;
            _count = 0;
            _channel = channelCount;
            channelCount++;
        }
        void process() 
          {
            int s = digitalRead(_pin);
            if (s != _state) 
              {
                _state = s;
                if (s == LOW)  // Упал
                  { 
                    _fall = millis();
                    _count++;
                    display();
                  } 
                else 
                  {
                    _rise = millis();
                  }
                }
            }
        void begin() 
        {
            pinMode(_pin, INPUT);
        }
};

uint8_t Channel::channelCount = 0;

Channel channels[] = { 3,5 };
#define NUM_CHANNELS (sizeof(channels) / sizeof(channels[0]))

void setup() 
{
    Serial.begin(115200);
    Serial.println("Channel,Minutes,Seconds,Count");
    for (unsigned int i = 0; i < NUM_CHANNELS; i++) 
      {
        channels[i].begin();
      }
}

void loop() 
{
    for (unsigned int i = 0; i < NUM_CHANNELS; i++) 
      {
        channels[i].process();
      }   
}

В некоторых случаях этот код работает нормально, (т. е.) он обеспечивает точное время между включением и выключением сигнала в секундах.

В некоторых случаях он выдает 10-значное число. Правильное значение следует за неизвестным числом на скриншоте, прикрепленном ниже, который был получен при записи вывода

, 👍1

Обсуждение

братан, эти 10 цифр - это максимальное значение 0xFFFFFFFF, которого может достичь 32-битное целое число без знака., @Vaibhav

@Vaibhav: Нет, максимальное значение — 4294967295. Значение, которое он видит, — −4. См. ответ Ризи., @Edgar Bonet

Вы еще не объяснили, почему вы поместили сюда ошибку. Я имею в виду «секунды-4» вместо «секунд»., @Jot

Значения, которые я получаю в секундах, на четыре секунды больше фактического значения. Поэтому я использовал «сек-4» вместо секунд., @Rajesh10


1 ответ


4

Я подозреваю, что секунды иногда равны 0, потому что _rise равен 0? В этом случае вычитание беззнакового целого числа приводит к следующему: secs(0) - 4 = -4 % 2^32, в результате чего получается 4294967292

,

Да, но будет хотя бы одна секунда, в течение которой сигнал будет длиться. (Я получаю 4294967292 три-четыре раза для одного перехода ВКЛ и ВЫКЛ). Есть ли другая возможность, которая могла бы вызвать это появление?, @Rajesh10

Я предлагаю трассировку, то есть распечатку всех переменных в методе Display., @Reezy

Да, но секунды не могут быть равны нулю, в моем случае это будет как минимум от 4 до 5 секунд, поэтому даже если я уберу это «-4», я все равно получу это число, верно?, @Rajesh10