Upload
tony-mcjohnston
View
36
Download
1
Embed Size (px)
Citation preview
ELET 4790 – Senior Project 2
Real-Time Wireless Monitoring for Automotive Applications
Tony Mcjohnston, Russell Rice, Justin McClesky
5-2-2016
Electrical Engineering Technology ELET 4790 – Senior Project 2
Overview:SAE race car teams need as much data from their car as possible, so that they can both
find faults in their design and improve on it. Some SAE teams collect their data after their
car has stopped driving, while others can acquire their data wirelessly in real-time. The
UNT SAE team started only three years ago, and they want to quickly catch up with other
SAE teams’ progress to be more competitive. Our wireless data acquisition system will
allow the UNT SAE team to do just that with the ability to see what their car is doing in
real-time. This will help with both testing purposes, and eventually in SAE tournaments.
For this paper we will be describing our system, as well as what could be added to the
system in the future.
Motivation:
The motivation for this project came from the UNT SAE team asking for a team of
Electrical Engineering techs to build a system for their formula car that would acquire
data in real-time wirelessly during vehicle testing. In addition to acquiring data from the
ECU, the team also asked for additional sensors on the car to accumulate more data from
the vehicle.
Design Description:The design for the system first starts with the race car as seen below. We then branch out
to two separate systems, the sensor system and the wireless ECU system. Both systems
share the 12V power supply already installed on the car.
The sensor system consist of the MPU-9250 sensor, the Arduino Uno R3 with Xbee
shield, and the Xbee Explorer. The sensor uses a gyroscope and accelerometer to
determine the orientation of the vehicle, and sends this data to the Arduino. The Arduino
then packs the data and sends it wirelessly to a computer via Xbee. The computer uses an
Xbee on an Xbee Explorer to receive the signal, then displays the data as a 3D image.
Page 1 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
The wireless ECU system consists of the ECU, which was installed on the car when the
car was built, and the Linksys router. Both parts are powered by the on-board 12V
battery. The ECU is connected directly to the router via an Ethernet cable. The router
then sends the data wirelessly to a computer in real-time. The computer receives this data
through a Wi-Fi connection, and displays it with ECU software.
Hardware:The hardware used in our project is as follows:
1. The PE3 ECU: The ECU is made by Performance Electronics and the model is
PE3-8400P which costs about $1,075. The ECU is used to control the car engine
through various sensor inputs, and mechanical and electrical outputs. It has a
Dedicated Ethernet connection for two-way communication with ECU PE3
Monitor program. Thankfully, this part is already installed on the car, so we did
not need to purchase this part.
Page 2 of 22
PE3 ECU Linksys Router Laptop (ECU Software)
Gyroscope/ Accelerometer
Arduino w/Xbee
Xbee w/ Explorer
Laptop (Processing Software)
SAE Formula Car
Electrical Engineering Technology ELET 4790 – Senior Project 2
2. The Linksys WRT54G Router: This router uses the 2.4 GHz Wi-Fi band, has a
transfer rate of up to 54 Mbps, and only cost us a total of $14.95. The router is
modifiable with already made third party firmware, and we currently have DD-
WRT firmware installed on our router to allow manual changes to transmit power.
3. The MPU-9250 9-Axis Gyro + Accel. + Magnet.: with a cost of $12.00, this chip
is used to acquire roll, pitch, yaw, and acceleration of the car. This board can also
be used to determine direction of car in relation to Earth’s magnetic field, though
we do not use this in our application.
4. The Arduino Uno R3 with Xbee Shield and Xbee Pro Series 1: This device uses
an ATmega328 Microcontroller, with 6 analog input pins and 12 digital input
pins. It runs on a 16 MHz clock speed, and has 32 KB Flash Memory with a
microSD card slot for expansion. The Xbee Shield connects the Xbee to the
Arduino, which allows the Arduino to communicate with another Xbee, like the
one connected to our computer. We connected the VCC and the SDA connections
Page 3 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
through a 500Ω resistor to increase the voltage on the SDA line due to cable
impedance to increase the MPU-925 logic value input to the required amount.
5. The Xbee Explorer with Xbee Pro Series 1: The Explorer connects an Xbee to a
computer using a USB-to-serial converter. This allows a computer to
communicate with the Xbee attached to the Arduino Uno. The Xbee used here is
the receiving Xbee in the Xbee pair used to connect the Arduino with a computer
over a long distance. They have 250 kbps max data rate, 63mW output power, and
up to 1 mile (1500 meter) range.
6. The 2.4 GHz 9 dBi Antenna: This antenna is connected to the Xbee Explorer
board through an SMA connector on it, and has a magnet in the base for mounting
to metal. This antenna cost us about $9.90.
Page 4 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
7. The 2.4 GHz 12 dBi Antenna: This antenna is connected to the computer through
a USB adapter. This allows the computer to connect to our Wi-Fi network from
further away. This antenna cost us about $39.95.
8. The final two hardware parts we have are the In-Line Fuse Holder w/ 4A fuse,
which cost us $5.50, and the Toggle Switch for power for our entire system,
which cost us $4.95.
Overall, our entire system cost us $223.00, not including taxes.
Software:
For this project we are currently using four different software programs. The first
software we are using is called Acrylic Wi-Fi Home. It is a commercial wireless signal
testing software, though we are using the free home-use version for testing. This software
is used to detect and analyze Wi-Fi signal quality and strength.
Page 5 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
The second program we are using is the ECU software called PE3 Monitor. This software
is used to communicate with the ECU on the race car and shows all data being processed
wirelessly.
The third program we are using is Arduino 1.6.7. This program is used for programming
our Arduino Uno to pack the incoming sensor data and send it to the Xbee for
transmission.
Page 6 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
The final program we are using is Processing 3.0.2. This program is used for displaying
received sensor data as a 3D car model. The model is designed to move when the sensor
moves.
Page 7 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
Timeline:
Originally, our predicted time table had us starting researching on our project when it was
assigned in September 2015. We had predicted that we would be completed with
research by mid-November 2015, that we would start software development and
prototyping in early October 2015, and that we would be completed by early April 2016.
During the course of this project, the timeline moved forward as we encountered
numerous issues, though we were able to complete the project by late April 2016.
Current Status:
Our entire system has been installed on the car, and has been tested both indoors and
outdoors. For the majority of our time, we were attempting to use three 9-dBi antennas
for router and Arduino data transmission, but these antennas were found to reduce our
range to about 90 feet. Once we switched to factory antennas for the router, and a small
4-dBi antenna that attaches directly to the Arduino, our range increased to over the 300
yard goal. This range has been tested while test driving the car, with no data transmission
errors.
Page 8 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
We were initially using Xbees for Arduino communication, then for a while we switched
to the router due to the ease of use and the higher bit-rate that is available on routers.
Eventually, we switched back to using Xbees for Arduino communication due to the
Processing software sketch requiring data from a serial connection. We also found that by
changing the channel on the Xbees, we were able to increase the range of the Xbees
without changing the antennas being used.
The Linksys router and the Arduino Uno are both installed on the SAE race car with
Velcro at the nose of the car. The wires are routed along the frame and currently secured
with zip ties.
The MPU-9250 is mounted in an aluminum casing, which is installed under the seat of
the car. This is as close to the center of the car as we were able to install the sensor.
Page 9 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
An in-line fuse holder has been added to the circuit to the router to provide circuit
protection. It houses a 4 amp fuse, and has a light on it that will light up when the fuse is
blown.
The completed circuit consists of the router and Arduino mounted in the front of the car,
with the accelerometer mounted under the seat. We have also installed a power switch for
our system on the dashboard of the car.
Page 10 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
Future Design Improvements:
For a future team wanting to improve on this project, there are at least three different
areas of our project that can be improved on. One part would be making a single
enclosure for both the Linksys router and the Arduino Uno, since they both are mounted
in the same area. This would allow for better cable management, as well as improve on
aesthetic design. Another part would be to increase the range of the data transmission to
about 1500 feet. This would be necessary to use this system on an SAE tournament track
efficiently. The final part would be to increase the number of additional sensors to the
system. One sensor of interest to the SAE team is tire temperature sensors, though we did
not add them due to them being beyond our project budget constraints.
Conclusion:In conclusion, our wireless data acquisition system is able to send both the ECU data and
the MPU-9250 sensor data wirelessly from a distance of at least 300 feet. We used a
Linksys WRT54G router to transmit ECU data wirelessly, and an Arduino Uno R3 with
Xbees to transmit the MPU-9250 sensor data wirelessly. Both signals have little to no
transmission errors, and both can be expanded on to increase system usability.
Page 11 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
References: https://www.arduino.cc/en/Main/ArduinoBoardEthernet
https://www.arduino.cc/en/Main/Software
https://www.sparkfun.com
http://downloads.linksys.com/downloads/userguide/WRT54G_UG_WEB_20070529.pdf
http://diyhacking.com/arduino-mpu-6050-imu-sensor-tutorial/
Page 12 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
Appendices:
Arduino Code:
#include <SoftwareSerial.h>
SoftwareSerial XBee(2, 3); // RX, TX
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
#include "avr/wdt.h"// Watchdog library
MPU6050 mpu;
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;
// MPU control/status vars
bool dmpReady = false; // set true if DMP init was successful
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
VectorInt16 aa; // [x, y, z] accel sensor measurements
VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements
VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements
VectorFloat gravity; // [x, y, z] gravity vector
float euler[3]; // [psi, theta, phi] Euler angle container
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
Page 13 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' ;
// INTERRUPT DETECTION ROUTINE
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone
high
void dmpDataReady()
mpuInterrupt = true;
//INITIAL SETUP
void setup()
wdt_enable(WDTO_1S); //Watchdog enable.
//WDTO_1S sets the watchdog timer to 1 second
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
XBee.begin(57600);
Serial.begin(57600);
while (!Serial);
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
Serial.println(F("Testing device connections..."));
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") :
F("MPU6050 connection failed"));
Serial.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
Page 14 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788);
if (devStatus == 0)
Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
else
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
pinMode(LED_PIN, OUTPUT);
// MAIN PROGRAM LOOP
void loop()
if (!dmpReady) return;
wdt_reset();//Resets the watchdog timer.
while (!mpuInterrupt && fifoCount < packetSize)
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
fifoCount = mpu.getFIFOCount();
if ((mpuIntStatus & 0x10) || fifoCount == 1024)
mpu.resetFIFO();
Serial.println(F("FIFO overflow!"));
Page 15 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
else if (mpuIntStatus & 0x02)
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
mpu.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;
teapotPacket[2] = fifoBuffer[0];
teapotPacket[3] = fifoBuffer[1];
teapotPacket[4] = fifoBuffer[4];
teapotPacket[5] = fifoBuffer[5];
teapotPacket[6] = fifoBuffer[8];
teapotPacket[7] = fifoBuffer[9];
teapotPacket[8] = fifoBuffer[12];
teapotPacket[9] = fifoBuffer[13];
Serial.write(teapotPacket, 14);
XBee.write(teapotPacket, 14);
teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
Processing Code:
import processing.serial.*;
import processing.opengl.*;
import toxi.geom.*;
import toxi.processing.*;
ToxiclibsSupport gfx;
Serial port; // The serial port
char[] teapotPacket = new char[14]; // InvenSense Teapot packet
int serialCount = 0; // current packet byte position
Page 16 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
int aligned = 0;
int interval = 0;
float[] q = new float[4];
Quaternion quat = new Quaternion(1, 0, 0, 0);
float[] gravity = new float[3];
float[] euler = new float[3];
float[] ypr = new float[3];
int car = 2;
void setup()
size(300, 300, OPENGL);
gfx = new ToxiclibsSupport(this);
lights();
smooth();
String portName = "COM4";
port = new Serial(this, portName, 115200);
port.write('r');
void draw()
if (millis() - interval > 1000)
port.write('r');
interval = millis();
background(0);
pushMatrix();
translate(width / 2, height / 2);
float[] axis = quat.toAxisAngle();
rotate(axis[0], -axis[1], axis[3], axis[2]);
fill(255, 0, 0, 200);
Page 17 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
box(40*car, 30*car, 80*car);
pushMatrix();
fill(0, 255, 0, 200);
translate(0, 0, -60*car);
rotateX(PI/2);
drawCylinder(0, 20*car, 20*car, 8*car);
fill(0, 0, 255, 200);
translate(-20*car, 35*car, -15*car);
rotateZ(PI/2);
drawCylinder(10*car, 10*car, 10*car, 8*car);
translate(50*car, 0, 0);
drawCylinder(10*car, 10*car, 10*car, 8*car);
translate(0, -50*car, 0);
drawCylinder(10*car, 10*car, 10*car, 8*car);
translate(-50*car, 0, 0);
drawCylinder(10*car, 10*car, 10*car, 8*car);
popMatrix();
fill(0, 255, 0, 200);
beginShape(QUADS);
vertex( 15*car, -15*car, 30*car); vertex( 15*car, -15*car, 40*car); vertex( 15*car, -30*car, 55*car); vertex( 15*car, -30*car, 45*car);
vertex( 13*car, -15*car, 30*car); vertex( 13*car, -15*car, 40*car); vertex( 13*car, -30*car, 55*car); vertex( 13*car, -30*car, 45*car);
vertex( 15*car, -15*car, 40*car); vertex( 15*car, -30*car, 55*car); vertex( 13*car, -30*car, 55*car); vertex( 13*car, -15*car, 40*car);
vertex( 15*car, -15*car, 30*car); vertex( 15*car, -30*car, 45*car); vertex( 13*car, -30*car, 45*car); vertex( 13*car, -15*car, 30*car);
vertex(-15*car, -15*car, 30*car); vertex(-15*car, -15*car, 40*car); vertex(-15*car, -30*car, 55*car); vertex(-15*car, -30*car, 45*car);
Page 18 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
vertex(-13*car, -15*car, 30*car); vertex(-13*car, -15*car, 40*car); vertex(-13*car, -30*car, 55*car); vertex(-13*car, -30*car, 45*car);
vertex(-15*car, -15*car, 40*car); vertex(-15*car, -30*car, 55*car); vertex(-13*car, -30*car, 55*car); vertex(-13*car, -15*car, 40*car);
vertex(-15*car, -15*car, 30*car); vertex(-15*car, -30*car, 45*car); vertex(-13*car, -30*car, 45*car); vertex(-13*car, -15*car, 30*car);
vertex( 20*car, -30*car, 40*car); vertex( 20*car, -30*car, 60*car); vertex(-20*car, -30*car, 60*car); vertex(-20*car, -30*car, 40*car);
vertex( 20*car, -32*car, 40*car); vertex( 20*car, -32*car, 60*car); vertex(-20*car, -32*car, 60*car); vertex(-20*car, -32*car, 40*car);
vertex( 20*car, -30*car, 40*car); vertex( 20*car, -32*car, 40*car); vertex(-20*car, -32*car, 40*car); vertex(-20*car, -30*car, 40*car);
vertex( 20*car, -30*car, 60*car); vertex( 20*car, -32*car, 60*car); vertex(-20*car, -32*car, 60*car); vertex(-20*car, -30*car, 60*car);
vertex( 20*car, -30*car, 40*car); vertex( 20*car, -30*car, 60*car); vertex( 20*car, -32*car, 60*car); vertex( 20*car, -32*car, 40*car);
vertex(-20*car, -30*car, 40*car); vertex(-20*car, -30*car, 60*car); vertex(-20*car, -32*car, 60*car); vertex(-20*car, -32*car, 40*car);
endShape();
popMatrix();
void serialEvent(Serial port)
interval = millis();
while (port.available() > 0)
int ch = port.read();
print((char)ch);
if (ch == '$') serialCount = 0;
if (aligned < 4)
if (serialCount == 0)
if (ch == '$') aligned++; else aligned = 0;
else if (serialCount == 1)
Page 19 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
if (ch == 2) aligned++; else aligned = 0;
else if (serialCount == 12)
if (ch == '\r') aligned++; else aligned = 0;
else if (serialCount == 13)
if (ch == '\n') aligned++; else aligned = 0;
serialCount++;
if (serialCount == 14) serialCount = 0;
else
if (serialCount > 0 || ch == '$')
teapotPacket[serialCount++] = (char)ch;
if (serialCount == 14)
serialCount = 0;
q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f;
q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f;
q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f;
q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f;
for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i];
quat.set(q[0], q[1], q[2], q[3]);
void drawCylinder(float topRadius, float bottomRadius, float tall, int sides)
float angle = 0;
float angleIncrement = TWO_PI / sides;
beginShape(QUAD_STRIP);
Page 20 of 22
Electrical Engineering Technology ELET 4790 – Senior Project 2
for (int i = 0; i < sides + 1; ++i)
vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
angle += angleIncrement;
endShape();
if (topRadius != 0)
angle = 0;
beginShape(TRIANGLE_FAN);
vertex(0, 0, 0);
for (int i = 0; i < sides + 1; i++)
vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
angle += angleIncrement;
endShape();
if (bottomRadius != 0)
angle = 0;
beginShape(TRIANGLE_FAN);
vertex(0, tall, 0);
for (int i = 0; i < sides + 1; i++)
vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
angle += angleIncrement;
endShape();
Page 21 of 22