I have hit a wall trying to work out the best way to assign multiple outputs to single inputs using the shift registers in my project.
My project is a train layout controller and will be taking inputs from a human and switching outputs on the train layout - pretty simple.
ie. A button will trigger an LED to illuminate, another light to come on and a solenoid to fire. This is just an example of something I may want to do on this train layout.
I am prototyping with 74HC165's for inputs and 74HC595's for outputs. Communication is via SPI and I'm buffering each shift register with 74HC125's to test the high impedance state allowing other SPI devices on the same bus as well as buffering the clock, latch and MISO/MOSI lines to avoid fan-out issues when I scale this up. The final project will have approx 6 x input shift registers and 8 x output shift registers - ie. 6 bytes of input and 8 bytes of output.
I am struggling a bit with the data structures to represent the layout inputs / outputs and then how I assign multiple outputs to a single input.
I'll prefix the following with a disclaimer about me knowing Python and Ruby and not so much C++ !
I decided to play with C++ structs to build a data structure that represented inputs and outputs to capture things like what shift register pin number, name for printing out to screens etc.
The code I have come up with is below. I am not sure of the appropriate way to find the bits that changed (or if I even have to). I am XOR'ing individual bytes to work out if the byte as a whole has changed as I read them from the shift registers, but not sure how to get the bit position number of the bit that changed (you'll see why I think I need to do that in the comments). Maybe I just go through each button and find the outputs and build the individual bytes to send to the shift registers.
I don't want a massive switch / case statement. I want to set the attributes in the struct declarations.
I think what I want to do is as follows:
- Read a byte from each input shift register into an array
- Iterate through this array and compare the new byte to a previous version of the byte and work out if it changed
- Now I know if a button has been pressed
- Work out what bit position changed don't know how to do this - possibly just iterate through every bit 0's and 1's and find the associated outputs
- Iterate through the button_t object for the bit identified above and find the outputs associated with it
- Set the output bits in the appropriate byte with bitSet() / bitClear()
- Do this for all changed bits identified
- Write the chain of bytes to the output shift registers
I'm not sure of the most efficient bitwise tools to use to accomplish this. Knowing how I think about code there is probably an easier way to do this but the simple requirements are:
- Read a button
- Find that button's associated outputs (one or many)
- Set the outputs state
- Repeat
I am not a software engineer or an electronics engineer - I am using this project as a way to learn more about both fields.
Latest code in post #6 below