title: Arduino SNES wireless receiver code questions
body: <p>I am building a transmitter and receiver pair for two SNES controllers, as I don't like using long extension cords to get the controllers to reach the couch. I'm using <a href="http://www.atmel.com/devices/atmega328p.aspx" rel="nofollow">ATmega328Ps</a> for the AVRs, with RF24l01 wireless transceivers (using ManiacBugs RF24 library). I am using a modified snesPad library on the transmitter to poll the button states of two controllers and return them as a 32-bit unsigned long, then transmitting that to the receiver. All standard libraries, no issues there (so far).</p>
  
  <p>However, on the receiver side, I have to properly respond to the latch and clock signals from the SNES, and I haven't found any stock libraries for that. For those not familiar with the SNES controllers, they are basically two 8-bit parallel to serial shift registers in series. They latch all of the button states on the rising edge of the latch signal (12&nbsp;µs pulse high, normally low), drive the first bit on the falling edge of latch, and then drive each successive bit on the rising edge of clock (6&nbsp;µs delay from fall of latch, normally high, 6&nbsp;µs low - 6&nbsp;µs high cycle).</p>
  
  <p>I've decided to use an external interrupt to trigger the proper behavior for the latch pulse and each clock pulse. I'm new to programming Arduinos though, and new to C/C++ as well. Although my code will compile, I'm not certain if it will actually function as intended. If someone who has some experience with AVR's could take a look at my code and let me know if it will work, and if not, where and why, I would be very grateful!</p>
  
  <p>Arduino <a href="http://www.arduino.cc/en/Tutorial/Sketch" rel="nofollow">sketch</a> follows:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>/*
     Copyright (C) 2012 John Byers &lt;jbyers2@wgu.edu&gt;
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License
     version 3 as published by the Free Software Foundation
  */
  
  /**
   * Dual Wireless Retro Controller Adapter Transmitter
   *
   * This is the reciever side code for the adapter set.
   */
  
  #include &lt;SPI.h&gt;
  #include &lt;nRF24L01.h&gt;
  #include &lt;RF24.h&gt;
  #include &lt;RF24_config.h&gt;
  
  //
  // Hardware Configuration
  //
  
  RF24 radio(9,10);
  
  //
  // Variable Inits
  //
  
  volatile unsigned long state2 = 0xFFFFFFFF;
  volatile byte i = 0;
  const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
  int strobe = 2;
  int clock = 3;
  volatile int data1 = 5;
  volatile int data2 = 6;
  bool firstLoop = true;
  volatile int status2 = 1;
  
  void setup()
  {
      radio.begin();
      radio.setRetries(0,15);
      radio.enableDynamicPayloads();
      Serial.begin(57600);
      pinMode(strobe, INPUT);
      pinMode(clock, INPUT);
      pinMode(data1, OUTPUT); digitalWrite(data1, LOW);
      pinMode(data2, OUTPUT); digitalWrite(data2, LOW);
  
      radio.openWritingPipe(pipes[1]);
      radio.openReadingPipe(1,pipes[0]);
  
      //
      //Dump the configuration of the RF unit for debugging
      //
  
      radio.printDetails();
  
      //
      //Setup Interupts
      //
  
      attachInterrupt(strobe,latch,RISING);
      attachInterrupt(clock,data,RISING);
  }
  
  void loop()
  {
      if (firstLoop) {
          int status1 = 1;
          bool ok = radio.write( &amp;status1, sizeof(int));
          firstLoop = false;
          radio.startListening();
          if (!ok) {
              Serial.println("sync packet transmission failed");
          }
          else {
              Serial.println("sync packet transmission successful");
          }
      }
      if ( radio.available() )
      {
          unsigned long state = 0;
          radio.read( &amp;state, sizeof(unsigned long) );
          Serial.println(state, BIN);
          state2 = state;
      }
      else
      {
          Serial.println("No data recieved yet");
      }
  }
  
  //Latch interrupt routine
  
  void latch()
  {
      i = 0;
      digitalWrite(data1,HIGH);
      digitalWrite(data2,HIGH);
      digitalWrite(data1,bitRead(state2,i));
      digitalWrite(data2,bitRead(state2,(i+16)));
      Serial.println("Bit0 out");
  }
  
  //Data interrupt routine
  
  void data()
  {
      i++;
      digitalWrite(data1,bitRead(state2,i));
      digitalWrite(data2,bitRead(state2,(i+16)));
      Serial.print("Bit");
      Serial.print(i);
      Serial.println(" out");
      if(i=15)
      {
          digitalWrite(data1,LOW);
          digitalWrite(data2,LOW);
          radio.stopListening();
          int status1 = status2;
          bool ok = radio.write( &amp;status1, sizeof(int));
          if (!ok) {
              Serial.println("sync packet transmission failed");
          }
          else {
              Serial.println("sync packet transmission successful");
          }
          radio.startListening();
      }
  }
  </code></pre>