Управление роботом с ультразвуковым дальномером

elranon
Offline
Зарегистрирован: 28.05.2012

Привет,

прошу помочь с кодом. 

Есть робот с ультразвуковым дальномером, почему то работает не корректно. 

По логике если расстояние менее 10 см - робот должен остановится.

но почему то он останавливается вне зависимости от физического препятствия, при мониторинге порта видно что проскакивает расстояние с минусом.

52 cm
52 cm
52 cm
-529 cm
43 cm
-46 cm
50 cm
50 cm
50 cm
196 cm
51 cm
196 cm
50 cm
-171 cm

 

#define PWMA 3  // выходам arduino присваиваем имена
#define PWMB 9
#define AIN1 2
#define AIN2 1
#define BIN1 11
#define BIN2 12
#define STBY 8 
#define TRIG 7
#define ECHO 6
long duration, distance;
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // замедленно

void setup() {
    Serial.begin (9600);
    pinMode(PWMA, OUTPUT);  //назначаем статус пинам
    pinMode(PWMB, OUTPUT);  
    pinMode(AIN1, OUTPUT);  
    pinMode(AIN2, OUTPUT);  
    pinMode(BIN1, OUTPUT);  
    pinMode(BIN2, OUTPUT);  
    pinMode(STBY, OUTPUT);
    pinMode(TRIG, OUTPUT);         // set trig pin as output
    pinMode(ECHO, INPUT);          //echo pin в режим ввода данных
    digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}

void loop() {
     int duration, distance;
     digitalWrite(TRIG, LOW);
     delayMicroseconds(2);   
     digitalWrite(TRIG, HIGH);     // передаем серию импульсов длительностью 10 мкс
     delayMicroseconds(10);
     digitalWrite(TRIG, LOW);
     duration = pulseIn(ECHO, HIGH); // принимаем отраженные импульсы
     distance = duration / 58.2;   // рассчитываем расстояние в см
     Serial.print(distance); 
     Serial.println(" cm"); 
     delay(10);
     if (distance > 10)
 {
     digitalWrite(AIN1, LOW);      // едем вперед
     digitalWrite(AIN2, HIGH);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, HIGH); 
     analogWrite(PWMA, motorSpeed);
     analogWrite(PWMB, motorSpeed);  
     }
  if (distance < 10)
  {
     digitalWrite(AIN1, LOW);      // стоим
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeed);
     analogWrite(PWMB, motorSpeed);  
     delay(500);
     digitalWrite(AIN1, HIGH);      // едем назад
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, HIGH);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeedSlow);
     analogWrite(PWMB, motorSpeedSlow);  
     delay(500);
     digitalWrite(AIN1, LOW);      // стоим
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, LOW); 
     delay(100);
     digitalWrite(AIN1, LOW);      // поворот
     digitalWrite(AIN2, HIGH);    
     digitalWrite(BIN1, HIGH);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeedSlow);
     analogWrite(PWMB, motorSpeedSlow); 
     delay(2000);

  }

} 

 

rkit
Offline
Зарегистрирован: 23.11.2016

elranon пишет:

     int duration, distance;
     digitalWrite(TRIG, LOW);
     delayMicroseconds(2);   
     digitalWrite(TRIG, HIGH);     // передаем серию импульсов длительностью 10 мкс
     delayMicroseconds(10);
     digitalWrite(TRIG, LOW);
     duration = pulseIn(ECHO, HIGH); // принимаем отраженные импульсы
     distance = duration / 58.2;   // рассчитываем расстояние в см

А че это такое? Откуда, нафиг, вылезла серия импульсов? Почему тип int?

elranon
Offline
Зарегистрирован: 28.05.2012

только учусь.... естественно я смотрел примеры похожих кодов и из них составлял свой...(

что не так с серией импульсов, как можно сделать иначе, подскажете?

по поводу int - http://wiki.amperka.ru/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:hc-sr04-ultrasonic-sensor-distance-module вот отсюда я брал примеры

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

elranon пишет:

     int duration, distance;
     digitalWrite(TRIG, LOW);
     delayMicroseconds(2);   
     digitalWrite(TRIG, HIGH);     // передаем серию импульсов длительностью 10 мкс
     delayMicroseconds(10);
     digitalWrite(TRIG, LOW);
     duration = pulseIn(ECHO, HIGH); // принимаем отраженные импульсы
     distance = duration / 58.2;   // рассчитываем расстояние в см

А че это такое? Откуда, нафиг, вылезла серия импульсов? Почему тип int?

из интернета вестимо:
 

float readDistanceCM() {
  digitalWrite(Trig01_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig01_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig01_pin, LOW);
  int duration = pulseIn(Echo01_pin, HIGH);
  return duration * 0.034 / 2;
}

 

elranon
Offline
Зарегистрирован: 28.05.2012

сделал так, ругается на синтаксис

 

#define PWMA 3  // выходам arduino присваиваем имена
#define PWMB 9
#define AIN1 2
#define AIN2 1
#define BIN1 11
#define BIN2 12
#define STBY 8 
#define TRIG 7
#define ECHO 6
long duration, distance;
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // замедленно

void setup() {
    Serial.begin (9600);
    pinMode(PWMA, OUTPUT);  //назначаем статус пинам
    pinMode(PWMB, OUTPUT);  
    pinMode(AIN1, OUTPUT);  
    pinMode(AIN2, OUTPUT);  
    pinMode(BIN1, OUTPUT);  
    pinMode(BIN2, OUTPUT);  
    pinMode(STBY, OUTPUT);
    pinMode(TRIG, OUTPUT);         // set trig pin as output
    pinMode(ECHO, INPUT);          //echo pin в режим ввода данных
    digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}

void loop() {

  float DistanceCM() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  int duration = pulseIn(ECHO, HIGH);
  return duration * 0.034 / 2;
}

     delay(10);
     if (DistanceCM > 10)
 {
     digitalWrite(AIN1, LOW);      // едем вперед
     digitalWrite(AIN2, HIGH);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, HIGH); 
     analogWrite(PWMA, motorSpeed);
     analogWrite(PWMB, motorSpeed);  
     }
  if (DistanceCM < 10)
  {
     digitalWrite(AIN1, LOW);      // стоим
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeed);
     analogWrite(PWMB, motorSpeed);  
     delay(1000);
     digitalWrite(AIN1, HIGH);      // едем назад
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, HIGH);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeedSlow);
     analogWrite(PWMB, motorSpeedSlow);  
     delay(500);
     digitalWrite(AIN1, LOW);      // стоим
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, LOW); 
     delay(500);
     digitalWrite(AIN1, LOW);      // поворот
     digitalWrite(AIN2, HIGH);    
     digitalWrite(BIN1, HIGH);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeedSlow);
     analogWrite(PWMB, motorSpeedSlow); 
     delay(2000);

  }

} 

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

значить, ты используешь неправильный синтаксис.  Используй правильный

elranon
Offline
Зарегистрирован: 28.05.2012

сделал правильный, теперь вообще нет реакции... только странный писк от конструкции

что я делаю не так?

#define PWMA 3  // выходам arduino присваиваем имена
#define PWMB 9
#define AIN1 2
#define AIN2 1
#define BIN1 11
#define BIN2 12
#define STBY 8 
#define TRIG 7
#define ECHO 6
long duration, distance;
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // замедленно



void setup() {
    Serial.begin (9600);
    pinMode(PWMA, OUTPUT);  //назначаем статус пинам
    pinMode(PWMB, OUTPUT);  
    pinMode(AIN1, OUTPUT);  
    pinMode(AIN2, OUTPUT);  
    pinMode(BIN1, OUTPUT);  
    pinMode(BIN2, OUTPUT);  
    pinMode(STBY, OUTPUT);
    pinMode(TRIG, OUTPUT);         // set trig pin as output
    pinMode(ECHO, INPUT);          //echo pin в режим ввода данных
    digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}

void loop() {

     float DistanceCM(); 
     digitalWrite(TRIG, LOW);
     delayMicroseconds(2);
     digitalWrite(TRIG, HIGH);
     delayMicroseconds(10);
     digitalWrite(TRIG, LOW);
     int duration = pulseIn(ECHO, HIGH);
     return duration * 0.034 / 2;

     
     if (DistanceCM > 10)
 {
     digitalWrite(AIN1, LOW);      // едем вперед
     digitalWrite(AIN2, HIGH);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, HIGH); 
     analogWrite(PWMA, motorSpeed);
     analogWrite(PWMB, motorSpeed);  
     }
  if (DistanceCM < 10)
  {
     digitalWrite(AIN1, LOW);      // стоим
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeed);
     analogWrite(PWMB, motorSpeed);  
     delay(1000);
     digitalWrite(AIN1, HIGH);      // едем назад
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, HIGH);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeedSlow);
     analogWrite(PWMB, motorSpeedSlow);  
     delay(500);
     digitalWrite(AIN1, LOW);      // стоим
     digitalWrite(AIN2, LOW);    
     digitalWrite(BIN1, LOW);  
     digitalWrite(BIN2, LOW); 
     delay(500);
     digitalWrite(AIN1, LOW);      // поворот
     digitalWrite(AIN2, HIGH);    
     digitalWrite(BIN1, HIGH);  
     digitalWrite(BIN2, LOW); 
     analogWrite(PWMA, motorSpeedSlow);
     analogWrite(PWMB, motorSpeedSlow); 
     delay(2000);

  }

} 

 

rkit
Offline
Зарегистрирован: 23.11.2016

ua6em пишет:

из интернета вестимо:
 

float readDistanceCM() {
  digitalWrite(Trig01_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig01_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig01_pin, LOW);
  int duration = pulseIn(Echo01_pin, HIGH);
  return duration * 0.034 / 2;
}

Полный бред в вашем интернете пишут. Ровно те же вопросы.

 

elranon
Offline
Зарегистрирован: 28.05.2012

если бред, подскажите пожалуйста в чем ошибка и как было бы сделать правильно?

rkit
Offline
Зарегистрирован: 23.11.2016

Если тебя сочетание int и отрицательных значений ни на что не натолкнуло, то нужно пойти прочитать учебник, а  не пытаться наскоком сделать вещи, которым годами нужно учиться.

elranon
Offline
Зарегистрирован: 28.05.2012

спасибо что не помогли. думал что форум это то место куда новичок может прийти и получить ответ. а видимо, сюда надо приходить уже будучи покованным учебниками...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

elranon пишет:

думал что форум это то место куда новичок может прийти и получить ответ.

Правила сетевой этики рекомендуют почитать форум прежде, чем на него писать.

Если бы Вы не пренебрегали этими правилами, у Вас не было бы заблуждений о предназначении форума.

rkit
Offline
Зарегистрирован: 23.11.2016

Ответ ты получил. Что ты хотел - это чтобы кто-то бросил все свои занятия, и вместо этого сделал то, что нужно тебе. Бесплатно. И ты этого не получишь, хоть с учебниками, хоть с диссертацией.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

тут rkit намекает:
 

// Получаем значение от датчика расстояния и сохраняем его в переменную
  unsigned int distance = sonar.ping_cm();

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

так попробуй:

PS с библиотекой NewPing.h работа значительно стабильней
 

#define PWMA 3  // выходам arduino присваиваем имена
#define PWMB 9
#define AIN1 2
#define AIN2 4  //был 1, а это UART однако
#define BIN1 11
#define BIN2 12
#define STBY 8
#define TRIG 7
#define ECHO 6
unsigned long distance;
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // замедленно


float DistanceCM() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  uint16_t duration = pulseIn(ECHO, HIGH);
  return duration * 0.034 / 2;
}

void setup() {
  Serial.begin (9600);
  pinMode(PWMA, OUTPUT);  //назначаем статус пинам
  pinMode(PWMB, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(STBY, OUTPUT);
  pinMode(TRIG, OUTPUT);         // set trig pin as output
  pinMode(ECHO, INPUT);          //echo pin в режим ввода данных
  digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}

void loop() {
  distance = DistanceCM();

  if (distance > 10)
  {
    digitalWrite(AIN1, LOW);      // едем вперед
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
  }
  if (distance < 10)
  {
    digitalWrite(AIN1, LOW);      // стоим
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
    delay(1000);
    digitalWrite(AIN1, HIGH);      // едем назад
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    delay(500);
    digitalWrite(AIN1, LOW);      // стоим
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
    delay(500);
    digitalWrite(AIN1, LOW);      // поворот
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    delay(2000);
  }
}

 

elranon
Offline
Зарегистрирован: 28.05.2012

спасибо

пробую использовать эту библиотеку. вот такой код пишу, но он все равно работает не адекватно, хотя расстояния я показывает вроде корректно

может быть что то не так в условиях ? 

#include <NewPing.h>
#define TRIG 10
#define ECHO 11
#define MAX_DISTANCE 200
#define PWMA 5  // выходам arduino присваиваем имена
#define PWMB 6
#define AIN1 3
#define AIN2 2
#define BIN1 8
#define BIN2 9
#define STBY 7 
NewPing sonar(TRIG, ECHO, MAX_DISTANCE);
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // замедленно

void setup() {
  Serial.begin(9600);
  pinMode(PWMA, OUTPUT);  //назначаем статус пинам
  pinMode(PWMB, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(STBY, OUTPUT);
  digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}
 
void loop() {
  delay(50);
  Serial.print("Ping: ");
  Serial.print(sonar.ping_cm());
  Serial.println("cm");
  if (sonar.ping_cm() > 10)
  {
    digitalWrite(AIN1, LOW);      // едем вперед
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
  }
    if (sonar.ping_cm() < 10)
  {
    digitalWrite(AIN1, LOW);      // стоим
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
    delay(2000);
    digitalWrite(AIN1, HIGH);      // едем назад
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    delay(2000);
    digitalWrite(AIN1, LOW);      // стоим
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
    delay(2000);
    digitalWrite(AIN1, LOW);      // поворот
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    delay(3000);
  }
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

там до условий еще далеко, во первых сонар должен опрашиваться периодически, минимальное время опроса 29 миллисекунд, обычно принимают 50, далее сравнивать надо сравнимые величины, то есть присвоить значение полученное от сонара некоторой переменной и далее с ней работать, для отладки программы использовать вывод значения  сонара в компорт...с сонара периодически лезут артефакты (сильно отличающие значения) значит надо вводить функцию усреднения, коэффициент усреднения рассчитывается из скорости тележки с учётом ограничений числа измерений сонара в секунду в 20 (30) замеров. Значит нужен еще независимый таймер, который будет вызывать эти измерения...функцию усреднения и  таймер можно найти здесь на сайте

PS где-то у меня есть код для тележки робота автомата обходящего препятствия, сонар был установлен на платформе поворачивающейся сервой, при подходе к препятствию тележка останавливалась, сонар поворачивался сервой  в разные стороны и определял в какую сторону поворачиваться, и далее тележка поворачивалась в этом направлении и продолжала движение

вот код с применением библиотеки и математическим усреднением значения дистанции:
 

#include <NewPing.h>

#define DEBUG

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

volatile uint32_t old_m;
uint32_t distance;

// фильтр среднее с буфером
uint32_t RunMiddleArifm(uint32_t newVal) {
#define NUM_Array 8  // порядок фильтра
  static uint32_t ret, buff, buffer[NUM_Array];
  static uint8_t i;
  if (++i >= NUM_Array) {
    i = 0;
  }
  buff += newVal;
  buff -= buffer[i];
  buffer[i] = newVal;
  ret = buff / NUM_Array;
  return ret;
}

void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
  old_m = millis();
}

void loop() {
  if (millis() - old_m >= 33) {
     // uint32_t uS = sonar.ping(); // Send ping, get ping time in microseconds (uS)
    // distance = RunMiddleArifm(uS / US_ROUNDTRIP_CM);
    uint32_t uS = sonar.ping_median(); // Send ping, get ping time in microseconds (uS)
    distance = uS / US_ROUNDTRIP_CM;
    
    #ifdef DEBUG
    Serial.print("Ping: ");
    Serial.print(distance); 
    Serial.println("cm");
    #endif
    
    old_m = millis();
  }
}

 

lilik
Offline
Зарегистрирован: 19.10.2017

:)

А уз датчик отдельно проверить не пробовали?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

lilik пишет:

:)

А уз датчик отдельно проверить не пробовали?

не с чем, есть другой, влагозащищённый, он с этой библиотекой не работает почему-то

lilik
Offline
Зарегистрирован: 19.10.2017

Это ТСу надоб сделать.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

lilik пишет:

Это ТСу надоб сделать.

я поправил скетч, добавил медианное средствами библиотеки, иногда проскакивают артефакты
 

Ping: 15cm
Ping: 14cm
Ping: 14cm
Ping: 15cm
Ping: 18cm
Ping: 30cm
Ping: 14cm
Ping: 15cm
Ping: 17cm
Ping: 14cm
Ping: 14cm
Ping: 14cm
Ping: 14cm
Ping: 14cm

 

lilik
Offline
Зарегистрирован: 19.10.2017

А у него каковы результаты? УЗ датчик нормально работает?

elranon
Offline
Зарегистрирован: 28.05.2012

Спасибо за проявленный интерес к моему вопросу...

давайте чуть подробнее обьясню) вот такая схема: https://ibb.co/TtNwR1Z

моторов 4, соединены между собой. 

загружаю данный код который подсказали, в результате работает не корректно - проезжает чуть чуть и сразу поворачивает, хотя препятствий нету никаких рядом и так постоянно. монитор порта вот что выдает, и обновление не частое а будто с какой то задержкой

1 cm
27 cm
1 cm
25 cm
3 cm
25 cm
3 cm
25 cm
2 cm
 
#define PWMA 5  // выходам arduino присваиваем имена
#define PWMB 6
#define AIN1 3
#define AIN2 2  //был 1, а это UART однако
#define BIN1 8
#define BIN2 9
#define STBY 7
#define TRIG 10
#define ECHO 11
unsigned long distance;
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // замедленно
float DistanceCM() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  uint16_t duration = pulseIn(ECHO, HIGH);
  return duration * 0.034 / 2;
}

void setup() {

  Serial.begin (9600);
  pinMode(PWMA, OUTPUT);  //назначаем статус пинам
  pinMode(PWMB, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(STBY, OUTPUT);
  pinMode(TRIG, OUTPUT);         // set trig pin as output
  pinMode(ECHO, INPUT);          //echo pin в режим ввода данных
  digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}
void loop() {
  distance = DistanceCM();
  Serial.print(distance);
  Serial.println(" cm");
  if (distance > 10)
  {
    digitalWrite(AIN1, LOW);      // едем вперед
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
  }
  if (distance < 10)
  {
    digitalWrite(AIN1, LOW);      // стоим
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
    delay(1000);
    digitalWrite(AIN1, HIGH);      // едем назад
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    delay(500);
    digitalWrite(AIN1, LOW);      // стоим
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
    delay(500);
    digitalWrite(AIN1, LOW);      // поворот
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    delay(2000);
  }
}

 

elranon
Offline
Зарегистрирован: 28.05.2012

вот с этиим кодом монитор порта показывает корректно

Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
Ping: 24cm
 
#include <NewPing.h>
#define PWMA 5  // выходам arduino присваиваем имена
#define PWMB 6
#define AIN1 3
#define AIN2 2  //был 1, а это UART однако
#define BIN1 8
#define BIN2 9
#define STBY 7
#define DEBUG
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // 
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
volatile uint32_t old_m;
uint32_t distance;
 

// фильтр среднее с буфером
uint32_t RunMiddleArifm(uint32_t newVal) {
#define NUM_Array 8  // порядок фильтра
  static uint32_t ret, buff, buffer[NUM_Array];
  static uint8_t i;
  if (++i >= NUM_Array) {
    i = 0;
  }
  buff += newVal;
  buff -= buffer[i];
  buffer[i] = newVal;
  ret = buff / NUM_Array;
  return ret;
}
 
void setup() {
  Serial.begin(9600); // 
  old_m = millis();
  pinMode(PWMA, OUTPUT);  //назначаем статус пинам
  pinMode(PWMB, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(STBY, OUTPUT);
  digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}
 
void loop() {
  if (millis() - old_m >= 33) {
     // uint32_t uS = sonar.ping(); // Send ping, get ping time in microseconds (uS)
    // distance = RunMiddleArifm(uS / US_ROUNDTRIP_CM);
    uint32_t uS = sonar.ping_median(); // Send ping, get ping time in microseconds (uS)
    distance = uS / US_ROUNDTRIP_CM;
     
    #ifdef DEBUG
    Serial.print("Ping: ");
    Serial.print(distance);
    Serial.println("cm");
    #endif
     
    old_m = millis();
  }
  }

осталось понять, как добавить сюда условие чтобы он поворачивал, по такой аналогии?

if (distance > 10)
  {
    digitalWrite(AIN1, LOW);      // едем вперед
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
  }

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

между строками 62 и 63 вставляйте ваш код, раз в 33 миллисекунды в этом месте будете иметь новое значение дистанции, естественно никаких delay() в вашем коде быть не должно, точнее может быть, но очень маленьким, на сквозники при переключении по 1 миллисекунде хватит

elranon
Offline
Зарегистрирован: 28.05.2012

вот смотрите... какое странное поведение.

заливаю код:

#include <NewPing.h>
#define PWMA 5  // выходам arduino присваиваем имена
#define PWMB 6
#define AIN1 3
#define AIN2 2  //был 1, а это UART однако
#define BIN1 8
#define BIN2 9
#define STBY 7
#define DEBUG
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // 
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
volatile uint32_t old_m;
uint32_t distance;
 

// фильтр среднее с буфером
uint32_t RunMiddleArifm(uint32_t newVal) {
#define NUM_Array 8  // порядок фильтра
  static uint32_t ret, buff, buffer[NUM_Array];
  static uint8_t i;
  if (++i >= NUM_Array) {
    i = 0;
  }
  buff += newVal;
  buff -= buffer[i];
  buffer[i] = newVal;
  ret = buff / NUM_Array;
  return ret;
}
 
void setup() {
  Serial.begin(9600); // 
  old_m = millis();
  pinMode(PWMA, OUTPUT);  //назначаем статус пинам
  pinMode(PWMB, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(STBY, OUTPUT);
  digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}
 
void loop() {
  if (millis() - old_m >= 33) {
     // uint32_t uS = sonar.ping(); // Send ping, get ping time in microseconds (uS)
    // distance = RunMiddleArifm(uS / US_ROUNDTRIP_CM);
    uint32_t uS = sonar.ping_median(); // Send ping, get ping time in microseconds (uS)
    distance = uS / US_ROUNDTRIP_CM;
     
    #ifdef DEBUG
    Serial.print("Ping: ");
    Serial.print(distance);
    Serial.println("cm");
    #endif
     
    old_m = millis();
  }
 
  }

и все вроде бы ок:

22:28:11.385 -> Ping: 18cm
22:28:11.525 -> Ping: 18cm
22:28:11.666 -> Ping: 18cm
22:28:11.807 -> Ping: 18cm
22:28:11.945 -> Ping: 18cm
22:28:12.131 -> Ping: 18cm
22:28:12.271 -> Ping: 18cm
22:28:12.412 -> Ping: 18cm
22:28:12.553 -> Ping: 18cm
22:28:12.693 -> Ping: 18cm

НО когда заливаю полный код:


#include <NewPing.h>
#define PWMA 5  // выходам arduino присваиваем имена
#define PWMB 6
#define AIN1 3
#define AIN2 2  //был 1, а это UART однако
#define BIN1 8
#define BIN2 9
#define STBY 7
#define DEBUG
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
int motorSpeed = 100; //  обычная скорость
int motorSpeedSlow = 50;  // 
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
volatile uint32_t old_m;
uint32_t distance;
 

// фильтр среднее с буфером
uint32_t RunMiddleArifm(uint32_t newVal) {
#define NUM_Array 8  // порядок фильтра
  static uint32_t ret, buff, buffer[NUM_Array];
  static uint8_t i;
  if (++i >= NUM_Array) {
    i = 0;
  }
  buff += newVal;
  buff -= buffer[i];
  buffer[i] = newVal;
  ret = buff / NUM_Array;
  return ret;
}
 
void setup() {
  Serial.begin(9600); // 
  old_m = millis();
  pinMode(PWMA, OUTPUT);  //назначаем статус пинам
  pinMode(PWMB, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(STBY, OUTPUT);
  digitalWrite(STBY, HIGH);   //подаем напряжение на схему управления
}
 
void loop() {
  if (millis() - old_m >= 33) {
     // uint32_t uS = sonar.ping(); // Send ping, get ping time in microseconds (uS)
    // distance = RunMiddleArifm(uS / US_ROUNDTRIP_CM);
    uint32_t uS = sonar.ping_median(); // Send ping, get ping time in microseconds (uS)
    distance = uS / US_ROUNDTRIP_CM;
     
    #ifdef DEBUG
    Serial.print("Ping: ");
    Serial.print(distance);
    Serial.println("cm");
    #endif
     
    old_m = millis();
  }
  if (distance > 10)
  {
    digitalWrite(AIN1, LOW);      // едем вперед
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);
    analogWrite(PWMA, motorSpeed);
    analogWrite(PWMB, motorSpeed);
  }
  if (distance < 10)
   {
    digitalWrite(AIN1, LOW);      // стоим
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, LOW);
    delay(2000);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    digitalWrite(AIN1, HIGH);      // едем назад
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    delay(2000);
    analogWrite(PWMA, motorSpeedSlow);
    analogWrite(PWMB, motorSpeedSlow);
    digitalWrite(AIN1, LOW);      // поворот
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    delay(3000);
   }
 
  }



 

поведение меняется, проскакивает нулевое расстояние и соотв работает не так как задумано. что это может быть?

22:30:20.147 -> Ping: 34cm
22:30:20.240 -> Ping: 34cm
22:30:20.287 -> Ping: 34cm
22:30:20.334 -> Ping: 34cm
22:30:20.380 -> Ping: 0cm
22:30:29.461 -> Ping: 35cm
22:30:29.508 -> Ping: 35cm
22:30:29.555 -> Ping: 34cm
22:30:29.602 -> Ping: 35cm
22:30:29.696 -> Ping: 34cm
22:30:29.743 -> Ping: 34cm
22:30:29.790 -> Ping: 34cm
22:30:29.837 -> Ping: 0cm

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

пост 24

а лучше смотрим код тут и разбираем до полного просветления

elranon
Offline
Зарегистрирован: 28.05.2012

простите, вчера уже уставший был, и не тот код вставил в пост, свой старый... сейчас я пост отредактировал и сделал правильно.

но в новом коде присутствует Delay в условиях.... вечером уберу и посмотрю на поведение. Отпишу о результате