Passing an array of pins

14 Nov 2013

Hi Folks,

I would like to pass an array of pins to a class so that I can create several instances of the same class on different IO pin. I have been programming in C for many years but C++ is still new to me.

I started out with a simple test in C to explore, but this used a global array and so is not very reusable:

Pin array test

#include "mbed.h"

DigitalOut ArrayOfDigitalOuts[3] = { (p9), (p10), (p11) };

void normal_c_pulse(unsigned int x)
    {
    ArrayOfDigitalOuts[x]=1;      // pulse an IO pin high and then low
    ArrayOfDigitalOuts[x]=0;     
    }

int main()
    {
    while(1)
        {
        normal_c_pulse(0);       // pulse pin p9
        normal_c_pulse(1);       // pulse pin p10
        normal_c_pulse(2);       // pulse pin p11 
        }
    }

Next I found out how to create a class and create an instance with a pin and rewrote the example above using a class:

Pin pulse class

#include "mbed.h"

class Test_One_Pin
    {
    private:
        DigitalOut  pin_A;
 
    public:
        Test_One_Pin(PinName A) : pin_A (A) {}
    
    void pulse(void)
        {
        pin_A = 1;
        pin_A = 0;
        }
     };  

Test_One_Pin pulse1(p9);
Test_One_Pin pulse2(p10);
Test_One_Pin pulse3(p11);

int main()
    {
    while(1)
        {
        pulse1.pulse();     
        pulse2.pulse();   
        pulse3.pulse();   
        }
    }

But what I actually want to do is pass several pins to the class and the number may vary for each instance. i.e these are row selects on a display and some displays have 1 row, some 2 and some 4.

Now being all new to this C++ stuff I tried this, but will not compile at the class / public code.

Test of passing an array of pins to pulse class

#include "mbed.h"
 
class Test_Array_Of_Pins
    {
    private:
        DigitalOut  *pin_array;
        
    public:
      Test_Array_Of_Pins(PinName *A) : pin_array(A) {}
  
    void pulse(unsigned int x)
        {
        pin_array[x] = 1;
        pin_array[x] = 0;    
        }
    };
 
PinName SomePins[] = { p9, p10 , p11 };
PinName SomeOtherPins[] = { p12, p13, p14, p15 };
 
Test_Array_Of_Pins  PulseGroupA( &SomePins[0] );
Test_Array_Of_Pins  PulseGroupB( &SomeOtherPins[0] );
 
int main()
    {
    while(1)
        {
        PulseGroupA.pulse(0);   
        PulseGroupA.pulse(1);  
        PulseGroupA.pulse(2);  
      
        PulseGroupB.pulse(0);   
        PulseGroupB.pulse(1);  
        PulseGroupB.pulse(2); 
        PulseGroupB.pulse(3);     
        }
    }

I hope these stripped down examples are clear and some one has a few moment to educate me so I know what I am doing wrong.

Thanks, Mark Leman

13 Nov 2013

You can define the array of pins on a global level and pass the array to your class instance. That class will then be used to operate on the elements of the array. See http://mbed.org/forum/mbed/topic/3610/ There are more hits when you search the site for "pinname array"

13 Nov 2013

What about using BusOut or BusInOut?

14 Nov 2013

Wim Huiskamp wrote:

You can define the array of pins on a global level and pass the array to your class instance. That class will then be used to operate on the elements of the array. See http://mbed.org/forum/mbed/topic/3610/ There are more hits when you search the site for "pinname array"

Thanks Wim, That works :-) I had found the forum message you quoted but was trying to pass the PinName rather than DigitalOut.

The working code is:

include the mbed library with this snippet

#include "mbed.h"
 
class Test_Array_Of_Pins
    {
    private:
        DigitalOut  *pin_array;
        
    public:
      Test_Array_Of_Pins(DigitalOut *A) : pin_array(A) {}
  
    void pulse(unsigned int x)
        {
        pin_array[x] = 1;
        pin_array[x] = 0;    
        }
    };

DigitalOut SomePins[] = { p9, p10 , p11 };
DigitalOut SomeOtherPins[] = { p12, p13, p14, p15 };
 
Test_Array_Of_Pins  PulseGroupA( &SomePins[0] );
Test_Array_Of_Pins  PulseGroupB( &SomeOtherPins[0] );
 
int main()
    {
    while(1)
        {
        PulseGroupA.pulse(0);   
        PulseGroupA.pulse(1);  
        PulseGroupA.pulse(2);  

        PulseGroupB.pulse(0);   
        PulseGroupB.pulse(1);  
        PulseGroupB.pulse(2); 
        PulseGroupB.pulse(3);   
        }
    }

Thanks again for your assistance.

Regards, Mark Leman

14 Nov 2013

Sam Grove wrote:

What about using BusOut or BusInOut?

Hi Sam, Thanks for the suggestion. I now have it working by passing an array of DigitalOut but your suggestion may be better. Normally I just want to select one line on my display so an array of pins is easier, however a bus would allow me to easily select multiple rows which is useful when you are clocking the same data in to several rows (i.e. to clear the display).

I will have a try later and hopefully add some working example code later.

Thanks again for your time and response. Regards, Mark Leman

14 Nov 2013

Mark Leman wrote:

Thanks Wim, That works :-)

Thanks again for your assistance.

Regards, Mark Leman

Good to hear that it works for your application. You may want to do some sanity check inside the class code to make sure that you cant try to set an output for a value that is outside the valid range of the pin array.

14 Nov 2013

Hi Wim,

Wim Huiskamp wrote:

You may want to do some sanity check inside the class code to make sure that you cant try to set an output for a value that is outside the valid range of the pin array.

Yes I fell for that one as a typo in my original question, I had specified 4 pins in the PulseGroupB array and was using PulseGroupB.pulse with 1..4 rather than 0..3. I have edited the original question to fix this typo so others don't copy my wrong code!. Fortunately in my real code one of the other parameters I pass to the class is the number of selects, so providing the user sets up the class correctly I can trap this condition.

Regards, Mark Leman