HC-SR04 машина

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

Здравствуйте!

Помогите составить код для машинки аля объезжайка, используется платформа от РУ машины, драйвер двигателей на L298N (готовый). Есть 2 сонара, а можно сделать с 1, но на сервоприводе? Вообщем спасибо заранее =)

Сам пробовал написать, но машина "сама по себе" =( То объедет, то врежется в ту же стенку.

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

UP

carduino.ru
Offline
Зарегистрирован: 06.12.2011

Могу помочь кодом для двухмоторной машинки

Видео

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

carduino.ru пишет:

Могу помочь кодом для двухмоторной машинки

Видео

Я не откажусь от любой помощи. А машинка, та что на видео - класс!

Mastino
Offline
Зарегистрирован: 03.12.2011
/*
 http://www.bajdi.com (your number one source for buggy Arduino sketches)
 Simple obstacle avoiding robot made from parts mostly sourced from Ebay
 Micro controller = ATmega328P-PU with Arduino bootloader (3.5$ @ Eb.. noooo Tayda Electronics)
 Using a L293D (bought from my favourite Ebay seller Polida) to drive 2 yellow "Ebay motors with yellow wheels"
 Detecting obstacles with an SR04 ultrasonic sensor (uber cheap on Ebay)
 SR04 sensor mounted on SG90 servo (you can get these servo very cheap on ... oh yes you guessed it: EBay) 
*/
  
#include <NewPing.h>  //library for the SR04 ultrasonic sensor
#include <Servo.h>    //servo library, SR04 is mounted on this servo
 
Servo myservo;    
 
#define TRIGGER_PIN  A1  //using analog pins as digital for SR04 sensor 
#define ECHO_PIN     A0  //because I just happened to plug them in here
#define MAX_DISTANCE 200 //the sensor can't measure much further then this distance
 
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
 
#define runEvery(t) for (static typeof(t) _lasttime;(typeof(t))((typeof(t))millis() - _lasttime) > (t);_lasttime += (t))
 
const int EN1 = 6;        //enable motor 1 = pin 1 of L293D
const int direction1 = 7; //direcion motor 1 = pin 2 of L293D
const int EN2 = 5;        //enable motor 2 = pin 9 of L293D
const int direction2 = 4; //direction motor 2 = pin 15 of L293D
// leds are very handy for testing
const int redLed = 10;    // this led will lit up when the robot drives forward
const int greenLed = 11;  // this led will lit up when the robot drives backward
const int yellowLed = 12; // this led will lit up when the robot turns left
const int whiteLed = 13;  // this led will lit up when the robot turns right
 
int uS;                  //value of SR04 ultrasonic sensor
int distance;            //distance in cm of ultrasonic sensor
int pos = 90;            //start position of servo = 90
int servoDirection = 0;  // sweeping left or right
int robotDirection = 0;  //0 = forward, 1 = backward, 2 = left, 3 = right
int lastRobotDirection;  //last direction of the robot
int distanceCenter;    
int distanceLeft;
int distanceRight;
int servoDelay = 20; //with this parameter you can change the sweep speed of the servo
const int speedLeft = 205; //there seems to be a bit of a difference between these cheap motors <img src="http://www.bajdi.com/wp-includes/images/smilies/icon_sad.gif" alt=":(" class="wp-smiley">
const int speedRight = 255; //this motor needs a bit more voltage to keep up with the other
 
long previousMillis = 0;
const int interval = 650;   //interval to switch between the robotDirection, this value will determine
//how long the robot will turn left/right when it detects an obstacle
 
void setup() {               
  pinMode(EN1, OUTPUT); 
  pinMode(direction1, OUTPUT);
  pinMode(EN2, OUTPUT);
  pinMode(direction2, OUTPUT);
  analogWrite(EN1, 0);
  analogWrite(EN2, 0);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(whiteLed, OUTPUT);
  Serial.begin(9600); //to use the serial monitor
  myservo.attach(8); //servo on pin 8
  myservo.write(pos); //center servo
  delay(1500);   // delay so we have some time to put the robot on the floor
}
 
void loop() {
 
  sweepServo(); //function to sweep the servo
   
  getDistance();  //function to get the distance from the ultrasonic sensor
   
    if (pos >= 15 && pos <= 45)
  {
    distanceRight = distance;  //servo is to the right so measured distance = distanceRight
  }
  if (pos >= 135 && pos <= 165)
  {
    distanceLeft = distance; //servo is to the left so measured distance = distanceLeft
  }  
  if (pos > 70 && pos < 110)
  {
    distanceCenter = distance; //servo is centred so measured distance = distanceCenter
  }
 
  if (distanceCenter >= 25)    // coast is clear, full power forward
  {
    robotDirection = 0;        //move forward
  }
  else   //obstacle detected, turn left or right?
  {
    if (distanceLeft > distanceRight) 
    {
      robotDirection = 2; //turn left
    }
    if (distanceLeft < distanceRight)
    {
      robotDirection = 3; //turn right
    }
    if (distanceLeft <= 5 && distanceCenter <= 5 || distanceRight <= 5 && distanceCenter <= 5)
    {
      robotDirection = 1;  // we are stuck <img src="http://www.bajdi.com/wp-includes/images/smilies/icon_sad.gif" alt=":(" class="wp-smiley">  lets try and backup
    }
  }
 
  unsigned long currentMillis = millis();  //set a timer
 
  if(robotDirection == 0 && robotDirection == lastRobotDirection) 
  {
    forward();
    lastRobotDirection = robotDirection;
  }
  if(robotDirection == 0 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval )
  { 
    forward();
    lastRobotDirection = robotDirection;
    previousMillis = currentMillis;
  }
  if(robotDirection == 1 && robotDirection == lastRobotDirection)
  {
    backward();
    lastRobotDirection = robotDirection;
  }
  if(robotDirection == 1 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval )
  { 
    backward();
    lastRobotDirection = robotDirection;
    previousMillis = currentMillis;
  }
  if(robotDirection == 2 && robotDirection == lastRobotDirection)
  {
    left();
    lastRobotDirection = robotDirection;
  }
  if(robotDirection == 2 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval )
  { 
    left();
    lastRobotDirection = robotDirection;
    previousMillis = currentMillis;
  }
  if(robotDirection == 3 && robotDirection == lastRobotDirection)
  {
    right();
    lastRobotDirection = robotDirection;
  }
  if(robotDirection == 3 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval )
  { 
    right();
    lastRobotDirection = robotDirection;
    previousMillis = currentMillis;
  }
}
 
void forward()
{
  digitalWrite(direction1, HIGH);
  digitalWrite(direction2, HIGH);  
  analogWrite(EN1, speedLeft);
  analogWrite(EN2, speedRight);
  digitalWrite(redLed, HIGH);
  digitalWrite(greenLed, LOW);
  digitalWrite(yellowLed, LOW);
  digitalWrite(whiteLed, LOW);
}
 
void stop()
{
  digitalWrite(direction1, LOW);  
  digitalWrite(direction2, LOW);  
  analogWrite(EN1, 0);
  analogWrite(EN2, 0);
  digitalWrite(redLed, LOW);
  digitalWrite(greenLed, LOW);
  digitalWrite(yellowLed, LOW);
  digitalWrite(whiteLed, LOW);
}
 
void backward()
{
  digitalWrite(direction1, LOW); 
  digitalWrite(direction2, LOW);  
  analogWrite(EN1, speedLeft+35);
  analogWrite(EN2, speedRight-15);
  digitalWrite(redLed, LOW);
  digitalWrite(greenLed, HIGH);
  digitalWrite(yellowLed, LOW);
  digitalWrite(whiteLed, LOW);
}
 
void left()
{
  digitalWrite(direction1, LOW);
  digitalWrite(direction2, HIGH);  
  analogWrite(EN1, speedLeft+35);
  analogWrite(EN2, speedRight);
  digitalWrite(redLed, LOW);
  digitalWrite(greenLed, LOW);
  digitalWrite(yellowLed, HIGH);
  digitalWrite(whiteLed, LOW);
}
 
void right()
{
  digitalWrite(direction1, HIGH);
  digitalWrite(direction2, LOW);  
  analogWrite(EN1, speedLeft);
  analogWrite(EN2, speedRight-30);
  digitalWrite(redLed, LOW);
  digitalWrite(greenLed, LOW);
  digitalWrite(yellowLed, LOW);
  digitalWrite(whiteLed, HIGH);
}
 
void getDistance()
{
  runEvery(40)   //loop for ultrasonic measurement
  {
    uS = sonar.ping();
    distance = uS / US_ROUNDTRIP_CM;
    if (uS == NO_ECHO) // if the sensor did not get a ping       
    {
      distance = MAX_DISTANCE;      //so the distance must be bigger then the max vaulue of the sensor
    }
    Serial.print("Ping: "); //to check distance on the serial monitor
    Serial.print(distance);
    Serial.println("cm");
  }
}
 
void sweepServo()
{
  runEvery(servoDelay)  //this loop determines the servo position
  {
    if(pos < 165 && servoDirection == 0)    // 165 = servo to the left
    {                                 
      pos = pos + 5;                        // +1 was to slow
    }
    if(pos > 15 && servoDirection == 1)     // 15 = servo to the right
    {                               
      pos = pos - 5;
    }   
  }  
  if (pos == 165 )   
  {
    servoDirection = 1;  //changes the direction
  }
  if (pos == 15 )    
  {
    servoDirection = 0;  //changes the direction
  }  
  myservo.write(pos);  //move that servo!
}

 

carduino.ru
Offline
Зарегистрирован: 06.12.2011

Tarantul_acc пишет:

Я не откажусь от любой помощи. А машинка, та что на видео - класс!

Будут вопросы, задавай

Цитата:

#include <CyberLib.h>

#define motors_init {D4_Out; D5_Out; D6_Out; D7_Out;}
#define robot_go {D4_Low; D5_High; D6_High; D7_Low;}
#define robot_stop {D4_Low; D5_Low; D6_Low; D7_Low;}
#define robot_rotation_left {D4_Low; D5_High; D6_Low; D7_High;}
#define robot_rotation_right {D4_High; D5_Low; D6_High; D7_Low;}

#define size_buff 5 //размер массива sensor
uint16_t sensor[size_buff]; //массив для хранения замеров дальномера
uint8_t stat=0; //направление разворота

void setup()
{
motors_init; //инициализация выходов моторов
D11_Out; //динамик
D14_Out; D14_Low; //пин trig ультразвукового сонара
D15_In; //пин echo ультразвукового сонара
randomSeed(A6_Read); //Получить случайное значение
for(uint8_t i=0; i<12; i++) beep(50, random(100, 1000)); //звуковое оповещение готовности робота
wdt_enable (WDTO_500MS); //Сторожевая собака 0,5сек.
}

void loop()
{Start
uint16_t dist=GetDistance(); //производим замер дистанции

if( dist < 10) {rotation(stat, 255);} else //если 10см максимальный угол разворота
if( dist < 20) {rotation(stat, 200);} else //если 20см средний угол разворота
if( dist < 40) {rotation(stat, 130);} else //если 40см минимальный угол разворота
{robot_go; stat=~stat;} //поехали!!!
wdt_reset(); //покормить собаку
End;}

//***************************************************
void rotation(uint8_t arr, uint8_t dur)
{
switch (arr) //смотрим в каком направление разворачиваться
{
case 0: robot_rotation_right;
break;
case 255: robot_rotation_left;
break;
}
delay_ms(dur); //угол разворота
robot_stop; //стоп мотор!
}
//***************************************************
uint16_t GetDistance()
{
uint16_t dist;
for (uint8_t i = 0; i < size_buff; ++i) //производим несколько замеров
{
D14_High; delay_us(10); D14_Low; //запустить измерение
dist = pulseIn(15, HIGH, 2400); //считываем длительность времени прохождения эха, ограничить время ожидания
if(dist==0) dist=2400;
sensor[i]=dist; //сохранить в массиве
delay_ms(40); //задержка между посылками
wdt_reset(); //покормить собаку, что бы она не сбежала
}
dist=(find_similar(sensor, size_buff, 58))/58; // //фильтруем показания датчика и переводим в см
return dist;
}

//***************************************************
void beep(uint8_t dur, uint16_t frq)
{
dur=(1000/frq)*dur; //рассчет длительности бипа
for(byte i=0; i<dur; i++)
{
D11_High;
delay_us(frq);
D11_Low;
delay_us(frq);
}
}

 

Схема

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

Спасибо всем, буду разбираться!