I'm working on a power regulator that takes user input from two different devices, and controls one output: a power driver.
I'd like to validate the modular design of my firmware with you.
The two input methods tell my device to output more or less power:
- a pair of buttons: one for less power, one for more
- a scroll wheel: turn left for less power, right for more.
The output is a PWM signal where the duty cycle defines the power going to the ballast.
My initial design was with a scroll wheel only, and I didn't pay too much attention on where to keep the state. I just kept it with the scroll wheel logic. Turning the wheel up or down changed that state.
My control loop would read the scroll wheel's value at regular times. If it had changed, it would change the duty cycle of the output.
My new design uses both the scroll wheel and up/down buttons.
It shouldn't matter for the output if the user scrolls the wheel, or presses the buttons. It should react just the same.
I could keep the state of the output in the main loop, or in the output module. I choose the latter.
I changed the scroll wheel module to keep a delta change state in stead of an absolute value. If you turn it, that will result in a positive or negative value depending on how you turned it. It has a value of 0 if you didn't touch the scroll wheel.
I did the same logic for the button module, but the delta is -1 for the down button, +1 when the up button is pushed. 0 when none is pushed.
My main module is rather stupid. It just polls the delta of the modules, and sends it to the output module.
The output module will apply that delta to it's current value and regulate the duty cycle of its signal accordingly.
It also guards the border conditions like min and max.
In total I have 3 layers
- peripheral driver
- my module
- the control loop
There's the peripheral driver from the supplier (the GIO, QUADRATURE DECODE and PWM drivers). They talk to the physical inputs and outputs. My main module doesn't know about them.
Above each driver, there's my own module. These translates the input events into a usable value and handles things like debounce for buttons and wrap-around for the scroll wheel.
The output module translates output values into PWM duty cycle change commands.
The control loop is the glue. It polls the inputs, without going to the driver level. It asks my own module that's on top of that. And it calls my own output module if anything interesting happened at the input side.
It all works. I can fairly easily add new input methods (there's ethernet hardware on my module, so I could take commands from there too, or a capacitive sense control?).
But how would you approach this? Feel free to bash my design, give advise on better approaches. Or share your typical way of working.
Thanks!