для измерения времени между сигналом ВКЛ и сигналом ВЫКЛ

int pin_state = LOW;    
struct Channel {  
    byte pin;  
    byte state;  
    byte count;  
    unsigned long fell, rose;    
};  

const int CHANNEL_COUNT = 3;  
Channel channels[CHANNEL_COUNT] = {  
    { 2, LOW, 0, 0 },  
    { 3, LOW, 0, 0 },  
    //{ 4, LOW, 0, 0 },  
    //{ 5, LOW, 0, 0 },
    //{ 6, LOW, 0, 0 }
};

void setup()
{
    for (int i = 2; i <= CHANNEL_COUNT; ++i) {
        pinMode(channels[i].pin, INPUT);
    }
    Serial.begin(9600);
    //Serial.println("pin,fell,rose,low time");
    Serial.println("Minutes, Seconds, Count");
}

void loop()
{
    for (int i = 0; i < CHANNEL_COUNT; ++i) 
    {
        Channel &c = channels[i];
        byte new_state = digitalRead(c.pin);
        if (c.state == LOW && new_state == HIGH)    
        {  
            c.rose = millis();
            c.count = c.count + 1;
        }
        else if (c.state == HIGH && new_state == LOW)  
        {  
            c.fell = millis();
            display_channel(c);
        }
        c.state = new_state;
    }
}

void display_channel(const Channel &c)
{
  int minutes, seconds;
  unsigned long difference;
  difference = c.fell - c.rose;
  seconds = int(difference/1000);
  if (seconds >= 60)
  {
       minutes = seconds / 60;
       seconds = seconds % 60;
  }
    //Serial.print(difference/1000);
    //Serial.print(",");
    Serial.print(minutes);
    Serial.print(",");
    Serial.print(seconds/1000);
    Serial.print(",");
    Serial.println(c.count-1);
    //Serial.print(",");
  }

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

, 👍0

Обсуждение

Подсказка: возможно, вам захочется проверить, как вы обрабатываете индекс вектора канала, инициализацию выводов и т. д. В эскизе много тривиальных ошибок., @Mikael Patel

Не могли бы вы предоставить лучший код решения ошибок, поскольку я не могу их найти., @Rajesh Anand10

Проверьте ответ Маженко ниже. Намеки он понял :)., @Mikael Patel


1 ответ


3

Вот каталог ошибок, которые я вижу на первый взгляд:

const int CHANNEL_COUNT = 3;  
Channel channels[CHANNEL_COUNT] = {  
    { 2, LOW, 0, 0 },  
    { 3, LOW, 0, 0 },  
    //{ 4, LOW, 0, 0 },  
    //{ 5, LOW, 0, 0 },
    //{ 6, LOW, 0, 0 }
};

Вы устанавливаете место для 3 записей, но заполняете только 2. Кроме того, структура канала имеет 5 записей, а не 4. Вы не инициализируете 5-ю запись (rose) (хотя она будет для вас инициализировано значением 0 - хотя лучше быть явным).


for (int i = 2; i <= CHANNEL_COUNT; ++i) {
    pinMode(channels[i].pin, INPUT);
}

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


for (int i = 0; i < CHANNEL_COUNT; ++i) 

Вы заполнили только 2 из трех записей. Однако вы используете третий, как если бы он был заполнен.


Serial.print(minutes);

Если секунд меньше 60, то минуты здесь не определены.


Я бы предложил изменить ваш код так, чтобы Channel был классом, и встроить в него код для управления этим классом.


  • Бонусное время

Вот ваша программа, переписанная с использованием класса. В качестве дополнительного бонуса я добавил автоматическое присвоение номера канала каждому объекту при его создании. Чтобы добавить больше каналов, просто добавьте номер контакта в список инициализации.

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(_channel);
            Serial.print(",");
            Serial.print(mins);
            Serial.print(",");
            Serial.print(secs);
            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) { // Fell
                    _fall = millis();
                    _count++;
                    display();
                } else {
                    _rise = millis();
                }
            }
        }
        void begin() {
            pinMode(_pin, INPUT);
        }
};

uint8_t Channel::channelCount = 0;

Channel channels[] = { 2, 3 };
#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();
    }   
}
,

Класс в Arduino такой же, как и в Python, так как я только начинаю с Arduino. В этом случае будет полезен модифицированный код :), @Rajesh Anand10

Да, концепция класса та же самая (это стандартный термин объектно-ориентированного программирования), но способ работы с ними и синтаксис разные. Вам следует проверить некоторые из множества библиотек — почти все они используют классы., @Majenko

@ RajeshAnand10 Я переписал твою программу, используя класс. Там нет комментариев. Вам предстоит разобрать его и понять, что он делает и как он это делает., @Majenko

Но не похоже, что два контакта могут обрабатывать один и тот же «voidprocess()», когда два входа поступают одновременно, верно?, @Rajesh Anand10

У каждого вывода есть свой собственный voidprocess(), и одновременного выполнения не существует., @Majenko

Здесь счетчик продолжает увеличиваться, когда на выводе низкий уровень, но мне нужен счетчик только тогда, когда на выводе низкий уровень. Я имею в виду, что подсчетом фактически является количество раз, когда булавка становится низкой, а не то, как долго она остается низкой. Как мне соответствующим образом перейти к этому состоянию, поскольку я даже не могу использовать команду Break, поскольку ее нет в структуре цикла?, @Rajesh Anand10