From 0d462439e34aa4623d16150506796fb0d7530289 Mon Sep 17 00:00:00 2001 From: JbLb Date: Sat, 4 Jan 2020 17:57:09 +0100 Subject: [PATCH] Nunchuk added - reformat of code from IDE ! --- src/hoverserial.ino | 309 +++++++++++++++++++++++++------------------- 1 file changed, 175 insertions(+), 134 deletions(-) diff --git a/src/hoverserial.ino b/src/hoverserial.ino index f6b6bc6..5edb7cf 100644 --- a/src/hoverserial.ino +++ b/src/hoverserial.ino @@ -33,152 +33,172 @@ // ########################## DEFINES ########################## #define HOVER_SERIAL_BAUD 38400 // [-] Baud rate for HoverSerial (used to communicate with the hoverboard) #define SERIAL_BAUD 115200 // [-] Baud rate for built-in Serial (used for the Serial Monitor) -#define START_FRAME 0xAAAA // [-] Start frme definition for reliable serial communication +#define START_FRAME 0xAAAA // [-] Start frme definition for reliable serial communication #define TIME_SEND 1000 // [ms] Sending time interval -#define SPEED_MAX_TEST 300 // [-] Maximum speed for testing +#define SPEED_MAX_TEST 300 // [-] Maximum speed for testing //#define DEBUG_RX // [-] Debug received data. Prints all bytes to serial (comment-out to disable) #include #include #include +#include // #include -// SoftwareSerial HoverSerial(2,3); // RX, TX +// SoftwareSerial HoverSerial(2,3); // RX, TX // Global variables -uint8_t idx = 0; // Index for new data pointer -uint16_t bufStartFrame; // Buffer Start Frame -byte *p; // Pointer declaration for the new received data +uint8_t idx = 0; // Index for new data pointer +uint16_t bufStartFrame; // Buffer Start Frame +byte *p; // Pointer declaration for the new received data byte incomingByte; byte incomingBytePrev; -typedef struct{ - uint16_t start; - int16_t steer; - int16_t speed; - uint16_t checksum; +typedef struct { + uint16_t start; + int16_t steer; + int16_t speed; + uint16_t checksum; } SerialCommand; SerialCommand Command; -typedef struct{ - uint16_t start; - int16_t cmd1; - int16_t cmd2; - int16_t speedR; - int16_t speedL; - int16_t speedR_meas; - int16_t speedL_meas; - int16_t batVoltage; - int16_t boardTemp; - int16_t checksum; +typedef struct { + uint16_t start; + int16_t cmd1; + int16_t cmd2; + int16_t speedR; + int16_t speedL; + int16_t speedR_meas; + int16_t speedL_meas; + int16_t batVoltage; + int16_t boardTemp; + int16_t checksum; } SerialFeedback; SerialFeedback Feedback; SerialFeedback NewFeedback; -#define SCREEN_WIDTH 128 // OLED display width, in pixels -#define SCREEN_HEIGHT 64 // OLED display height, in pixels +#define SCREEN_WIDTH 128 // OLED display width, in pixels +#define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); +// Connect to a Nunchuk +Nunchuk nchuk; // ########################## SETUP ########################## void setup() { - display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64) - // Clear the buffer - display.clearDisplay(); - display.display(); - display.setCursor(0, 0); - display.setTextSize(1); // Draw 1X-scale text - display.setTextColor(SSD1306_WHITE); - display.println("Hoverboard Serial"); - display.println("v1.0"); - display.display(); - - Serial1.begin(HOVER_SERIAL_BAUD); // RX, TX from arduino to TX RX on hoverboard board. ! be carreful 3v3 - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(SERIAL_BAUD); - if (Serial) { - Serial.println("Hoverboard Serial v1.0"); - } + nchuk.begin(); + + display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64) + // Clear the buffer + display.clearDisplay(); + display.display(); + display.setCursor(0, 0); + display.setTextSize(1); // Draw 1X-scale text + display.setTextColor(SSD1306_WHITE); + display.println("Hoverboard Serial"); + display.println("v1.0"); + display.print("Nunchuk "); + nchuk.connect()? display.print("") : display.print("not "); + display.println("connected"); + display.display(); + + Serial1.begin(HOVER_SERIAL_BAUD); // RX, TX from arduino to TX RX on hoverboard board. ! be carreful 3v3 + pinMode(LED_BUILTIN, OUTPUT); + + Serial.begin(SERIAL_BAUD); + if (Serial) { + Serial.println("Hoverboard Serial v1.0"); + } } // ########################## SEND ########################## void Send(int16_t uSteer, int16_t uSpeed) { - // Create command - Command.start = (uint16_t)START_FRAME; - Command.steer = (int16_t)uSteer; - Command.speed = (int16_t)uSpeed; - Command.checksum = (uint16_t)(Command.start ^ Command.steer ^ Command.speed); - - // Write to Serial - Serial1.write((uint8_t *) &Command, sizeof(Command)); + // Create command + Command.start = (uint16_t) START_FRAME; + Command.steer = (int16_t) uSteer; + Command.speed = (int16_t) uSpeed; + Command.checksum = + (uint16_t) (Command.start ^ Command.steer ^ Command.speed); + + // Write to Serial + Serial1.write((uint8_t *) & Command, sizeof(Command)); } // ########################## RECEIVE ########################## void Receive() { - // Check for new data availability in the Serial buffer - if (Serial1.available()) { - incomingByte = Serial1.read(); // Read the incoming byte - bufStartFrame = ((uint16_t)(incomingBytePrev) << 8) + incomingByte; // Construct the start frame - } - else { - return; - } - - // If DEBUG_RX is defined print all incoming bytes - #ifdef DEBUG_RX - Serial.print(incomingByte); - return; - #endif - - // Copy received data - if (bufStartFrame == START_FRAME) { // Initialize if new data is detected - p = (byte *)&NewFeedback; - *p++ = incomingBytePrev; - *p++ = incomingByte; - idx = 2; - } else if (idx >= 2 && idx < sizeof(SerialFeedback)) { // Save the new received data - *p++ = incomingByte; - idx++; - } - - // Check if we reached the end of the package - if (idx == sizeof(SerialFeedback)) { - uint16_t checksum; - checksum = (uint16_t)(NewFeedback.start ^ NewFeedback.cmd1 ^ NewFeedback.cmd2 ^ NewFeedback.speedR ^ NewFeedback.speedL - ^ NewFeedback.speedR_meas ^ NewFeedback.speedL_meas ^ NewFeedback.batVoltage ^ NewFeedback.boardTemp); - - // Check validity of the new data - if (NewFeedback.start == START_FRAME && checksum == NewFeedback.checksum) { - // Copy the new data - memcpy(&Feedback, &NewFeedback, sizeof(SerialFeedback)); - - // Print data to CDC Serial if available - if (Serial) { - Serial.print("1: "); Serial.print(Feedback.cmd1); - Serial.print(" 2: "); Serial.print(Feedback.cmd2); - Serial.print(" 3: "); Serial.print(Feedback.speedR); - Serial.print(" 4: "); Serial.print(Feedback.speedL); - Serial.print(" 5: "); Serial.print(Feedback.speedR_meas); - Serial.print(" 6: "); Serial.print(Feedback.speedL_meas); - Serial.print(" 7: "); Serial.print(Feedback.batVoltage); - Serial.print(" 8: "); Serial.println(Feedback.boardTemp); - } - } else { - if (Serial) Serial.println("Non-valid data skipped"); - } - - idx = 0; // Reset the index (it prevents to enter in this if condition in the next cycle) - } - - // Update previous states - incomingBytePrev = incomingByte; + // Check for new data availability in the Serial buffer + if (Serial1.available()) { + incomingByte = Serial1.read(); // Read the incoming byte + bufStartFrame = ((uint16_t) (incomingBytePrev) << 8) + incomingByte; // Construct the start frame + } else { + return; + } + + // If DEBUG_RX is defined print all incoming bytes +#ifdef DEBUG_RX + Serial.print(incomingByte); + return; +#endif + + // Copy received data + if (bufStartFrame == START_FRAME) { // Initialize if new data is detected + p = (byte *) & NewFeedback; + *p++ = incomingBytePrev; + *p++ = incomingByte; + idx = 2; + } else if (idx >= 2 && idx < sizeof(SerialFeedback)) { // Save the new received data + *p++ = incomingByte; + idx++; + } + // Check if we reached the end of the package + if (idx == sizeof(SerialFeedback)) { + uint16_t checksum; + checksum = + (uint16_t) (NewFeedback.start ^ NewFeedback. + cmd1 ^ NewFeedback.cmd2 ^ NewFeedback. + speedR ^ NewFeedback.speedL ^ NewFeedback. + speedR_meas ^ NewFeedback.speedL_meas ^ + NewFeedback.batVoltage ^ NewFeedback.boardTemp); + + // Check validity of the new data + if (NewFeedback.start == START_FRAME + && checksum == NewFeedback.checksum) { + // Copy the new data + memcpy(&Feedback, &NewFeedback, sizeof(SerialFeedback)); + + // Print data to CDC Serial if available + if (Serial) { + Serial.print("1: "); + Serial.print(Feedback.cmd1); + Serial.print(" 2: "); + Serial.print(Feedback.cmd2); + Serial.print(" 3: "); + Serial.print(Feedback.speedR); + Serial.print(" 4: "); + Serial.print(Feedback.speedL); + Serial.print(" 5: "); + Serial.print(Feedback.speedR_meas); + Serial.print(" 6: "); + Serial.print(Feedback.speedL_meas); + Serial.print(" 7: "); + Serial.print(Feedback.batVoltage); + Serial.print(" 8: "); + Serial.println(Feedback.boardTemp); + } + } else { + if (Serial) + Serial.println("Non-valid data skipped"); + } + + idx = 0; // Reset the index (it prevents to enter in this if condition in the next cycle) + } + // Update previous states + incomingBytePrev = incomingByte; } // ########################## LOOP ########################## @@ -189,34 +209,55 @@ int iTest = 0; void loop(void) { - unsigned long timeNow = millis(); - - // Check for new received data - Receive(); - - // Send commands - if (iTimeSend > timeNow) - return; - iTimeSend = timeNow + TIME_SEND; - Send(0, abs(iTest)); - - display.setCursor(0, 30); - display.setTextSize(1); // Draw 1X-scale text - display.setTextColor(SSD1306_WHITE); - display.print("Speed : "); - display.setCursor(45, 30); - display.print(" "); - display.display(); - display.setCursor(45, 30); + unsigned long timeNow = millis(); + + // Check for new received data + Receive(); + // Get new data from the controller + if (!nchuk.update()) { + Serial.println("Controller disconnected!"); + nchuk.reconnect(); + } else { + // Read a button (on/off, C and Z) + Serial.print("Z: "); + nchuk.buttonZ()? Serial.print("On ") : Serial.print("Off "); + Serial.print("C: "); + nchuk.buttonC()? Serial.print("On ") : Serial.print("Off "); + + // Read joystick axis (0-255, X and Y) + Serial.print("The joystick's Y axis is at "); + Serial.print(nchuk.joyY()); + Serial.print(" and X axis is at "); + Serial.print(nchuk.joyX()); + + // Read an accelerometer and print values (0-1023, X, Y, and Z) + Serial.print(" - The accelerometer's X-axis is at "); + Serial.println(nchuk.accelX()); + } + + // Send commands + if (iTimeSend > timeNow) + return; + iTimeSend = timeNow + TIME_SEND; + Send(0, abs(iTest)); + + display.setCursor(0, 30); + display.setTextSize(1); // Draw 1X-scale text + display.setTextColor(SSD1306_WHITE); + display.print("Speed : "); + display.setCursor(45, 30); + display.print(" "); + display.display(); + display.setCursor(45, 30); display.print(iTest); - display.display(); - // Calculate test command signal - iTest += 10; - if (iTest > iTestMax) - iTest = -iTestMax; - - // Blink the LED - digitalWrite(LED_BUILTIN, (timeNow % 2000) < 1000); + display.display(); + // Calculate test command signal + iTest += 10; + if (iTest > iTestMax) + iTest = -iTestMax; + + // Blink the LED + digitalWrite(LED_BUILTIN, (timeNow % 2000) < 1000); } // ########################## END ##########################