Project 12 Ultrasonic Following Tank

Beschrijving

In project 11 hebben we een auto met obstakeldetectie gemaakt. In feite hoeven we alleen maar de testcode aan te passen om een auto met obstakeldetectie om te zetten in een volgende auto. In deze les maken we een ultrasone volgende robot. De ultrasone sensor detecteert de afstand tussen de slimme auto en het obstakel om de tankwagen te laten bewegen.

De specifieke logica van de ultrasone volgende robot is als volgt:

Detectie

Gemeten afstand van frontale obstakels

Afstand (eenheid: cm)

Instellingen

Servo hoek 90°

8X16 LED-paneel toont het pictogram “V”

Als

20≤ afstand ≤60

Status

Vooruit gaan(PWM ingesteld op 200)

Als

10<afstand<20

afstand>60

Status

Stoppen

Als

afstand ≤10

Status

Stoppen(PWM ingesteld op 200)

Stroomdiagram

Verbindingsschema

Opmerkingen voor bedrading:

1.8x16 LED-paneel

V5 Sensor Shield

GND

-(GND)

VCC

+(VCC)

SDA

SDA

SCL

SCL

Testcode

 /*
 keyestudio Mini Tank Robot V2.1
 les 12
 ultrasone volgende tank
 http://www.keyestudio.com
*/ 
//Array, gebruikt om de gegevens van het patroon op te slaan, kan zelf worden berekend of verkregen via het modulus-gereedschap
unsigned char start01[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char front[] = {0x00,0x00,0x00,0x00,0x00,0x24,0x12,0x09,0x12,0x24,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char back[] = {0x00,0x00,0x00,0x00,0x00,0x24,0x48,0x90,0x48,0x24,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char left[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x44,0x28,0x10,0x44,0x28,0x10,0x00};
unsigned char right[] = {0x00,0x10,0x28,0x44,0x10,0x28,0x44,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char STOP01[] = {0x2E,0x2A,0x3A,0x00,0x02,0x3E,0x02,0x00,0x3E,0x22,0x3E,0x00,0x3E,0x0A,0x0E,0x00};
unsigned char clear[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
#define SCL_Pin  A5  //Stel klokpin in op A5
#define SDA_Pin  A4  //Stel gegevenspin in op A4

#define ML_Ctrl 13  //definieer de richtingscontroleppin van de linkermotor
#define ML_PWM 11   //definieer PWM-controleppin van de linkermotor
#define MR_Ctrl 12  //definieer de richtingscontroleppin van de rechtermotor
#define MR_PWM 3   //definieer PWM-controleppin van de rechtermotor
#define Trig 5  //ultrasone trig-pin
#define Echo 4  //ultrasone echo-pin
int distance;
int pulsewidth;
#define servoPin 9  //servo-pin
void setup(){
  Serial.begin(9600);
  pinMode(SCL_Pin,OUTPUT);
  pinMode(SDA_Pin,OUTPUT);
  matrix_display(clear); //Wis het display
  matrix_display(start01);  //toon startpatroon
  pinMode(servoPin, OUTPUT);
  procedure(90); //stel servo in op 90°
  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
  pinMode(ML_Ctrl, OUTPUT);
  pinMode(ML_PWM, OUTPUT);
  pinMode(MR_Ctrl, OUTPUT);
  pinMode(MR_PWM, OUTPUT);
}
void loop(){
  distance = checkdistance();  //wijs de afstand gedetecteerd door ultrasone sensor toe aan distance
  if (distance >= 20 && distance <= 60) //bereik om vooruit te gaan
  {
    Car_front();
  }
  else if (distance > 10 && distance < 20)  //bereik om te stoppen
  {
    Car_Stop();
  }
  else if (distance <= 10)  //bereik om achteruit te gaan
  {
    Car_back();
  }
  else  //andere situaties, stoppen
  {
    Car_Stop();
  }
}
/***********de functie voor motorwerking****************/
void Car_front()
{
  digitalWrite(MR_Ctrl,LOW);
  analogWrite(MR_PWM,200);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,200);
}
void Car_back()
{
  digitalWrite(MR_Ctrl,HIGH);
  analogWrite(MR_PWM,200);
  digitalWrite(ML_Ctrl,HIGH);
  analogWrite(ML_PWM,200);
}
void Car_left()
{
  digitalWrite(MR_Ctrl,LOW);
  analogWrite(MR_PWM,200);
  digitalWrite(ML_Ctrl,HIGH);
  analogWrite(ML_PWM,200);
}
void Car_right()
{
  digitalWrite(MR_Ctrl,HIGH);
  analogWrite(MR_PWM,200);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,200);
}
void Car_Stop()
{
  digitalWrite(MR_Ctrl,LOW);
  analogWrite(MR_PWM,0);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,0);
}

/******************puntmatrix********************/
// de functie voor puntmatrix-display
void matrix_display(unsigned char matrix_value[])
{
  IIC_start(); // roep de functie aan die gegevenstransmissie start
  IIC_send(0xc0);  //Kies adres
  
  for(int i = 0;i < 16;i++) //patroongegevens hebben 16 bits
  {
     IIC_send(matrix_value[i]); //gegevens om patronen over te dragen
  }

  IIC_end();   //beëindig het overbrengen van gegevenspatroon
  
  IIC_start();
  IIC_send(0x8A);  //selecteer pulsbreedte 4/16, controleer display
  IIC_end();
}

//De voorwaarde om gegevenstransmissie te starten
void IIC_start()
{
  digitalWrite(SCL_Pin,HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,LOW);
  delayMicroseconds(3);
}

// gegevens overbrengen
void IIC_send(unsigned char send_data)
{
  for(char i = 0;i < 8;i++)  //Elke byte heeft 8 bits
  {
      digitalWrite(SCL_Pin,LOW);  //trek klokpin SCL_Pin omlaag om de signalen van SDA te veranderen      
delayMicroseconds(3);
      if(send_data & 0x01)  //stel hoog en laag niveau van SDA_Pin in volgens 1 of 0 van elke bit
      {
        digitalWrite(SDA_Pin,HIGH);
      }
      else
      {
        digitalWrite(SDA_Pin,LOW);
      }
      delayMicroseconds(3);
      digitalWrite(SCL_Pin,HIGH); //trek klokpin SCL_Pin omhoog om gegevenstransmissie te stoppen
      delayMicroseconds(3);
      send_data = send_data >> 1;  // detecteer bit voor bit, dus verschuif de gegevens naar rechts met één
  }
}
//Het teken dat gegevenstransmissie eindigt
void IIC_end()
{
  digitalWrite(SCL_Pin,LOW);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin,HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,HIGH);
  delayMicroseconds(3);
}
/***************einde puntmatrix-display******************/
//De functie om servo te controleren
void procedure(int myangle) {
  for (int i = 0; i <= 50; i = i + (1)) {
    pulsewidth = myangle * 11 + 500;
    digitalWrite(servoPin,HIGH);
    delayMicroseconds(pulsewidth);
    digitalWrite(servoPin,LOW);
    delay((20 - pulsewidth / 1000));
  }}
//De functie om ultrasone sensorfunctie te controleren die ultrasone controleert
float checkdistance() {
  digitalWrite(Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);
  float distance = pulseIn(Echo, HIGH) / 58.20;  //58.20, dat wil zeggen, 2*29.1=58.2
  delay(10);
  return distance;
}
//****************************************************************

Testresultaat

Code succesvol geüpload, DIP-schakelaar is naar het rechtereinde verschoven, de servo roteert naar 90°, “V” wordt weergegeven op het 8X16 LED-paneel en de slimme auto beweegt mee met het obstakel.