UnoJoy Questions. Guidance needed.

Okay, Long story as short as possible, I had a switchboard for the PC that I was using for various games, Using a leonardo, 7 toggle switches, 3 buttons, And a rotary encoder, Along with a bunch of LEDs. I was using that to feed keyboard commands into whatever game I was using it for, No problem.

Now, I wanted to upgrade. I now have a setup where I have 12 pushbuttons(momentary) 18 toggles, 5 POTs, and 7 rotary encoders, And will eventually have LEDs for most of them also... So I upgraded to a mega 2560 and unojoy/megajoy.

It works flawlessly as it should with the provided code, But I am having issues with the toggle switches, and rotary encoders. How Am I supposed to implement these into unojoy/megajoy? I cant seem to find any kinds of examples out there to help me along.

Here is the sample code given, Which is what I am using and works great, As long as its a button, Or you double flip the toggle.. But thats not what I am looking for. I need the toggles to act as a button press and release rather than a hold(on most of the toggles)

Plus I need to figure out how to tie in the rotary encoders to act as quick button presses also.

I am not that tech savy with the code, i have no idea what an array is... But I can understand 80% of whats going on... and I have a feeling thats where changes need to be made...

any guidance and others with experience with unojoy feel free to show me the way. :slight_smile:

The toggle switches should be fairly easy. Did you want the ON and OFF toggles to press the same button or different buttons?

The included example code just copies all digital pins to bits in an array:

for (int i = 2; i < 54; i++){
    controllerData.buttonArray[(i - 2) / 8] |= (!digitalRead(i)) << ((i - 2) % 8);
}

To treat any pin specially you would need to read the pin state and deal with state changes:

for (int i=0; i<TogglePinCount; i++) {
    boolean newState = !digitalRead(TogglePins[i])
    if (newState != TogglePreviousState[i]) {
        // Toggle switch has changed state
        if (newState) { // Toggle just switched ON
             setButtonState(ToggleOnButton, HIGH);  // Show the button as pressed
        } else {
             // Toggle just switched OFF
             setButtonState(ToggleOffButton, HIGH);  // Show the button as pressed
        }
    } else { // Not a state change
        // Toggle switch has not changed state
             setButtonState(ToggleOnButton, LOW);  // Show the button as released
             setButtonState(ToggleOffButton, LOW);  // Show the button as released
        }
    }

The 'setButtonState()' function would set a bit in the button state array, like in the example:

void setButtonState(unsigned int index, boolean value) {
    controllerData.buttonArray[index/8] |= value << (index%8);
}

Yes, I should of mentioned that I could write that part, :stuck_out_tongue: and yes.. each toggle will press the same virtual button when it is switched to on and off.

But the big thing is, How to tie the toggle state change to this "controllerData.Button" part?

How is the arduino actually passing information to the serial controller?

I cant simply digitalwrite or serialwrite like i can normally with a normal arduino...

Where is the controller data at the end of the script getting "returned" to?

Its getting hard to explain...

Wait.. I think I see what your saying..

maybe its simply this "for" statement thats screwing me up..

im used to writing out code for each and every pin.. not in a single line.

what if the toggle pins and button pins are mixed? i could just rewire if needed.. But doing it in the code may be easier.

  controllerData.buttonArray[(i - 2) / 8] |= (!digitalRead(i)) << ((i - 2) % 8);

this line is bugging me too.. i just cant wrap my head around how this line works.

  controllerData.buttonArray[(i - 2) / 8] |= (!digitalRead(i)) << ((i - 2) % 8);

Let's break it down. The 'i' variable is looping through pin numbers starting at Pin 2. Array indexes start at 0 so that is why '(i-2)' is used in two places.

int bitIndex = i-2;
  controllerData.buttonArray[bitIndex / 8] |= (!digitalRead(i)) << (bitIndex % 8);

The pins have the internal pull-up resistor enabled so they read HIGH/1/true when not connected and LOW/0/false when the button is pressed (or switch is closed) connecting them to Ground. The logical inversion operator '!' is used the make the button state true/1 when pressed and false/0 when not pressed.

int bitIndex = i-2;
boolean buttonState = !digitalRead(i);
  controllerData.buttonArray[bitIndex / 8] |= buttonState << (bitIndex % 8);

The array is an array of bytes, each containing 8 bits. We want to manipulate an individual bit.

int bitIndex = i-2;
boolean buttonState = !digitalRead(i);
int byteIndex = bitIndex / 8;
int bit = bitIndex % 8;  // Remainder when divided by 8
byte bitMask = buttonState << bit;  // Shift the bit to the correct mask position
  controllerData.buttonArray[byteIndex]  |=  bitMask;

The logical OR operator '|' will turn the bit ON if buttonState is 'true'.

Does is make sense now?

Thanks

I think i understand now.

i now know i need to brush up on my coding some more.

Never had to use code where bytes and bit shifts were needed.

johnwasser: Old question, the equivalent of the array of bits is:
controllerData.buttonArray[byte][bit]=TRUE or FALSE ?
or
controllerData.buttonArray[indexByte*8+bit?]

thaks you