Hello everyone. I'm new to arduino. Currently I'm trying to make something using Wii Classic Controller as input device. Some days ago I bought a cheap knock-off Wii Classic Controller Pro from the internet, only cost me less than $6. I then googled some information, and wrote the following code:
WiiClassicController.cpp
#include "WiiClassicController.h"
void WiiClassicControllerClass::init(){
Serial.begin(19200);
Wire.begin();
pinMode(18, INPUT); // Disable internal pull-ups, use external pull-ups(4.7K resistors) instead
digitalWrite(18, LOW);
pinMode(19, INPUT);
digitalWrite(19, LOW);
TWBR = 12; // Set I2C speed (12 = 400kHz, 32 = 200kHz, 72 = 100kHz, 152 = 50kHz. 25K or 12.5K or Lower freq needs extra settings)
delay(100); // Delay a short period to make PINs stable
Wire.beginTransmission(WII_CLASSIC_CONTROLLER_7BIT_ADDR); // The Address of WiiClassicController is 0x52
#ifdef USE_COMPATIBLE_METHOD
Wire.write(0xF0);
Wire.write(0x55);
Wire.endTransmission(); // Start the real transmitting
Wire.beginTransmission(WII_CLASSIC_CONTROLLER_7BIT_ADDR); // Another initialization procedure
Wire.write(0xFB);
Wire.write(0x00);
#else
Wire.write(0x40);
Wire.write(0x00);
#endif
Wire.endTransmission(); // Stop transmitting
delay(2); // Delay a short period to make updates stable
#ifdef CHECK_CONTROLLER_ID
Wire.beginTransmission(WII_CLASSIC_CONTROLLER_7BIT_ADDR);
Wire.write(0xFA); // Check the ID of the controller
Wire.endTransmission();
Wire.requestFrom(WII_CLASSIC_CONTROLLER_7BIT_ADDR, 6);
Serial.print("ID=");
while(Wire.available()){
Serial.print(Wire.read(), HEX);
Serial.print(" ");
}
Serial.println();
delay(2);
#endif
}
void WiiClassicControllerClass::update(){
Wire.beginTransmission(WII_CLASSIC_CONTROLLER_7BIT_ADDR);
Wire.write(0x00);
Wire.endTransmission();
delay(2); // 1ms is enough not to overload the controller. This value can be adjusted later to gain a best performance
Wire.requestFrom(WII_CLASSIC_CONTROLLER_7BIT_ADDR, 6);
uint8_t t = 0;
while(Wire.available()){
rawData[t] = decode(Wire.read());
t++;
}
}
void WiiClassicControllerClass::read(NormalizedWiiData* wiiData){
wiiData->xLAnalog = (rawData[0] & 0x3F);
wiiData->yLAnalog = (rawData[1] & 0x3F);
wiiData->xRAnalog = ((rawData[0] >> 6) & 0x03) << 3;
wiiData->xRAnalog |= ((rawData[1] >> 6) & 0x03) << 1;
wiiData->xRAnalog |= ((rawData[2] >> 7) & 0x01);
wiiData->yRAnalog = (int8_t)(rawData[2] & 0x1F);
wiiData->LTrigger = ((rawData[2] >> 5) & 0x03) << 3;
wiiData->LTrigger |= (rawData[3] >> 5) & 0x07;
wiiData->RTrigger = (rawData[3] & 0x1F);
*((uint16_t*)&wiiData->buttons) = ~(rawData[4] | (rawData[5] << 8));
wiiData->xLAnalog <<= 2;
wiiData->yLAnalog <<= 2;
wiiData->xRAnalog <<= 3;
wiiData->yRAnalog <<= 3;
wiiData->LTrigger <<= 3;
wiiData->RTrigger <<= 3;
}
uint8_t WiiClassicControllerClass::decode(uint8_t raw){
#ifdef USE_COMPATIBLE_METHOD
return raw;
#else
return (x ^ 0x17) + 0x17;
#endif
}
WiiClassicControllerClass WiiClassicController;
WiiClassicController.h
#ifndef _WIICLASSICCONTROLLER_h
#define _WIICLASSICCONTROLLER_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
#ifndef WII_CLASSIC_CONTROLLER_7BIT_ADDR
#define WII_CLASSIC_CONTROLLER_7BIT_ADDR 0x52
#endif
#define USE_COMPATIBLE_METHOD
#define CHECK_CONTROLLER_ID
struct NormalizedWiiButton{
uint8_t dummy :1;
uint8_t r :1;
uint8_t plus :1;
uint8_t home :1;
uint8_t minus :1;
uint8_t l :1;
uint8_t down :1;
uint8_t right :1;
uint8_t up :1;
uint8_t left :1;
uint8_t zr :1;
uint8_t x :1;
uint8_t a :1;
uint8_t y :1;
uint8_t b :1;
uint8_t zl :1;
};
struct NormalizedWiiData{
int8_t xLAnalog;
int8_t yLAnalog;
int8_t xRAnalog;
int8_t yRAnalog;
int8_t LTrigger;
int8_t RTrigger;
NormalizedWiiButton buttons;
};
class WiiClassicControllerClass{
public:
void init();
void update();
void read(NormalizedWiiData* wiiData);
protected:
private:
uint8_t decode(uint8_t raw);
uint8_t rawData[6];
};
extern WiiClassicControllerClass WiiClassicController;
#endif
When I was trying to initialize the Wii Classic Controller using WiiClassicController.init(); I found nothing printed on the COM Monitor.
I then inserted Serial.println(SOME RANDOM CHARACTERS); in every line in the code to see where the problem happened at.
At last I found the program hangs inside the first call of Wire.endTransmission();.
Wire.write(0xF0);
Wire.write(0x55);
Wire.endTransmission(); // <----Program hangs here!
Wire.beginTransmission(WII_CLASSIC_CONTROLLER_7BIT_ADDR); // Another initialization procedure
Wire.write(0xFB);
Wire.write(0x00);
I checked the circuit and confirmed nothing was wrong. I'm using Arduino Nano so I connected SDA to Analog PIN4 and SCL to Analog PIN5, both pulled up to +3.3V using two 4.7K resistors. VCC and GND also well connected.
I then got confused. Why the program hangs? Could anyone please give me some hints? Thanks very much!
![IMG_0899[1].JPG](https://europe1.discourse-cdn.com/arduino/original/3X/2/2/22a5267649373f9e3decaf8ccca8189dd7516641.jpg)