Hello,
I have 2 DC motors connected to a motor driver and an MPU-6050 sensor connected to an Arduino UNO R3. The purpose of my sketch is to enable control of each or both motors and reading the sensor data via the Serial Monitor using a command line interface. I am using Switch/Case statements but the default case is running even when it should not. And on top of that, it runs more than once when a value is entered which does not match any of the case values.
Here is my complete code:
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include <I2Cdev.h>
#include <MPU6050.h>
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include <Wire.h>
#endif
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high
int16_t ax, ay, az;
int16_t gx, gy, gz;
char val;
int speed = 60; // set the starting speed
// Motor Connections A
int enA = 10;
int in1 = 8;
int in2 = 12;
// Motor Connections B
int enB = 9;
int in3 = 7;
int in4 = 6;
void setup () {
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(9600);
// initialize device
Serial.println("Initialising MPU-6050...");
accelgyro.initialize();
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful." : "MPU6050 connection failed.");
while (!Serial) {
; // wait for serial port to connect.
}
Serial.println("Serial port connected.");
// list of commands
Serial.println("----------------------------------");
Serial.println("The following commands are available:");
Serial.println("1 - Forward Motor A only.");
Serial.println("2 - Forward both motors A and B.");
Serial.println("3 - Forward motor B only.");
Serial.println("4 - Stop motor A only.");
Serial.println("5 - Stop both motors A and B.");
Serial.println("A - Set PWM to 100.");
Serial.println("E - Set PWM to 255.");
Serial.println("G - Read Gyroscope values.");
Serial.println("L - Read Accelerometer values.");
Serial.println("----------------------------------");
pinMode (enA, OUTPUT);
pinMode (enB, OUTPUT);
pinMode (in1, OUTPUT);
pinMode (in2, OUTPUT);
pinMode (in3, OUTPUT);
pinMode (in4, OUTPUT);
analogWrite (enA, speed);
analogWrite (enB, speed);
}
void loop () {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
if (Serial.available()) {
val = Serial.read();
switch(val)
{
case '1':
Serial.println("Input: '1'. Forward motor A.");
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
break;
case '2':
Serial.println("Input: '2'. Forward motor A and B.");
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
digitalWrite (in3, HIGH);
digitalWrite (in4, LOW);
break;
case '5':
Serial.println("Input: '5'. Stop motors A and B.");
digitalWrite (in1, LOW);
digitalWrite (in2, LOW);
digitalWrite (in3, LOW);
digitalWrite (in4, LOW);
break;
case 'A':
Serial.println("Input: 'A'. Set PWM to 100.");
speed = 100;
break;
case 'X':
Serial.println("Input: 'X'. Turn motor A only.");
analogWrite (enA, 60);
analogWrite (enB, 60);
digitalWrite (in1, HIGH);
digitalWrite (in2, LOW);
digitalWrite (in3, LOW);
digitalWrite (in4, LOW);
delay (800);
break;
case 'G':
Serial.print("Input: 'G'. Gyro-X: ");
Serial.print(gx);
Serial.print(", ");
Serial.print("Gyro-Y: ");
Serial.print(gy);
Serial.print(", ");
Serial.print("Gyro-Z: ");
Serial.print(gz);
Serial.println(".");
break;
case 'L':
Serial.print("Input: 'L'. Acc-X: ");
Serial.print(ax);
Serial.print(", ");
Serial.print("Acc-Y: ");
Serial.print(ay);
Serial.print(", ");
Serial.print("Acc-Z: ");
Serial.print(az);
Serial.println(".");
break;
default:
Serial.println("Invalid command.");
break;
}
analogWrite (enA, speed);
analogWrite (enB, speed);
}
}
Here is the problem when i enter a valid case value in the Serial Monitor. The correct motor is actually activated though.
Input: '1'. Forward motor A.
Invalid command.
Invalid command.
Here is the output when i enter an invalid case value.
Invalid command.
Invalid command.
Invalid command.
The default case is executed twice when a valid case value is entered and thrice when an invalid case value is entered in the Serial Monitor. These should not happen but i can't figure out why. Also, is it necessary to have a break statement at the end of the default case statements?