ModWheels Electronic Breadboarding
By: Matt Shellhammer (Electronics & Control Engineer)
Approved by: Lucas Gutierrez (Project Manager)
Introduction
To create a baseline design that can be used for testing and software development an electronic breadboarding of ModWheels was constructed. All components were breadboarded using some components that will not be used on the day of the final that are being used for prototyping and testing. This allows us to do testing on all of our components and ensure that our wiring diagrams are correct as well as confirming that all of our components work together properly and the software is developed appropriately for the electronic components in use.
Methodology
To perform this electronic breadboarding a Sparkfun Pro Micro and a Sparkfun TB6612FNG motor driver was used to imitate the 3DoT v5.03 board. Then all external components were connected to these two central components.
Components breadboarded:
- I2C Multiplexer (TCA9548A)
- Two Color sensors (TCS34725) (Through I2C Mux)
- IR Proximity sensor (VL6180) (Through I2C Mux)
- Two GM6 Extended Shaft Motors
- Two Magnetic Quadrature Hall Effect Encoders
- Micro Servo
The breadboarding was first done without the ModWheels chassis to test the breadboarding and software first. This was done connected printing data to the Serial print monitor from the Arduino IDE. The breadboarding done without the ModWheels chassis and serial print monitor is shown below in Figures 1 & 2. The motors were programed to stop when the proximity sensor was lower than 6 inches (~153 mm) but otherwise to continue spinning.
Figure 1. Electronic breadboarding without ModWheels chassis.
Figure 2. Serial print monitor showing sensor readings (color sensors, encoders, IR proximity sensor)
This breadboarding was then implemented within the ModWheels chassis to test the motors and proximity sensor together. Since it is programmed to stop within 6 inches of an object the car should stop and then continue when that object is moved. The breadboarding can be seen below in Figure 3 and the testing can be seen in Video 1.
Figure 3. Electronic breadboarding with ModWheels chassis.
Video 1. Testing of IR proximity sensor with GM6 motors and ModWheels chassis.
Software
ElectronicBreadboarding.ino
//////////////////////////////////////////////////////////////// // Name : Electronic Breadboarding // // Author : Matt Shellhammer // // Date : 3 December, 2017 // // Version : 1.0 // //////////////////////////////////////////////////////////////// #define __PROG_TYPES_COMPAT__ #include <avr/pgmspace.h> #include <Wire.h> #include "Adafruit_TCS34725.h" #include "EBB.h" #include <Configure.h> #include <FuelGauge.h> #include <Motor.h> #include <Packet.h> #include <Robot3DoTBoard.h> #include <TB6612FNG.h> #include <TelecomClass.h> #include <Watchdog.h> #include <SparkFun_VL6180X.h> // Define motor driver pins #define AIN1 14 // Pro-micro pin 14 (PB3) #define BIN1 7 // Pro-micro pin 7 (PE6) #define AIN2 4 // Pro-micro pin 4 (PD4) #define BIN2 8 // Pro-micro pin 8 (PB4) #define PWMA 5 // Pro-micro pin 5 (PC6) #define PWMB 6 // Pro-micro pin 6 (PD7) #define STBY 9 // Pro-micro pin 9 (PB5) // Address for I2C multiplexer #define TCAADDR 0x70 // Define Color sensors using library Adafruit_TCS34725 colorSensor = Adafruit_TCS34725(); // Define IR proximity sensor using library #define VL6180X_ADDRESS 0x29 VL6180xIdentification identification; VL6180x sensor(VL6180X_ADDRESS); // Define Servo int8_t pos = 115; // servo position #define servo_pin 10 // (PB6) // Define Encoders #define LME A0 // Left motor encoder #define RME A1 // Right motor encoder void setup() { // put your setup code here, to run once: Serial.begin(9600); // DDRx & PORTx for motor drivers DDRD |= (1<<PD4)|(1<<PD7); DDRE |= (1<<PE6); DDRB |= (1<<PB3)|(1<<PB4)|(1<<PB5); DDRC |= (1<<PC6); // Pinmode for Servo DDRB |= (1<<PB6); // if(sensor.VL6180xInit() != 0){ // Serial.println("FAILED TO INITALIZE"); //Initialize device and check for errors // }; // sensor.VL6180xDefautSettings(); //Load default settings to get started. } void loop() { static bool IRflag = false; static color_t colorL; // create an instance of color_t called colorL (left color sensor) static color_t colorR; // create an instance of color_t called colorR (right color sensor) static uint8_t IR = 0; // create variable for IR proximity sensor static bool LMEV; // Left motor Encoder value static bool RMEV; // Right motor Encoder value static uint16_t LMEV_count = 0; // Left motor Encoder value count static uint16_t RMEV_count = 0; // Right motor Encoder value count // Read Sensors colorL = readColor(0); // Serial.print("Left Red: "); Serial.print(colorL.r); Serial.print(" "); // Serial.print("Left Green: "); Serial.print(colorL.g); Serial.print(" "); // Serial.print("Left Blue: "); Serial.print(colorL.b); Serial.print(" "); // Serial.print("Left Clear: "); Serial.print(colorL.c, DEC); Serial.print(" ");Serial.println(); colorR = readColor(1); // Serial.print("Right Red: "); Serial.print(colorR.r); Serial.print(" "); // Serial.print("Right Green: "); Serial.print(colorR.g); Serial.print(" "); // Serial.print("Right Blue: "); Serial.print(colorR.b); Serial.print(" "); // Serial.print("Right Clear: "); Serial.print(colorR.c, DEC); Serial.print(" ");Serial.println(); IR = readIR(2); // Serial.print("Distance measured (mm) = ");Serial.println(IR);Serial.println(""); while (IR < 153){ // Don't hit something analogWrite(PWMA, 0); analogWrite(PWMB, 0); IR = readIR(2); IRflag = true; } if (IRflag == true){ delay(3000); IRflag = false; } // Move motors/servo forward(); LMEV = digitalRead(LME); RMEV = digitalRead(RME); if (LMEV == true){LMEV_count++;} if (RMEV == true){RMEV_count++;} // Serial.print("LMEV_count: ");Serial.println(LMEV_count); // Serial.print("RMEV_count: ");Serial.println(RMEV_count);Serial.println(""); // uint16_t count = 40000; // while(count > 0){ // LMEV = digitalRead(LME); // RMEV = digitalRead(RME); // if (LMEV == true){LMEV_count++;} // if (RMEV == true){RMEV_count++;} // count--; // } }
EBB.h
struct color_t{ uint16_t r = 0; // Color sensor Red uint16_t g = 0; // Color sensor Green uint16_t b = 0; // Color sensor Blue uint16_t c = 0; // Color sensor Clear };
EBBsub.ino
void tcaselect(uint8_t i) { //Selecting an address on I2C Mutiplexer if (i > 7) return; Wire.beginTransmission(TCAADDR); Wire.write(1 << i); Wire.endTransmission(); } color_t readColor(uint8_t index) { color_t colors; // create an instance of color_t called colors // Read value from color sensor and determine reading tcaselect(index); colorSensor.begin(); colorSensor.getRawData(&colors.r, &colors.g, &colors.b, &colors.c); return colors; } uint8_t readIR(uint8_t index) { // Read value from color sensor and determine reading tcaselect(index); uint8_t IR = sensor.getDistance(); return IR; } void forward(){ digitalWrite(STBY, HIGH); digitalWrite(AIN2, LOW); digitalWrite(AIN1, HIGH); digitalWrite(BIN1, HIGH); digitalWrite(BIN2, LOW); analogWrite(PWMA, 150); analogWrite(PWMB, 150); analogWrite(servo_pin,60); } void turn_right() { digitalWrite(STBY, HIGH); digitalWrite(AIN2, LOW); digitalWrite(AIN1, HIGH); digitalWrite(BIN1, HIGH); digitalWrite(BIN2, LOW); analogWrite(PWMA, 100); analogWrite(PWMB, 150); analogWrite(servo_pin,30); } void turn_left() { digitalWrite(STBY, HIGH); digitalWrite(AIN2, LOW); digitalWrite(AIN1, HIGH); digitalWrite(BIN1, HIGH); digitalWrite(BIN2, LOW); analogWrite(PWMA, 150); analogWrite(PWMB, 100); analogWrite(servo_pin,90); } void turn_around() { } void stopRobot(uint16_t d) { digitalWrite(STBY, HIGH); digitalWrite(AIN2, LOW); digitalWrite(AIN1, HIGH); digitalWrite(BIN1, HIGH); digitalWrite(BIN2, LOW); analogWrite(PWMA, 0); analogWrite(PWMB, 0); analogWrite(servo_pin,115); delay(d); }