Hello,
I am using the Nyko Kama wireless nunchuck to control my electric longboard, and it works fairly well. There are several threads on this topic, but they are all over months old and do not address my question. I can read data from the nunchuck, map it to the correct values for the Servo library, and then use that library to control the ESC connected to the brushless motor.
However, I am having some problems with the initial sync between the nunchuck and its' receiver. When I reset the Arduino, sometimes it works just fine and I get meaningful data from the chuck, and I can ride the board around for miles. Other times my serial monitor starts and shows that the joystick is at its minimum value and the system is totally unresponsive, or I get the joystick at max value and no response (other than my board taking off at full throttle...).
This is my second arduino project, and I am very new to programming as a whole (some MatLab experience, but I don't think that really counts). I have tried to use a couple IF statements to see if the nunchuck is receiving good data, but I don't think they are working how I intended (if at all).
I am using Tim Hirzel's WiiChuck library, but I am not experienced enough to work through it and find what is not playing nice with my nunchuck. I think there is something in his 'void begin()' that my particular nunchuck does not like, but I don't know. I'm trying to figure out how the problem could be intermittent, and I don't know where to start. If not the code, it could be my $6 nunchuck, cheap-o breadboard/jumpers, or even the fake arduino clone I have until my replacement real one shows up. Any advice would be appreciated.
My sketch:
#include <Wire.h> // Library for I2C communication
#include <WiiChuck.h> // Library for reading data from Wii Nunchuck
#include <Servo.h> // Library for controlling Servo or ESC
WiiChuck chuck = WiiChuck();
Servo myservo;
int speed_val; // Speed value
int speed_val_cur = 90; // Current speed value
int y = 0; // Joystick value
int time = 200; // Delay timer
int speed_val_hold; // speed value for the throttle hold feature
// Setup. This runs at startup, and initializes the nunchuck
void setup() {
Serial.begin(115200); // Begin serial communication with baud rate at 115200. For debugging
chuck.begin(); // Initialize nunchuck. This function is located in the WiiChuck.h library
chuck.update(); // Read nunchuck. This function is located in the WiiChuck.h library
myservo.attach(9); // ESC attached to 9 pin of Arduino
// Print to serial monitor. This tells us that the setup ran once. Again, for debugging
Serial.println();
Serial.print("Initialization Sequence Complete");
Serial.println();
delay(1000);
}
// Main loop. This is what actually does stuff. The rest of the sketch is inside this
void loop() {
//Check if Z or C button is pressed
if ((chuck.buttonZ)||(chuck.buttonC)) {
// If you hold down Z, the throttle hold is enabled and speed adjustments occur slowly (think cruise control buttons in a car)
if (chuck.buttonZ) {
Serial.print(" Z ");
time = 50;
}
/*
// If you press C, something will happen -- NOTE: This feature is not yet implimented, so nothing will really happen
if (chuck.buttonC) {
do stuff
}
*/
}
// If no buttons are pressed, throttle response is set to maximum (think throttle/brake pedels in a car)
else {
time = 5;
}
// Delay for the time amount specified above. This determines how fast the throttle will react to input
delay(time);
// Request updated data from the nunchuck, and assign the Y axis position to variable y
chuck.update();
y = chuck.readJoyY();
// Map the joystick value onto the speed value (joystick at 0 = speed at 90. This is neutral throttle)
speed_val = map(y, -128, 125, 30, 150);
// If the connection is lost, set all speeds to 90. Remember, speed = 90 is neutral. IE. the motor is stopped.
if ((y > 125) || (y < -129)) {
speed_val = 90;
speed_val_cur = 90;
speed_val_hold = 90;
setup();
}
if (chuck.buttonZ) { // If Z is pressed (throttle hold on):
if ((speed_val_hold < speed_val) // Check if we are trying to accellerate:
&& (y > 5)) {
speed_val_hold++; // If hold button is pressed and throttle stick moved up – increase speed
}
if ((speed_val_hold > speed_val) // Check if we are trying to decellerate:
&& (y < -5)) {
speed_val_hold--; // If hold button is pressed and throttle stick moved down – decrease speed
}
speed_val_cur = speed_val_hold;
}
else { // If Z is not pressed (throttle hold off):
if (speed_val_cur < speed_val) { // Check if we are trying to accellerate:
speed_val_cur++; // If hold button is NOT pressed and throttle stick moved up – increase speed
}
if (speed_val_cur > speed_val) { // Check if we are trying to decellerate:
speed_val_cur--; // If hold button is NOT pressed and throttle stick moved down – decrease speed
}
speed_val_hold = speed_val_cur;
}
// Write current speed value to the ESC
myservo.write(speed_val_cur);
//Print important variables to serial monitor. For debugging purposes.
Serial.println();
Serial.print("Joy = ");
Serial.print(y);
Serial.print(" speed_val = ");
Serial.print(speed_val);
Serial.print(" speed_hold = ");
Serial.print(speed_val_hold);
Serial.print(" Speed = ");
Serial.print(speed_val_cur);
}