0
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(",");
  }

When I try to run the program, I don't get any output. Is there anything wrong with the code, that must be solved before any output can get displayed?

  • 1
    Hint: Might want to check how you handle channel vector index, pin initialization, etc. There are many trivial mistakes in the sketch. – Mikael Patel Jan 2 at 13:48
  • Could you provide a better solution code for the mistakes as i cant find any. – Rajesh Anand10 Jan 2 at 14:44
  • Check the answer provided below by Majenko. He understood the hints :). – Mikael Patel Jan 2 at 15:09
3

Here's the catalog of errors I see at first glance:

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 }
};

You set up space for 3 entries but only fill 2. Also, the Channel structure has 5 entries, not 4. You don't initialize the 5th (rose) entry (although it will be initialized to 0 for you - best to be explicit though).


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

You start from entry number 2 (the third entry) and iterate to the 4th (non-existent) entry to set the pin mode of either undefined or invalid pins.


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

You have only filled in 2 of the three entries. Yet you use the third as if it were filled in.


Serial.print(minutes);

If seconds is less than 60 then minutes is undefined here.


I would suggest changing your code so that Channel is a class and embed the code to manage that class within it.


  • Bonus Time

Here's your program re-written using a class. As an added bonus I have added automatic allocation of a channel number to each object as it's created. To add more channels just add the pin number into the initialization list.

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();
    }   
}
  • Is class in arduino same as it is in python, as im just starting with arduino. Modified code would be helpful in that case :) – Rajesh Anand10 Jan 2 at 15:17
  • The concept of a class is the same, yes (it's a standard Object Oriented Programming term), but the way of working with them and the syntax is different. You should check some of the many many libraries around - they almost all use classes. – Majenko Jan 2 at 15:19
  • @RajeshAnand10 I have rewritten your program using a class. There's no comments. It's up to you to pull it apart and work out what it's doing and how it's doing it. – Majenko Jan 2 at 19:03
  • will do. Thank you and much appreciated :) – Rajesh Anand10 Jan 4 at 13:20
  • But this doesn't seem like two pins can process the same "void process()" when two inputs come in simultaneously right? – Rajesh Anand10 Jan 5 at 12:01

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.