Right, I made a NES controller emulator using a Wii nunchuk. The protocol was a tiny bit obscure (one latch pulse and seven clock pulses) but I got there. For timing reasons I made a tight loop where it waited for latch, and then clocked out the 8 values. Then in the 1/60th of a second I should have available I read the nunchuk ready for next time.
// NES controller emulator using Wii nunchuk
// Author: Nick Gammon
// Date: 1st December 2013
#include <Nunchuk.h>
#include <Wire.h>
const byte JOYSTICK_LOW_THESHOLD = 100;
const byte JOYSTICK_HIGH_THESHOLD = 200;
void setup ()
{
// don't have bogus initial data
pinMode (12, INPUT_PULLUP);
// initialize nunchuk
Nunchuk::begin ();
// first read
Nunchuk::read ();
} // end of setup
byte reply [8]; // A, B, SELECT, START, UP, DOWN, LEFT, RIGHT
void loop ()
{
reply [0] = Nunchuk::z_button; // A
reply [1] = Nunchuk::c_button; // B
reply [2] = 0; // SELECT ??
reply [3] = Nunchuk::c_button && Nunchuk::z_button; // START (both Z and C buttons together)
reply [4] = Nunchuk::joy_y_axis > JOYSTICK_HIGH_THESHOLD; // UP
reply [5] = Nunchuk::joy_y_axis < JOYSTICK_LOW_THESHOLD; // DOWN
reply [6] = Nunchuk::joy_x_axis < JOYSTICK_LOW_THESHOLD; // LEFT
reply [7] = Nunchuk::joy_x_axis > JOYSTICK_HIGH_THESHOLD; // RIGHT
noInterrupts ();
// wait for LATCH (pin 10) to go high
while ((PINB & bit(2)) == 0)
{ }
PORTB |= bit (4); // start off with HIGH output
DDRB |= bit (4); // set MISO (pin 12) to output
// wait for LATCH (pin 10) to go low again
while (PINB & bit(2))
{ }
// After LATCH we immediately output the first bit
// set MISO (pin 12) to appropriate value for the "A" button
if (reply [0])
PORTB &= ~bit (4);
else
PORTB |= bit (4);
// do 7 more data pulses
for (byte i = 1; i < 8; i++)
{
// wait for CLOCK (pin 13) to go high
while ((PINB & bit(5)) == 0)
{ }
// set MISO (pin 12) to appropriate value
if (reply [i])
PORTB &= ~bit (4);
else
PORTB |= bit (4);
// wait for CLOCK (pin 13) to go low
while (PINB & bit(5))
{ }
} // end of 8 pulses
PORTB |= bit (4); // end off with HIGH output
DDRB &= ~bit (4); // set MISO (pin 12) to input
interrupts ();
// read for next time around
Nunchuk::read ();
} // end of loop
With the assistance of that I was able to play the game. Now I'll take a look at how the code works.