Help with arrays and debouncing


  • Admin

    Hi All,

    I was wondering if someone could take a look at my code that doesn't seem to be working for me. I am making some internal door sensors (reed switches) to be able to do some more advanced automation (turn on bath fan after door is opened if humidity is over 80% while door is closed etc.). I was trying to use arrays and for loops since much of the logic is the same. I have been able to work out some of my issues so far but I think I am still having some issues with the debouncer (just a guess though). Basically it seems to work ok until a sensor is triggered then it will stop responding to input. Vera logs show nothing. I ran out of time last night and I couldn't get the Arduino logs. I was wondering if someone more experienced than me could spot a glaring error in my code.

    Thanks in advance!

    Pete

        #include <Sensor.h>
        #include <SPI.h>
        #include <EEPROM.h>  
        #include <RF24.h>
        #include <Bounce2.h>
        
        
        /******
        Make sure the Child IDs are in the same array order at the Pins
        For example, if MASTER_DOOR_CHILD is first in the "children" array
        it should be first in the "pins" array
        ******/
        
        //Define Child IDs
        #define MASTER_DOOR_CHILD 1
        #define MASTER_BATH_DOOR_CHILD 2
        #define MASTER_WIN_CHILD 3
        #define GUEST_DOOR_CHILD 6
        #define GUEST_BATH_DOOR_CHILD 11
        #define ASHERS_DOOR_CHILD 16
        #define NATALIES_DOOR_CHILD 21
        
        int children[] = {
          MASTER_DOOR_CHILD,
          MASTER_WIN_CHILD,
          MASTER_BATH_DOOR_CHILD,
          GUEST_DOOR_CHILD,
          GUEST_BATH_DOOR_CHILD,
          ASHERS_DOOR_CHILD,
          NATALIES_DOOR_CHILD
        };
        
        //Pins used on Arduino -- Arduino Digital I/O pin for button/reed switch
        #define MASTER_DOOR_PIN 46
        #define MASTER_BATH_DOOR_PIN 42
        #define MASTER_WIN_PIN 45 
        #define GUEST_DOOR_PIN 48
        #define GUEST_BATH_DOOR_PIN 43
        #define ASHERS_DOOR_PIN 47
        #define NATALIES_DOOR_PIN 44
        
        int pins[]={
          MASTER_DOOR_PIN,
          MASTER_WIN_PIN, 
          MASTER_BATH_DOOR_PIN,
          GUEST_DOOR_PIN,
          GUEST_BATH_DOOR_PIN,
          ASHERS_DOOR_PIN,
          NATALIES_DOOR_PIN
        };
        
        
        Sensor gw(49,53);
        //Bounce debouncer42 = Bounce();
        //Bounce debouncer43 = Bounce();
        //Bounce debouncer44 = Bounce();
        //Bounce debouncer45 = Bounce();
        //Bounce debouncer46 = Bounce();
        //Bounce debouncer47 = Bounce();
        //Bounce debouncer48 = Bounce();
        
        //Set up debouncer
        Bounce debouncer[] = {
          Bounce(),
          Bounce(),
          Bounce(),
          Bounce(),
          Bounce(),
          Bounce(),
          Bounce(),
        };
        
        //used to keep track of previous value of switches
        int oldValue[] = {-1,-1,-1,-1,-1,-1,-1};
        
        #define NUMCHILDREN sizeof(children)//gives size of array *helps for adding buttons -- 
        //this did not seem to work.  It gave me 8 instead of 7 and caused the Mega to restart every Loop cycle
        
        void setup()  
        {  
          gw.begin();
          // Send the sketch version information to the gateway and Controller
          gw.sendSketchInfo("Door Window Sensors Mega", "1.0");
          
          //Set up Arduino
          for(int i=0;i<NUMCHILDREN;i++){
            
            // Setup the pins
            //pinMode(MASTER_WIN_PIN,INPUT); //Old Code
            
            //New code with FOR loop
            pinMode(pins[i],INPUT);
            
            // Activate internal pull-up
            //digitalWrite(MASTER_WIN_PIN,HIGH); //Old Code
            digitalWrite(pins[i],HIGH);
            
            // After setting up the button, setup debouncer
            //debouncer45.attach(MASTER_WIN_PIN);
            //debouncer45.interval(5);
            debouncer[i].attach(pins[i]);
            debouncer[i].interval(5);
          }
          
          // Register binary input sensor to gw (they will be created as child devices)
          // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
          // If S_LIGHT is used, remember to update variable type you send in below.
          gw.sendSensorPresentation(MASTER_WIN_CHILD, S_MOTION); 
          gw.sendSensorPresentation(MASTER_DOOR_CHILD, S_DOOR); 
          gw.sendSensorPresentation(MASTER_BATH_DOOR_CHILD, S_DOOR);
          gw.sendSensorPresentation(GUEST_DOOR_CHILD, S_DOOR);
          gw.sendSensorPresentation(GUEST_BATH_DOOR_CHILD, S_DOOR);
          gw.sendSensorPresentation(ASHERS_DOOR_CHILD, S_DOOR);
          gw.sendSensorPresentation(NATALIES_DOOR_CHILD, S_DOOR);
        Serial.print("In the setup");
          
        }
        
        
        //  Check if digital input has changed and send in new value
        void loop() 
        {
          Serial.print("In Loop Function");
            
          for(int i=0;i<7;i++){
            Serial.print("In the For loop. Value of i is: ");
            Serial.println(i);
            debouncer[i].update();
            // Get the update value
            int value = debouncer[i].read();
            Serial.print("Value is: ");
            Serial.println(value);
            if (value != oldValue[i]) {
               // Send in the new value
               gw.sendVariable(children[i], V_TRIPPED, value==HIGH ? "1" : "0");  // Change to V_LIGHT if you use S_LIGHT in presentation above
               oldValue[i] = value;
               Serial.print("In the old value If value is");
               Serial.println(oldValue[i]);
            }
          }
        }

  • Code Contributor

    I am not by a computer now but :

    define NUMCHILDREN sizeof(children)

    children = 8 chars.. 🙂 you cant define that like so. The compiler will try to do a size of before code is compiled.

    The correct way would be uint8_t numchildren = sizeof(children); as your first line of code.
    and note, dont have a habit of using INT as standard (2 bytes, -32,768 to 32,767)


  • Mod

    @Damme no, that's not true....
    Children is an array of int. Sizeof(int) = 2, sizeof(children) = size of the whole structure = 8*sizeof(int) = 14

    I usually define a macro to get the number of elements in an array:
    #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

    Then use as:

    for(int I = 0; I < ARRAY_SIZE(children); ++I)
      ....

  • Code Contributor

    @Yveaux Hmm, you're right. I didsomething just the other day and realized that it was sizing the variable as a string, not the content of variable itself! and it was somthing like in this example.Hmm, too bad I didn't remenber correcly.. 🙂


  • Admin

    @Yveaux said:

    I usually define a macro to get the number of elements in an array:

    #define ARRAY_SIZE(x)      (sizeof(x)/sizeof(x[0]))
    

    Great, thanks. Just so I'm clear, I would just paste in the line of code above as is? I don't need to substitute x for anything else?

    I was also just thinking... Is there any problem with having multiple Bounce objects in the array like I did?

    Thanks again. I'll try this tonight when I get home.


  • Admin

    @Damme said:

    and note, dont have a habit of using INT as standard (2 bytes, -32,768 to 32,767)
    

    Sorry forgot to respond to this before. What would you recommend I use instead, byte?

    Thanks.


  • Mod

    @petewill said:

    What would you recommend I use instead, byte?

    uint8_t, which is effectively an unsigned char or byte.

    Bit more typing, but I prefer making things explicit.
    Also no discussion on the size if you ever decide to port your code to a different platform (regular int on ATMega is 8bit, Arduino defines it as 16bit, on 32bit intel x86 or e.g. Raspberry Pi it is 32bit and on 64bit intel x64 it is 64bit !!)


  • Admin

    Ok, making progress. I think I have more problems than just my code. I am using a Mega so I can get more inputs and apparently I don't have something wired quite right. My sensors are sending 10 times but then stop because they are not receiving an Ack. That will then cause my node to time out. It seems I don't have the radio wired correctly. Any idea which pin is wrong? The sends are working fine when going to Vera (at least until the timeout). Here is what I'm getting in the serial monitor:

        Relaying message back to gateway.
        Tx: fr=12,to=0,la=12,ne=0,ci=21,mt=1,ty=16,cr=235: 0
        Ack: receive timeout
        Natalie's Door: 0
        
        Relaying message back to gateway.
        Tx: fr=12,to=0,la=12,ne=0,ci=21,mt=1,ty=16,cr=140: 1
        Ack: receive timeout
        Natalie's Door: 1
        
        Relaying message back to gateway.
        Tx: fr=12,to=0,la=12,ne=0,ci=21,mt=1,ty=16,cr=235: 0
        Ack: receive timeout
        Natalie's Door: 0
        
        Relaying message back to gateway.
        Tx: fr=12,to=0,la=12,ne=0,ci=21,mt=1,ty=16,cr=140: 1
        Ack: receive timeout
        Open ping reading pipe: 12
        Tx: fr=12,to=255,la=12,ne=255,ci=255,mt=4,ty=9,cr=85: 
        No relay nodes was found. Trying again in 10 seconds.
        Tx: fr=12,to=255,la=12,ne=255,ci=255,mt=4,ty=9,cr=85: 
        No relay nodes was found. Trying again in 10 seconds.
        Tx: fr=12,to=255,la=12,ne=255,ci=255,mt=4,ty=9,cr=85: 
        No relay nodes was found. Trying again in 10 seconds.
    

    Thanks!


  • Admin

    Probably should have done some more testing before posting. Just anxious to get this working before I have to go to bed...

    I figured out the problem. I had to put a capacitor across my radio 3.3v and ground pins. I haven't had to do this with any of my pro mini sensors so I forgot that may be an issue. Anyway, after doing that I got an Ack: received OK message!

    Hopefully my mistakes can help someone else avoid them...

    20140805_195725.jpg


  • Admin

    Ok, looks like I was wrong again. Turns out was a bad wire (or wires) connecting the radio to the Mega. Either that or the Mega has some bad connections. Anyway, I switched out the wires and all is working again (for now).


  • Hero Member

    @petewill said:

    Ok, looks like I was wrong again. Turns out was a bad wire (or wires) connecting the radio to the Mega. Either that or the Mega has some bad connections. Anyway, I switched out the wires and all is working again (for now).

    Loose wires are a bear to find at times - you do something (like adding a cap) and you think you fixed it. Then for no good reason the problem comes back. Been there.


Log in to reply
 

Suggested Topics

  • 1
  • 1
  • 6
  • 1
  • 3
  • 1

65
Online

11.4k
Users

11.1k
Topics

112.7k
Posts