Infineon Team
Published © MIT

Autonomous Driving Car V2

Curious about autonomous driving, AI and neural networks? Build your own autonomous driving car and get your hands on these topics!

IntermediateFull instructions provided20 hours2,598
Autonomous Driving Car V2

Things used in this project

Hardware components

Boot Kit XMC1100 (Arduino shield compatible)
Infineon Boot Kit XMC1100 (Arduino shield compatible)
×1
DC-SHIELD BTN9970LV
Infineon DC-SHIELD BTN9970LV
×1
Reely Onroad-Chassis 1:10
×1
Reely 1:10 Wheels
×1
Brushed Motor Carson Modellsport Cup
×1
Savöx Standard-Servo SC-0254MG Digital-Servo
×1
LiPo 7.4 V 3500 mA
×1
Raspberry Pi 4 Model B
Raspberry Pi 4 Model B
×1
Camera Module
Raspberry Pi Camera Module
×1
SanDisk Extreme 32 GB microSDHC
×1
batterie connector
×1

Software apps and online services

donkey car

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
3D Printer (generic)
3D Printer (generic)
Multitool, Screwdriver
Multitool, Screwdriver
Crimp Tool, Heavy-Duty
Crimp Tool, Heavy-Duty

Story

Read more

Custom parts and enclosures

20180323_Magnet_roll_Cage_IFX

roll cage - also a good handle to pick it up

20180706_Basisplatte_1

Baseplate

20180323_Cameramount_M2

camera mount

Schematics

donkey_car_cd_CmgLn2zMwy.png

Code

XMC 1100 Bootkit code

C/C++
This code runs on the XMC.
It emulates the PWM shield used in the donkey car project and is therefore a plug and play solution.
The Raspberry Pi sends throttle and steering data via I2C. The XMC takes care of setting these values via PWM (servo) and motor control signals (BTN997x Motor Shield).
#include "btn99x0_motor_control.hpp"
using namespace btn99x0;


// servo pin
int servo = 8;

// variables for servo control
int pwm;
int Servo_pos = 0;
int Servo_pos_aktuell;

// serial communication
String inString = "";
int neg;

//variables for motor control 
int speedvalue = 0;
int speedvalue_aktuell;
int speedflag = false;


void servoMove(int servo, int Servo_pos){
  pwm = (Servo_pos) + 1500;
  digitalWrite(servo, HIGH);
  delayMicroseconds(pwm);
  digitalWrite(servo, LOW);
}

//i2c communication
int on1;
int off1;

int on0;
int off0;

int r;        //register
int x;        //value

int received;

#include <Wire.h>
DCShield shield;
MotorControl btn_motor_control(shield);

void setup() {
//communications
  Wire.begin(64);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent);  // register event
  Wire.onRequest(requestEvent);  // register event
  Serial.begin(9600);          // start serial for output
  delay(10);
//servo
 pinMode(servo, OUTPUT);
 servoMove(servo, Servo_pos);

//motor   

  btn_motor_control.begin();
  Serial.println("Initialising speed");
  btn_motor_control.set_speed(speedvalue);
  Serial.println("Starting motor");
  Serial.println("Setup Done");
  


}

void loop() {
    
  if(received == 0) {
    Serial.println("fail!");
  }
    
  //servo control
    if(abs(Servo_pos_aktuell - Servo_pos)<200){ //fail save
    servoMove(servo, Servo_pos);   
    }
  Servo_pos_aktuell = Servo_pos; 

  //motor control
  if(abs(speedvalue_aktuell - speedvalue)<200){ //fail save
    btn_motor_control.set_speed(speedvalue*0.4);
    }
  speedvalue_aktuell = speedvalue; 
  
  delay(20);
 
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write(0x01); // respond with 0x01 as expected by master
  Serial.println("0x01");
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {  //checking how many bytes are received
  if(howMany == 2){               //expecting a pair of I2C register and value byte
  received = true;
  }
  else{
    received = false;
  }

     
// read
  while (1 < Wire.available()) { // receive a pair of one register byte and value byte
      r = Wire.read();           // receive register byte
  }
      x = Wire.read();           // receive Value byte as an integer

//process two Speed bytes | two Steer bytes
  switch (r) {  
    case 8:                     //first speed byte
      off0 = x;                 //map read value to first speed byte 
      speedflag = true;         //flag for first speed byte
      break;
    case 9:                     //second speed byte
      if (speedflag == true) {  //only if first speed byte was received
      off0 = off0+(x<<8);       //create two byte speed value
      speedvalue = off0-255;    //calculate offset to match with setup of donkeycar
      speedflag = false;        //reset flag
      }   
      break;
    case 12:                    //first steering byte
      off1 = x;                 //map read value to first steering byte
      break;
    case 13:                    //second steering byte
      off1 = off1+(x<<8);       //create two byte steering value
      Servo_pos = off1-600;     //calculate offset to match with setup of donkeycar
      break;   
 }
}

Credits

Infineon Team

Infineon Team

75 projects • 116 followers

Comments