2 つの SNES コントローラー用の送信機と受信機のペアを構築しています。これは、長い延長コードを使用してコントローラーをソファに届けるのが好きではないからです。RF24l01 ワイヤレス トランシーバー (ManiacBugs RF24 ライブラリを使用) を使用して、AVR にATmega328Pを使用しています。送信機で変更された snesPad ライブラリを使用して、2 つのコントローラーのボタンの状態をポーリングし、それらを 32 ビットの符号なし long として返し、それを受信機に送信しています。すべての標準ライブラリ、問題はありません (これまでのところ)。
ただし、レシーバー側では、SNES からのラッチ信号とクロック信号に適切に応答する必要があり、そのためのストック ライブラリは見つかりませんでした。SNES コントローラーに慣れていない方のために説明すると、これらは基本的に 2 つの 8 ビット パラレル ツー シリアル シフト レジスターを直列に接続したものです。これらは、ラッチ信号の立ち上がりエッジですべてのボタン状態をラッチし (12 μs パルスが高、通常は低)、ラッチの立ち下がりエッジで最初のビットを駆動し、クロックの立ち上がりエッジで連続する各ビットを駆動します (6ラッチの立ち下がりからの µs 遅延、通常は High、6 µs Low - 6 µs High サイクル)。
外部割り込みを使用して、ラッチ パルスと各クロック パルスの適切な動作をトリガーすることにしました。私はArduinoのプログラミングは初めてで、C / C ++も初めてです。私のコードはコンパイルされますが、実際に意図したとおりに機能するかどうかはわかりません。AVR の経験がある人が私のコードを見て、それが機能するかどうか、機能しない場合は場所と理由を教えていただければ幸いです。
Arduinoのスケッチは次のとおりです。
/*
Copyright (C) 2012 John Byers <jbyers2@wgu.edu>
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 <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
//
// 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( &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( &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( &status1, sizeof(int));
if (!ok) {
Serial.println("sync packet transmission failed");
}
else {
Serial.println("sync packet transmission successful");
}
radio.startListening();
}
}