Intro
I am doing some work with Raspberry PI GPIO. Until now I was writing code as you would in C, using functions to group together sections of code.
My work has got to the point where I am happy that everything is working, but now things are starting to get messy and so I would like to move towards an object oriented approach.
Problem
Here is the problem I face.
At the moment I have a class which represents my "device". (The hardware I built which is attached to the GPIO port.) The hardware has 2 distinct sections. One section is an "input" section, and the other is an "output" section.
To help you understand this better, the "input" section is an ADC. (Analog-to-digital converter.) This is a device which converts an analog signal to a 10bit binary representation. (In case you were not familiar with electronics.)
The "output" section is just a transistor which switches a set of LEDs on and off.
I wanted to have a class which represented the ADC Board, and one which represented the LED Board, as they are 2 conceptually different devices, as they are not "linked" in any way.
This causes a problem, as the GPIO pins must be set to certain values before their modes are set. By values I mean "HIGH" or "LOW", 1 or 0. By modes I mean "INPUT" or "OUTPUT". This sounds strange, but basically, the ADC will become de-synchronized if the control lines are not set to their correct LOGIC HIGH and LOGIC LOW values before it is powered up. (This is a very strange device, it does not power up until it is told to, even though it is connected to power. (VCC or VDD 5.0V) One of the control lines sends a signal to power up the device.
In order to carry out the above, consider that the GPIO pins are initially in INPUT mode. To "make the ADC work properly" we first set the data values (HIGH / LOW) which are to be present on the pins BEFORE they are changed to OUTPUT mode. This way, when the mode is changed from INPUT to OUTPUT the data is present which the correct values, and we won't upset the ADC.
My initial idea was to have a constructor for the ADC which firstly sets the values for output data and then changes the requires pins from INPUT mode to OUTPUT mode. But this forces us to construct the ADC Board class before the LED Board class.
This can be fixed by both constructors carrying out the same code to set the output modes, but this seems like a bad idea because we are calling 2 bits of code twice - not a very elegant solution.
Another solution is to have a GPIOPort class which combines the input and output devices together, but this isn't very elegant either and it would be difficult to modify if we were to ever add a second, identical, LED Board. (For example.)
What I think I want but I'm not sure...
I think what I want is another class which represents the GPIOPort itself. (A kind of abstract idea, I guess?) Then I think I want "a class within a class" to represent the ADC Board and "a class within a class" to represent the LED Board, also. I can't remember what this technique is called, but usually the "outer class" is like a shell, with a pointer to an object of the type which is the "inner class" and a create method and a destroy method. The outer class does something like pointer = new type;
in the create method and delete pointer
in the destroy method. This allows the constructor to be called when required, and the class destructor to be called when required.
The point of this is that the GPIOPort class constructor handles the order in which these objects are created, which hides everything from main(). Within main, the programmer just does something like GPIOPort myGPIOPort;
, and this handles everything you need, so you don't have to include 20 lines of code in main() to setup the data for the output pins, which is the only other solution. (Which I didn't mention above.)
Questions
So my first question is what is this technique known as? I thought it was called a wrapper class, but my understanding is a wrapper class is for using fundamental types like double
and int
as objects. (And adding methods like clear()
or reset()
or something like that.) Is this what I actually want to be doing, or is there a better method? (I guess it comes down to "how do I fix my problem".)
My second question is that, as far as I can remember, I have to make some of the methods (the destructor?) virtual methods, but I can't remember why. (Or perhaps I don't, and I'm just confused.)
My third question is are there any examples of this which I can use to help myself understand it, or alternatively, where can I go to improve my understanding. (Resources.)
Thanks, obviously this is quite a long question. I tried to include as much information as I could to help explain the situation. If you want clarification, then I'll try and improve what I said.
Edit: More info on devices
The data must be sent to the GPIO pins before their mode is changed from input to output.
The GPIO pins look like all zeros, as there are pull-down resistors on the pins, and they are still set as inputs. The data which as been sent does not appear until their mode is changed.
The pins are then set to output mode. (Or some of them are anyway.) Now the data which was sent appears on the pins.
If the pins are set to output mode before the data is sent, we cannot prevent the ADC from powering up, as the data pin which controls the powering up of the ADC may be set to HIGH. It may be set to LOW, but there is no way of telling, its state is undefined, until we tell the GPIO what values we want before setting the mode to output. Luckily, we can guarantee that all the pins will be in input mode.