N64 Controller read data and use it to turn on LED

Hi,
I posted this in Device Hacking but I think it is more of a programming question, I will try to explain clearly. I have decent basic programming knowledge but I am struggling trying to adapt a piece of code for my needs. I am working from this tutorial:

I loaded up the code fine and can read the data in the serial window. What I get is:

0000000000000000 0 0

printed with a delay of (25) so very fast. When you press any of the buttons on the N64 controller I get one of the bits as 4 so if I press lets say the A button I get

0400000000000000 0 0

The last two zeros are the analog stick values, they are of no interest to me here.

What I want to do is two things really

  1. Figure out how to use the unique data for each button press. Ideally I want to be able to hold in 4 buttons on the controller at once for lets say 10 seconds then a Pin will digitalWrite HIGH to light an LED.

  2. Cut out any parts of the existing code that I do not need. The code is for reading N64 controller data and then sending it to be used by an emulator on your computer using Processing.

This program is too complex for me to understand in its entirety at the minute. From what I see I need to have a placeholder for the buttons pressed use an IF statement to say that if the 4 buttons are held for a time duration a pin goes HIGH.

I think I may need something like a serial event?

I tried to use an IF statement to say that

if((N64_raw_dump*, DEC) == 0400000000000000 0 0);*

  • digitalWrite(13, HIGH):*
  • delay(1000);*
    This just makes my LED come on without pressing a button, so I think maybe that is just looking at an array maybe and that value is just a value in an array so it is TRUE and the pin goes high. I can't figure out how to use the data.
    Also if no button is pressed we see all zeros printed constantly so I am not sure how to get around that.
    Has anyone any ideas or pointers here? My main goal here is to understand how to use the data from the controller in a statement or function.
    *I have attached the code and will try post it in the next comment below. It may be too large. *
    N64_Arduino.pde (11.1 KB)

I tried but the code is too large to quote here in its entirety. Hopefully someone can help here as I can't find anyone else that has done this with N64 controller data.

if((N64_raw_dump, DEC) == 0400000000000000 0 0);

That didn't compile, did it?

First, what the hell is that , DEC crap in there for? Just because Serial.print(N64_raw_dump, DEC) means something, does NOT mean that (N64_raw_dump, DEC) means ANYTHING.

You really ought to pay attention to the comments:

    // listen for the expected 8 bytes of data back from the controller and
    // blast it out to the N64_raw_dump array, one bit per byte for extra speed.
    // Afterwards, call translate_raw_data() to interpret the raw data and pack
    // it into the N64_status struct.

and stop trying to use the raw data directly.

The N64_status struct contains two bytes, data1 and data2 that contain values where the bits correspond to the various switches.

You can get the value that corresponds to the state of the Dup switch by using bit manipulation (or the bitRead() macro that hides all that ugly stuff:

   byte DupState = bitRead(N64_status.data2, 4);

Other switches are detailed in different positions in data2. Other switches are detailed in data1. The joystick values are in stick_x and stick_y.

Hi, thank you very much for your pointers and advice. It is much appreciated. I tried a few things with the byte DupState = bitRead(N64_status.data2, 4); but I am not sure how to incorporate it. Now I may be a mile off but i tried the following code and it compiled ok. I am at work at the minute so can't test with the controller until later but hopefully I am at least going the right direction to understand what I need.

I have this in my loop.

unsigned long start_time;
unsigned long stop_time;

do
{
  delay(50);          
  start_time=micros();  

} while ((N64_status.data1 & 0x02 ? 1:0)&&(N64_status.data2 & 32 ? 1:0)&&(N64_status.data2 & 16 ? 1:0)&&(N64_status.data2 & 0x01 ? 1:0));

if (stop_time >= 10000);
stop_time=micros();
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);

What I am trying to say here is while N64 DLeft, CRight, L and R are pressed start the timer. ( pretty sure I am wrong here because I need the timer to stop and reset if I have not held the 4 buttons in for 10 seconds)

When the timer is >= 10 seconds stop the timer and light the LED for a half second and then off.

I know this is likely a laughable attempt but I am determined to figure this out. Any more pointers or direction would be very much appreciated.

Can I use byte DupState = bitRead(N64_status.data2, 4); here instead of what I have attempted? How would I go about this?

if (stop_time >= 10000);

If stop_time is greater than, or equal, 10000, do nothing ( ; ). Otherwise, do nothing. So, why bother with the comparison?

A do/while statement is almost never the right statement. Why are you using a do/while?

What I am trying to say here is while N64 DLeft, CRight, L and R are pressed start the timer.

While? Surely, you mean when.

It is not less efficient to use intermediate variables.

   bool left = N64_status.data1 & 0x02;
   bool right = N64_status.data1 & 0x04; // Or whatever the correct value is
   bool l = N64_status.data1 & 0x08; // Or whatever the correct value is
   bool r = N64_status.data1 & 0x16; // Or whatever the correct value is
   if(left && right && l && r)
   {
      // Record start time

Doing so makes debugging MUCH easier, and the logic is clearer (IMHO).