Final Project: Mini-Tesla car

Description:

For my project, I am building a mini-Tesla car that will feature both autopilot mode and manual mode. When the autopilot mode is enabled, the car will be able to move around and avoid all obstacles. Whereas for the manual mode, the user will be able to control the car through processing using the arrows/buttons.

Components:

I am using the Adafruit motor shield to control the wheels and add movement to the car. To use it correctly, I had to download a new library called “Adafruit Motor Shield V2 Library”, and a couple of other sub-libraries that come with it.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <Adafruit_MotorShield.h>
Adafruit_MotorShield AFMS(0x61);
Adafruit_DCMotor *rb = AFMS.getMotor(3);
Adafruit_DCMotor *lf = AFMS.getMotor(2);
Adafruit_DCMotor *lb = AFMS.getMotor(1);
Adafruit_DCMotor *rf = AFMS.getMotor(4);
#include <Adafruit_MotorShield.h> Adafruit_MotorShield AFMS(0x61); Adafruit_DCMotor *rb = AFMS.getMotor(3); Adafruit_DCMotor *lf = AFMS.getMotor(2); Adafruit_DCMotor *lb = AFMS.getMotor(1); Adafruit_DCMotor *rf = AFMS.getMotor(4);
#include <Adafruit_MotorShield.h>
 
Adafruit_MotorShield AFMS(0x61);

Adafruit_DCMotor *rb = AFMS.getMotor(3);
Adafruit_DCMotor *lf = AFMS.getMotor(2);
Adafruit_DCMotor *lb = AFMS.getMotor(1);
Adafruit_DCMotor *rf = AFMS.getMotor(4);

I am also using a Servo and an Ultrasonic Sensor to detect obstacles around the car.

Setup:

To begin with, in my setup function, I am setting the pin modes and the motors’ speed, then ensuring that all motors are stopped.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
void setup(){
AFMS.begin();
Serial.begin(9600);
Serial.println("0,0");
myservo.attach(3);
pinMode(4,OUTPUT);
pinMode(5,INPUT);
rb->setSpeed(car_speed);
lb->setSpeed(car_speed);
rf->setSpeed(car_speed);
lf->setSpeed(car_speed);
delay(1500);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
void setup(){ AFMS.begin(); Serial.begin(9600); Serial.println("0,0"); myservo.attach(3); pinMode(4,OUTPUT); pinMode(5,INPUT); rb->setSpeed(car_speed); lb->setSpeed(car_speed); rf->setSpeed(car_speed); lf->setSpeed(car_speed); delay(1500); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); }
void setup(){
  AFMS.begin();
  Serial.begin(9600);
  Serial.println("0,0");
  myservo.attach(3);
  pinMode(4,OUTPUT);
  pinMode(5,INPUT);
  rb->setSpeed(car_speed);
  lb->setSpeed(car_speed);
  rf->setSpeed(car_speed);
  lf->setSpeed(car_speed);
  delay(1500);
  rb->run(RELEASE);
  lb->run(RELEASE);
  rf->run(RELEASE);
  lf->run(RELEASE);
}
Autopilot mode:
Measuring the distance:

At first, I am setting my servo to look ahead, then using an ultrasonic I am measuring the distance to the next obstacle (basically to check if there are objects ahead).

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
myservo.write(90);
// calculate the distance ahead
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(5);
digitalWrite(4, LOW);
duration = pulseIn(5, HIGH);
dist = duration/29/2;
myservo.write(90); // calculate the distance ahead digitalWrite(4, LOW); delayMicroseconds(2); digitalWrite(4, HIGH); delayMicroseconds(5); digitalWrite(4, LOW); duration = pulseIn(5, HIGH); dist = duration/29/2;
myservo.write(90);
// calculate the distance ahead
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(5);
digitalWrite(4, LOW);
duration = pulseIn(5, HIGH);
dist = duration/29/2;

Then, using a while() loop, I keep measuring the distance while moving forward, until the obstacle is within the minimum stopping distance.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
while (dist >= min_dist){
rb->run(FORWARD);
lb->run(FORWARD);
rf->run(FORWARD);
lf->run(FORWARD);
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(5);
digitalWrite(4, LOW);
duration = pulseIn(5, HIGH);
dist = duration/29/2;
}
while (dist >= min_dist){ rb->run(FORWARD); lb->run(FORWARD); rf->run(FORWARD); lf->run(FORWARD); digitalWrite(4, LOW); delayMicroseconds(2); digitalWrite(4, HIGH); delayMicroseconds(5); digitalWrite(4, LOW); duration = pulseIn(5, HIGH); dist = duration/29/2; }
while (dist >= min_dist){
  rb->run(FORWARD);
  lb->run(FORWARD);
  rf->run(FORWARD);
  lf->run(FORWARD);
  digitalWrite(4, LOW);
  delayMicroseconds(2);
  digitalWrite(4, HIGH);
  delayMicroseconds(5);
  digitalWrite(4, LOW);
  duration = pulseIn(5, HIGH);
  dist = duration/29/2;
}

If the car is close enough to the obstacle, the wheels are stopped, the servo checks both the right and left directions, and using the ultrasonic, we get both distances.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int rdist = 0;
int ldist = 0;
// calculate right distance
myservo.write(0);
delay(1500);
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(5);
digitalWrite(4, LOW);
pinMode(5, INPUT);
duration = pulseIn(5, HIGH);
rdist = duration/29/2;
// calculate left distance
myservo.write(180);
delay(1500);
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(5);
digitalWrite(4, LOW);
pinMode(5, INPUT);
duration = pulseIn(5, HIGH);
ldist = duration/29/2;
int rdist = 0; int ldist = 0; // calculate right distance myservo.write(0); delay(1500); pinMode(4, OUTPUT); digitalWrite(4, LOW); delayMicroseconds(2); digitalWrite(4, HIGH); delayMicroseconds(5); digitalWrite(4, LOW); pinMode(5, INPUT); duration = pulseIn(5, HIGH); rdist = duration/29/2; // calculate left distance myservo.write(180); delay(1500); pinMode(4, OUTPUT); digitalWrite(4, LOW); delayMicroseconds(2); digitalWrite(4, HIGH); delayMicroseconds(5); digitalWrite(4, LOW); pinMode(5, INPUT); duration = pulseIn(5, HIGH); ldist = duration/29/2;
int rdist = 0;
int ldist = 0;

// calculate right distance
myservo.write(0);
delay(1500);
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(5);
digitalWrite(4, LOW);
pinMode(5, INPUT);
duration = pulseIn(5, HIGH);
rdist = duration/29/2;

// calculate left distance
myservo.write(180);
delay(1500);
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(5);
digitalWrite(4, LOW);
pinMode(5, INPUT);
duration = pulseIn(5, HIGH);
ldist = duration/29/2;

Here, we come across 4 scenarios:

1st scenario: 

If both directions are blocked (distance is below the minimum stopping distance), the car does a U-turn. To do it, the car keeps turning to the right until it reaches 180 degrees (using Delay).

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// if both directions are blocked, do a u-turn
if (rdist<= min_dist && ldist<= min_dist) {
rb->setSpeed(255);
lb->setSpeed(255);
rf->setSpeed(255);
lf->setSpeed(255);
rb->run(BACKWARD);
lb->run(FORWARD);
rf->run(BACKWARD);
lf->run(FORWARD);
delay(1400);
rb->setSpeed(60);
lb->setSpeed(60);
rf->setSpeed(60);
lf->setSpeed(60);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// if both directions are blocked, do a u-turn if (rdist<= min_dist && ldist<= min_dist) { rb->setSpeed(255); lb->setSpeed(255); rf->setSpeed(255); lf->setSpeed(255); rb->run(BACKWARD); lb->run(FORWARD); rf->run(BACKWARD); lf->run(FORWARD); delay(1400); rb->setSpeed(60); lb->setSpeed(60); rf->setSpeed(60); lf->setSpeed(60); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); }
// if both directions are blocked, do a u-turn
if (rdist<= min_dist && ldist<= min_dist) {
  rb->setSpeed(255);
  lb->setSpeed(255);
  rf->setSpeed(255);
  lf->setSpeed(255);
  rb->run(BACKWARD);
  lb->run(FORWARD);
  rf->run(BACKWARD);
  lf->run(FORWARD);
  delay(1400);
  rb->setSpeed(60);
  lb->setSpeed(60);
  rf->setSpeed(60);
  lf->setSpeed(60);
  rb->run(RELEASE);
  lb->run(RELEASE);
  rf->run(RELEASE);
  lf->run(RELEASE);
}

2nd scenario:

If both directions are free (distance is much higher than the minimum stopping distance), the car chooses the right direction. 🙂

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// if both directions are free, choose right
else if (rdist>=20 && ldist>=20){
rb->setSpeed(255);
lb->setSpeed(255);
rf->setSpeed(255);
lf->setSpeed(255);
rb->run(BACKWARD);
lb->run(FORWARD);
rf->run(BACKWARD);
lf->run(FORWARD);
delay(700);
rb->setSpeed(60);
lb->setSpeed(60);
rf->setSpeed(60);
lf->setSpeed(60);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// if both directions are free, choose right else if (rdist>=20 && ldist>=20){ rb->setSpeed(255); lb->setSpeed(255); rf->setSpeed(255); lf->setSpeed(255); rb->run(BACKWARD); lb->run(FORWARD); rf->run(BACKWARD); lf->run(FORWARD); delay(700); rb->setSpeed(60); lb->setSpeed(60); rf->setSpeed(60); lf->setSpeed(60); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); }
// if both directions are free, choose right
else if (rdist>=20 && ldist>=20){
  rb->setSpeed(255);
  lb->setSpeed(255);
  rf->setSpeed(255);
  lf->setSpeed(255);
  rb->run(BACKWARD);
  lb->run(FORWARD);
  rf->run(BACKWARD);
  lf->run(FORWARD);
  delay(700);
  rb->setSpeed(60);
  lb->setSpeed(60);
  rf->setSpeed(60);
  lf->setSpeed(60);
  rb->run(RELEASE);
  lb->run(RELEASE);
  rf->run(RELEASE);
  lf->run(RELEASE);
}

3rd scenario:

If the right direction is free, but the left is blocked, choose the right direction.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// if right way is free, choose right
else if (rdist>=ldist){
rb->setSpeed(255);
lb->setSpeed(255);
rf->setSpeed(255);
lf->setSpeed(255);
rb->run(BACKWARD);
lb->run(FORWARD);
rf->run(BACKWARD);
lf->run(FORWARD);
delay(700);
rb->setSpeed(60);
lb->setSpeed(60);
rf->setSpeed(60);
lf->setSpeed(60);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// if right way is free, choose right else if (rdist>=ldist){ rb->setSpeed(255); lb->setSpeed(255); rf->setSpeed(255); lf->setSpeed(255); rb->run(BACKWARD); lb->run(FORWARD); rf->run(BACKWARD); lf->run(FORWARD); delay(700); rb->setSpeed(60); lb->setSpeed(60); rf->setSpeed(60); lf->setSpeed(60); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); }
// if right way is free, choose right
else if (rdist>=ldist){
  rb->setSpeed(255);
  lb->setSpeed(255);
  rf->setSpeed(255);
  lf->setSpeed(255);
  rb->run(BACKWARD);
  lb->run(FORWARD);
  rf->run(BACKWARD);
  lf->run(FORWARD);
  delay(700);
  rb->setSpeed(60);
  lb->setSpeed(60);
  rf->setSpeed(60);
  lf->setSpeed(60);
  rb->run(RELEASE);
  lb->run(RELEASE);
  rf->run(RELEASE);
  lf->run(RELEASE);
}

4th scenario:

If the left direction is free, but the right is blocked, choose the left direction.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// if left way is free, choose left
else if (rdist<ldist){
rb->setSpeed(255);
lb->setSpeed(255);
rf->setSpeed(255);
lf->setSpeed(255);
rb->run(FORWARD);
lb->run(BACKWARD);
rf->run(FORWARD);
lf->run(BACKWARD);
delay(700);
rb->setSpeed(60);
lb->setSpeed(60);
rf->setSpeed(60);
lf->setSpeed(60);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// if left way is free, choose left else if (rdist<ldist){ rb->setSpeed(255); lb->setSpeed(255); rf->setSpeed(255); lf->setSpeed(255); rb->run(FORWARD); lb->run(BACKWARD); rf->run(FORWARD); lf->run(BACKWARD); delay(700); rb->setSpeed(60); lb->setSpeed(60); rf->setSpeed(60); lf->setSpeed(60); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); }
// if left way is free, choose left
else if (rdist<ldist){
  rb->setSpeed(255);
  lb->setSpeed(255);
  rf->setSpeed(255);
  lf->setSpeed(255);
  rb->run(FORWARD);
  lb->run(BACKWARD);
  rf->run(FORWARD);
  lf->run(BACKWARD);
  delay(700);
  rb->setSpeed(60);
  lb->setSpeed(60);
  rf->setSpeed(60);
  lf->setSpeed(60);
  rb->run(RELEASE);
  lb->run(RELEASE);
  rf->run(RELEASE);
  lf->run(RELEASE);
}

Manual mode:

When enabled, the user can control the car through Processing using either the arrows or the screen buttons. When an action is specified, Processing sends the data to Arduino.

To receive data from Processing, I am doing the following:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
while (Serial.available()) {
if (Serial.read() == '\n') {
state = Serial.parseInt();
direc = Serial.parseInt();
}
}
while (Serial.available()) { if (Serial.read() == '\n') { state = Serial.parseInt(); direc = Serial.parseInt(); } }
while (Serial.available()) {
  if (Serial.read() == '\n') {
    state = Serial.parseInt();
    direc = Serial.parseInt();
  }
}

To control the car:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
else if (autopilot==false) {
// forward
if (direc == 0) {
rb->setSpeed(60);
lb->setSpeed(60);
rf->setSpeed(60);
lf->setSpeed(60);
rb->run(FORWARD);
lb->run(FORWARD);
rf->run(FORWARD);
lf->run(FORWARD);
delay(200);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// right
if (direc == 1) {
rb->setSpeed(255);
lb->setSpeed(255);
rf->setSpeed(255);
lf->setSpeed(255);
rb->run(BACKWARD);
lb->run(FORWARD);
rf->run(BACKWARD);
lf->run(FORWARD);
delay(100);
rb->setSpeed(60);
lb->setSpeed(60);
rf->setSpeed(60);
lf->setSpeed(60);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// backward
if (direc == 2) {
rb->run(BACKWARD);
lb->run(BACKWARD);
rf->run(BACKWARD);
lf->run(BACKWARD);
delay(200);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// left
if (direc == 3) {
rb->setSpeed(255);
lb->setSpeed(255);
rf->setSpeed(255);
lf->setSpeed(255);
rb->run(FORWARD);
lb->run(BACKWARD);
rf->run(FORWARD);
lf->run(BACKWARD);
delay(100);
rb->setSpeed(60);
lb->setSpeed(60);
rf->setSpeed(60);
lf->setSpeed(60);
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
// stop
if (direc == 4) {
rb->run(RELEASE);
lb->run(RELEASE);
rf->run(RELEASE);
lf->run(RELEASE);
}
}
else if (autopilot==false) { // forward if (direc == 0) { rb->setSpeed(60); lb->setSpeed(60); rf->setSpeed(60); lf->setSpeed(60); rb->run(FORWARD); lb->run(FORWARD); rf->run(FORWARD); lf->run(FORWARD); delay(200); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); } // right if (direc == 1) { rb->setSpeed(255); lb->setSpeed(255); rf->setSpeed(255); lf->setSpeed(255); rb->run(BACKWARD); lb->run(FORWARD); rf->run(BACKWARD); lf->run(FORWARD); delay(100); rb->setSpeed(60); lb->setSpeed(60); rf->setSpeed(60); lf->setSpeed(60); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); } // backward if (direc == 2) { rb->run(BACKWARD); lb->run(BACKWARD); rf->run(BACKWARD); lf->run(BACKWARD); delay(200); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); } // left if (direc == 3) { rb->setSpeed(255); lb->setSpeed(255); rf->setSpeed(255); lf->setSpeed(255); rb->run(FORWARD); lb->run(BACKWARD); rf->run(FORWARD); lf->run(BACKWARD); delay(100); rb->setSpeed(60); lb->setSpeed(60); rf->setSpeed(60); lf->setSpeed(60); rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); } // stop if (direc == 4) { rb->run(RELEASE); lb->run(RELEASE); rf->run(RELEASE); lf->run(RELEASE); } }
else if (autopilot==false) {
  // forward
  if (direc == 0) {
    rb->setSpeed(60);
    lb->setSpeed(60);
    rf->setSpeed(60);
    lf->setSpeed(60);
    rb->run(FORWARD);
    lb->run(FORWARD);
    rf->run(FORWARD);
    lf->run(FORWARD);
    delay(200);
    rb->run(RELEASE);
    lb->run(RELEASE);
    rf->run(RELEASE);
    lf->run(RELEASE);
    
  }
  // right
  if (direc == 1) {
    rb->setSpeed(255);
    lb->setSpeed(255);
    rf->setSpeed(255);
    lf->setSpeed(255);
    rb->run(BACKWARD);
    lb->run(FORWARD);
    rf->run(BACKWARD);
    lf->run(FORWARD);
    delay(100);
    rb->setSpeed(60);
    lb->setSpeed(60);
    rf->setSpeed(60);
    lf->setSpeed(60);
    rb->run(RELEASE);
    lb->run(RELEASE);
    rf->run(RELEASE);
    lf->run(RELEASE);
  }
  // backward
  if (direc == 2) {
    rb->run(BACKWARD);
    lb->run(BACKWARD);
    rf->run(BACKWARD);
    lf->run(BACKWARD);
    delay(200);
    rb->run(RELEASE);
    lb->run(RELEASE);
    rf->run(RELEASE);
    lf->run(RELEASE);
  }
  // left
  if (direc == 3) {
    rb->setSpeed(255);
    lb->setSpeed(255);
    rf->setSpeed(255);
    lf->setSpeed(255);
    rb->run(FORWARD);
    lb->run(BACKWARD);
    rf->run(FORWARD);
    lf->run(BACKWARD);
    delay(100);
    rb->setSpeed(60);
    lb->setSpeed(60);
    rf->setSpeed(60);
    lf->setSpeed(60);
    rb->run(RELEASE);
    lb->run(RELEASE);
    rf->run(RELEASE);
    lf->run(RELEASE);
  }
  // stop
  if (direc == 4) {
    rb->run(RELEASE);
    lb->run(RELEASE);
    rf->run(RELEASE);
    lf->run(RELEASE);
  }
}
Processing:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import processing.serial.*;
Serial myPort;
PImage img;
void setup() {
size(960,720);
printArray(Serial.list());
String portname=Serial.list()[1];
println(portname);
myPort = new Serial(this,portname,9600);
myPort.clear();
myPort.bufferUntil('\n');
img = loadImage("bg.png");
}
void draw() {
background(#e9eaea);
image(img, width*1/2-135, height/2-125,270,250);
fill(#555555);
textSize(30);
text("Use the arrows to control the car.", width*1/2-200, height/2+ 145);
text("Click on S to switch to stop the car.", width*1/2-210, height/2+ 195);
text("Click on A to switch to autopilot mode.", width*1/2-225, height/2+ 245);
if(keyPressed) {
//if a key is pressed, do the following
if (key == 'm'){
myPort.write(0+","+9+"\n");
}
else if (keyCode == UP){
myPort.write(0+","+0+"\n");
}
else if (keyCode == DOWN){
myPort.write(0+","+2+"\n");
}
else if (keyCode == RIGHT){
myPort.write(0+","+1+"\n");
}
else if (keyCode == LEFT){
myPort.write(0+","+3+"\n");
}
else if (key == 's'){
myPort.write(0+","+4+"\n");
}
else if (key == 'a'){
myPort.write(1+","+0+"\n");
}
else {
myPort.write(4+","+9+"\n");
}
}
else {
myPort.write(4+","+9+"\n");
}
}
import processing.serial.*; Serial myPort; PImage img; void setup() { size(960,720); printArray(Serial.list()); String portname=Serial.list()[1]; println(portname); myPort = new Serial(this,portname,9600); myPort.clear(); myPort.bufferUntil('\n'); img = loadImage("bg.png"); } void draw() { background(#e9eaea); image(img, width*1/2-135, height/2-125,270,250); fill(#555555); textSize(30); text("Use the arrows to control the car.", width*1/2-200, height/2+ 145); text("Click on S to switch to stop the car.", width*1/2-210, height/2+ 195); text("Click on A to switch to autopilot mode.", width*1/2-225, height/2+ 245); if(keyPressed) { //if a key is pressed, do the following if (key == 'm'){ myPort.write(0+","+9+"\n"); } else if (keyCode == UP){ myPort.write(0+","+0+"\n"); } else if (keyCode == DOWN){ myPort.write(0+","+2+"\n"); } else if (keyCode == RIGHT){ myPort.write(0+","+1+"\n"); } else if (keyCode == LEFT){ myPort.write(0+","+3+"\n"); } else if (key == 's'){ myPort.write(0+","+4+"\n"); } else if (key == 'a'){ myPort.write(1+","+0+"\n"); } else { myPort.write(4+","+9+"\n"); } } else { myPort.write(4+","+9+"\n"); } }
import processing.serial.*;
Serial myPort;  
PImage img;

void setup() { 
  size(960,720);
  printArray(Serial.list());
  String portname=Serial.list()[1];
  println(portname);
  myPort = new Serial(this,portname,9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  img = loadImage("bg.png");
}

void draw() {
  background(#e9eaea);
  image(img, width*1/2-135, height/2-125,270,250);
  fill(#555555);
  textSize(30);
  text("Use the arrows to control the car.", width*1/2-200, height/2+ 145);
  text("Click on S to switch to stop the car.", width*1/2-210, height/2+ 195);
  text("Click on A to switch to autopilot mode.", width*1/2-225, height/2+ 245);
  if(keyPressed) { 
    //if a key is pressed, do the following
    if (key == 'm'){     
      myPort.write(0+","+9+"\n");
    }
    else if (keyCode == UP){     
      myPort.write(0+","+0+"\n"); 
    }
    else if (keyCode == DOWN){     
      myPort.write(0+","+2+"\n");  
    }
    else if (keyCode == RIGHT){     
      myPort.write(0+","+1+"\n");  
    }
    else if (keyCode == LEFT){     
      myPort.write(0+","+3+"\n");  
    }
    else if (key == 's'){     
      myPort.write(0+","+4+"\n");
    }
    else if (key == 'a'){     
      myPort.write(1+","+0+"\n");
    }
    else {
      myPort.write(4+","+9+"\n");
    }
  }
  else {
    myPort.write(4+","+9+"\n");
  }
}
IM Showcase:

Here are a couple of videos from the IM showcase:

 

Leave a Reply