Машинка, ориентация в пространстве.

k4eha
Offline
Зарегистрирован: 27.03.2021

Здравствуйте, первый код для ардуино. Вообще работает, едет до препятствия, ищет куда повернуть, отрабатывает поворот 2 сек. и проверяет можно ли ехать. Есть непонятное условие при котором выпрыгивает из моей функции и попадает в лупу (void loop). Какую то фундаментальную штуку не понимаю или специфичную для ардуино.  Ещё, недоезд и не начинает оглядываться. Ардуина, отработав функцию, всегда возвращается в тот код где был вызов этой функции? Вернувшись начинает со строчки к-я под вызовом функции?

#include <SoftwareSerial.h>
SoftwareSerial mySerial(0, 1); // RX, TX
//*  digital pin 4 (соединить с TX на модуле блютуз)
//*  digital pin 5 (соединить с RX на модуле блютуз)

#include   <Stepper.h>

// 1_pin-6_ЗЕЛЁНЫЙ, 2_pin-4_ЖОЛТЫЙ, 3_pin-7_ОРАНЖЕВЫЙ, 4_pin-8_СИРЕНЕВЫЙ


uint32_t myTimer1;
uint32_t myTimer2;

Stepper myStepper(2038, 8, 4, 7, 6);

// ____________ ЛАЗЕРНИК ______________
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
//#define LONG_RANGE
//#define HIGH_SPEED
//#define HIGH_ACCURACY           
// _____________ ЛАЗЕРНИК ____________


// Создаем объект, методами которого будем затем пользоваться для получения расстояния.
// В качестве параметров передаем номера пинов, к которым подключены выходы ECHO и TRIG датчика


/*ЛЕВЫЙ      НАЗАД */ int EN1 = 9;   /*ВПЕРЁД*/ int EN2 = 10;   /*_____       ПРАВЫЙ     ВПЕРЁД*/ int EN3 = 5; /*НАЗАД*/ int EN4 = 3; // драйвер мотора подключен!




byte          FrontLight = A2; //ФАРА
int           Speed =      300;  //начальная скорость моторов, сразу после запуска программы на смартфоне
int           kolSteps;
int           button_pin = 11; //КНОПКА ПУСК
int           command =    0;
long unsigned Dist;
long unsigned leftDist;
long unsigned rightDist;
long unsigned lidDist = 600;
boolean       lightFront=  false; //переменные для хранения состояния световых приборов и звукового сигнала





void setup() {
  mySerial.begin(9600); Serial.begin(2400);//запускаем виртуальный серийный порт для связи с блютуз модулем
  Serial.begin(2400); //запускаем серийный порт для связи с пк для отладки программы
   //настраиваем порты на ввод и вывод----------------

// _________________ НАСТРОЙКА ЛАЗЕРНИКА НАЧАЛО __ лазерный лидар _________________________________-
Wire.begin();
sensor.setTimeout(50);
  if (!sensor.init())
  {
    Serial.println("Failed to detect and initialize sensor!");
    while (1) {}
  }
#if defined LONG_RANGE
  // lower the return signal rate limit (default is 0.25 MCPS)
  sensor.setSignalRateLimit(0.1);
  // increase laser pulse periods (defaults are 14 and 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 10);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif
#if defined HIGH_SPEED
  // reduce timing budget to 20 ms (default is about 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
#endif
// ____________ НАСТРОЙКА ЛАЗЕРНИКА ОКОНЧАНИЕ _______________

  //далее объявлены пины для связи ардуино и драйвера двигателя
  myStepper.setSpeed(13);
  pinMode (EN1,        OUTPUT); pinMode (EN2, OUTPUT); pinMode (EN3, OUTPUT); pinMode (EN4, OUTPUT);
  pinMode (button_pin, INPUT ); // Инициализируем цифровой вход КНОПКИ ПУСК.

  pinMode (FrontLight, OUTPUT);

}





void loop()
{
  

  delay (100);
 
  if (digitalRead(button_pin) == HIGH)
  {
    delay (500);
    mashina(0);
    delay (500);
  }
  
  Serial.println("_ВКЛЮЧИТЕ_!");

} 

void RMGO (int Speed) { //правый мотор вперед
    delay       (10);
    analogWrite (EN3, 250);
    delay       (100);
    analogWrite (EN3, Speed);
    analogWrite (EN4, 0);
   
  }


void LMGO (int Speed) { //левый мотор вперед
    delay       (10);
    analogWrite (EN2, 250);
    delay       (100);
    analogWrite (EN1, 0);
    analogWrite (EN2, Speed);
    
  }

void LMBACK (int Speed) { //левый мотор назад
    delay       (10);
    analogWrite (EN1, 250);
    delay       (100);
    analogWrite (EN1, Speed);
    analogWrite (EN2, 0);
    
  }

void RMBACK (int Speed) { //правый мотор назад
    delay       (10);
    analogWrite (EN4, 250);
    delay       (100);
    analogWrite (EN3, 0);
    analogWrite (EN4, Speed);
    
  }

void Stop () {  //оба мотора стоп
    delay       (20);
    analogWrite (EN1, 0); analogWrite (EN2, 0);
    analogWrite (EN3, 0); analogWrite (EN4, 0);
    
  }

void mashina(int command)
{


Serial.println("УПРАВЛЯЕМЫЙ_");

if (mySerial.available() > 0) {  //если в буфере программного серийного порта есть данные
  command = mySerial.read();     //считываем их и запоминаем комманду
  analogWrite (EN1, 0); analogWrite (EN2, 0);
  analogWrite (EN3, 0); analogWrite (EN4, 0);                        //останавливаем двигатели
  Serial.println(command);       //выводим команду в монитор порта (используется для отладки)


  

Serial.print("_ОЖИДАНИЕ_");
  
  switch (command)
  { //выполняем действия в зависимости от полученной по блютуз команде
    case 70: {  
          LMGO(Speed);  //Едем вперед
          RMGO(Speed);
          break;
      }
    case 66: {
        LMBACK(Speed);  //Едем назад
        RMBACK(Speed);
        break;
      }
    case 82: {
        LMGO(Speed);  //танковый разворот направо
        RMBACK(Speed);
        break;
      }
    case 76: {
        RMGO(Speed);  //танковый разворот налево
        LMBACK(Speed);
        break;
      }
    case 73: LMGO(Speed); RMGO(Speed / 3); break;
     
    case 71: RMGO(Speed); LMGO(Speed / 3); break;
      
    case 74: LMBACK(Speed); RMBACK(Speed / 3); break;
     
    case 72: RMBACK(Speed); LMBACK(Speed / 3); break;
     
    case 48: Speed = 120; break; //задаем скорость
    case 49: Speed = 125; break; //задаем скорость
    case 50: Speed = 135; break; //задаем скорость
    case 51: Speed = 145; break; //задаем скорость
    case 52: Speed = 160; break; //задаем скорость
    case 53: Speed = 175; break; //задаем скорость
    case 54: Speed = 190; break; //задаем скорость
    case 55: Speed = 205; break; //задаем скорость
    case 56: Speed = 220; break; //задаем скорость
    case 57: Speed = 235; break; //задаем скорость
    case 113: Speed = 255; break; //задаем скорость
    case 87: lightFront = true; break;   //меняем состояние переменной управления передними фарами (включение)
    case 119: lightFront = false; break; //меняем состояние переменной управления передними фарами (отключение)
  }  
  if (command == 85) 
     {
      automatik();
     Serial.println("_НА_АВТОМАТ_");
     }
  }

  // управляем светодиодами и пьезопищалкой
if (lightFront)  {
    digitalWrite(FrontLight, HIGH); //включаем передние фары
  }
if (!lightFront) {
    digitalWrite(FrontLight, LOW); //либо отключаем их.
  }
  




if (digitalRead(button_pin) == HIGH)
  {
    delay (500);
    Serial.println("_СТОП_ПРОГРАММА_");
    return
    delay (500);
  }

mashina(0);

}



void automatik()
{
command = 0;

  if (mySerial.available() > 0)
  { 
    //если в буфере программного серийного порта есть данные
    command = mySerial.read();
  if (command == 85) 
  {
    mashina(0);
    Serial.println("_НА_УПРАВЛЕНИЕ_");
  }
 }     //считываем их и запоминаем комманду
  
   
 

  
  if (digitalRead(button_pin) == HIGH)
  {
    delay (500);
    Serial.println("_СТОП_ПРОГРАММА_");
    return
   delay (500);
  }

  if (millis() - myTimer1 >= 80) {   // ищем разницу (80 мс)
    myTimer1 = millis();

// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________
if (sensor.readRangeSingleMillimeters() < 2000)
   {
   lidDist = sensor.readRangeSingleMillimeters();
      if (sensor.timeoutOccurred())
         { 
          Serial.print(" TIMEOUT"); 
          }
                     
           }
           else 
           {lidDist = 2000;}
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________ 
  }         
if  (lidDist <= 0)    { automatik(); }
 else
 {if  (lidDist <= 350)  { obzor();     }
    else
   {if  (lidDist >= 1000)  { Speed = 255; }
      else
      {if  (lidDist >= 800)  { Speed = 210; } 
         else  
           {if  (lidDist >= 600)  { Speed = 180; }  
              else  
                {if  (lidDist >= 500) { Speed = 170; }  
                   else  
                     {if  (lidDist >= 300) { Speed = 160; }
          
         }}}}}}

  
  analogWrite (EN3, Speed); analogWrite (EN1, 0);
  analogWrite (EN4, 0);     analogWrite (EN2, Speed);

automatik();

}

void obzor()

{
  Serial.println("РАССТОЯНИЕ_МЕНЬШЕ_200"); 
  command = 0;

  if (mySerial.available() > 0)
  { //если в буфере программного серийного порта есть данные
    command = mySerial.read();
      //считываем их и запоминаем комманду

  Serial.println(command);       //выводим команду в монитор порта (используется для отладки)
  if (command == 85) {
    mashina(0);
  }
  }
  if (digitalRead(button_pin) == HIGH)
  {
    delay (500);
    return
    delay (500);
  }


  delay (20);
  analogWrite (EN1, 0); analogWrite (EN2, 0);
  analogWrite (EN3, 0); analogWrite (EN4, 0);
  Serial.println("_СТОП");
delay       (100);
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________

if (sensor.readRangeSingleMillimeters() < 4000)
   {
    lidDist = sensor.readRangeSingleMillimeters();
      if (sensor.timeoutOccurred())
         { 
          Serial.print(" TIMEOUT"); 
          }
           }
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________
delay       (100);
  if (lidDist <= 200)
  {
    delay (1000);
    Dist = lidDist;
    myStepper.step(400);
    Serial.println("_ИЗМЕРЕНИЕ ЛАЗЕРОМ_");
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________

if (sensor.readRangeSingleMillimeters() < 4000)
   {
    lidDist = sensor.readRangeSingleMillimeters();
      if (sensor.timeoutOccurred())
         { 
          Serial.print(" TIMEOUT"); 
          }
           }
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________
    leftDist = lidDist;
    delay (2000);
    myStepper.step(-800);
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________

if (sensor.readRangeSingleMillimeters() < 4000)
   {
    lidDist = sensor.readRangeSingleMillimeters();
      if (sensor.timeoutOccurred())
         { 
          Serial.print(" TIMEOUT"); 
          }
           }
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________
    delay (1000);
    rightDist = lidDist;
    myStepper.step(400);


    Serial.print(lidDist);
    Serial.println("ОГЛЯДКИ");



    if (leftDist >= rightDist) {

      Serial.print(leftDist);
      Serial.println("_ЛЕВО");
      Serial.print(rightDist);
      Serial.println("_ПРАВО");
      Serial.print(Dist);
      Serial.println("_ПРЯМО");




      delay       (2000);
      delay       (10);
      analogWrite (EN2, 250);   analogWrite (EN4, 250);
      delay       (100);
      analogWrite (EN1, 0);     analogWrite (EN3, 0);
      analogWrite (EN2, 200);   analogWrite (EN4, 200); //ВПРАВО
delay       (100);
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________

if (sensor.readRangeSingleMillimeters() < 4000)
   {
    lidDist = sensor.readRangeSingleMillimeters();
      if (sensor.timeoutOccurred())
         { 
          Serial.print(" TIMEOUT"); 
          }
           }
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________

      
 }

    delay (2000);

    
    analogWrite (EN3, 250); analogWrite (EN1, 250);
    delay       (100);
    analogWrite (EN3, 200); analogWrite (EN1, 200);
    analogWrite (EN4, 0);   analogWrite (EN2, 0); //ВЛЕВО
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________

if (sensor.readRangeSingleMillimeters() < 4000)
   {
    lidDist = sensor.readRangeSingleMillimeters();
      if (sensor.timeoutOccurred())
         { 
          Serial.print(" TIMEOUT"); 
          }
           }
// ________________ ИЗМЕРЕНИЕ ЛАЗЕРОМ _______________
    

delay       (100);
    if (Dist <= 200 && leftDist <= 200 && rightDist <= 200)
    {
      delay       (2000);
      analogWrite (EN1, 250);  analogWrite (EN4, 250);
      delay       (100);
      analogWrite (EN1, 200);  analogWrite (EN3, 0);
      analogWrite (EN2, 0);    analogWrite (EN4, 200);

      Serial.print(lidDist);
      Serial.println("СДАТЬ ЗАДОМ");
      obzor();
    }
   obzor();
  } 
else 
{automatik();}
}

 

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

k4eha пишет:

Ардуина, отработав функцию, всегда возвращается в тот код где был вызов этой функции? Вернувшись начинает со строчки к-я под вызовом функции?

Если выход  штатный, то да.

Гриша
Offline
Зарегистрирован: 27.04.2014

а что за прикол в строках 1 и 2, или я что-то не понимаю ?! Нууу я многое не понимаю, но это особенно. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Гриша пишет:

а что за прикол в строках 1 и 2, или я что-то не понимаю ?! Нууу я многое не понимаю, но это особенно. 

Он что посадил софт-сериал на те же пины, где живёт аппаратный, а в программе использует оба? Достойно!

А в строка №№3 и 4 вроде все пристойно задумывалось.

k4eha
Offline
Зарегистрирован: 27.03.2021

Посадил блютуз туда где написано RX TX. Обычных шим и цифровых пинов для оборудования и так не хватает. Только бы не на обычные пины! Мне что бы перезалить скетч, блютуз всё время отключать от RX TX приходиться.

b707
Offline
Зарегистрирован: 26.05.2017

К4ена - ты молодец, посадил два сериала на одни и те же пины...
Если подключил блютус к пинам 0 и 1 - убери Сериал из кода. Если же тебе нужен и блютус и сериал - придется вешать на 4 разных пина, иначе никак.
Не хватает пинов - выбери другой МК

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

k4eha пишет:

 Только бы не на обычные пины! Мне что бы перезалить скетч, блютуз всё время отключать от RX TX приходиться.

Т.е. то, что при заливке два устройства не могут сидеть на одних пинах, Вы понимаете. А при работе? Как-нибудь разберутся? И так сойдёт?

Вот скажите, пришел на пин 0 сигнал. Как Ваш код отличит от кого он - от Serial или от Блютуз? Вы правда этого не понимаете?

k4eha
Offline
Зарегистрирован: 27.03.2021

Ну значит физ.выключатель на блютуз_RX TX. Программно там ни как наверно,  вот и не нашёл. Ардуина не отличает оборудование один от другого на rx tx?  Софт_сериал это блютуз? А что можно вешать на сдвиговый регистр кроме диодиков? С поддержкой I2C только лазер.

Спасибо rkit, вынесу измерение в отдельную функцию и буду вызывать.

Гриша
Offline
Зарегистрирован: 27.04.2014

k4eha пишет:

Обычных шим и цифровых пинов для оборудования и так не хватает. Только бы не на обычные пины!

а что за плата?

с буковками А все тоже заняты? те, что АЦП! надеюсь для вас не секрет, что пины АЦП можно использовать как цифровые? я заметил в коде только А2 занят...

Гриша
Offline
Зарегистрирован: 27.04.2014

что за плата и что чем занято? лучше конечно схему, но и простой таблицы хватит, загрузите ее как вставку кода.  конкретно какая нога чем занимается.

k4eha
Offline
Зарегистрирован: 27.03.2021

UNO пины. В перспективе подключу туда HW-201 Дальномер на маленькую дистанцию два надо будет подключать.

Ещё датчик присутствия есть - тоже надо.

А пока программные заморочки.

  0. RX_     блютуз
  1. TX_     блютуз
  2. D_       пусто
  3. ШИМ_контроллер моторчика колеса.
  4. D_       контроллер шаговика
  5. ШИМ_контроллер моторчика колеса.
  6. ШИМ_контроллер шаговика (ОПА-НА перенесу на двушку!)
  7. D_       контроллер шаговика
  8. D_       контроллер шаговика
  9. ШИМ_контроллер моторчика колеса.
10. ШИМ_контроллер моторчика колеса.
11. ШИМ_физическая кнопка "пуск" 
12. D_       пусто
13. D_       пусто
14. GND_ занят в другом месте
15. Aref_  пусто лазер VL53L0X отказался на нём работать.
16. нет надписи кажись второй пин для лазера
17. тайна
____ВТОРАЯ СТОРОНА___

А0_     лазер
А1_     лазер
GND_ занято
+5в_   откусил
______________________
После замыкания оловом которое капнуло со "щита"
питаю через юзби постоянно своей шимкой.
ЮЗБИ подключаю на другое гнездо на котором только data_1 data_2
5в остались в старом гнезде. GND с компом не соединяется.
Там накрылось что то ещё кроме стаба или диода.
Переферия на отдельном шим 1А 5в. шаговик тоже на своём 300Ма 9в
и моторы колёс тоже 1,5А 9в GND общий только там где одинаково 5в.
Я пытался компаратор там какой то менять не помогло ну и фиг с ним и так работает.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Это следует отлить в граните:
15. Aref_ пусто лазер VL53L0X отказался на нём работать.
16. нет надписи кажись второй пин для лазера
17. тайна

k4eha
Offline
Зарегистрирован: 27.03.2021

Я перепутал пины сейчас а тогда сначала подключал лазер найдя эту схему без сиреневого и голубого. У меня датчик VL53LXX V2 Вот чтобы прямо точно для него библиотеку ни где не нашёл. Сайт изготовителя не на все страницы пускает. Должно было заработать с этим подключением? А то ещё раз попробую. Сейчас A0,  A1.  Хотел бы освободить А0 И А1. Про Aref уже гуглил почти дошло в ближайшей перспективе не трону.

Гриша
Offline
Зарегистрирован: 27.04.2014

sadman41 пишет:
Это следует отлить в граните: 15. Aref_ пусто лазер VL53L0X отказался на нём работать. 16. нет надписи кажись второй пин для лазера 17. тайна

еще по списку:
А2 в коде есть, а в списке потерялся...

пин 17.. ммм что за версия UNO такая, себе хочу

А3,А4,А5 походу обрезаны, не хочу себе такую....

 

k4eha
Offline
Зарегистрирован: 27.03.2021

А2....  сотру из кода наверно. Меня очень волнует почему из функции void obzor() не регулярно вылетает в loop() онаж не должна!

Гриша
Offline
Зарегистрирован: 27.04.2014

k4eha пишет:

А2....  сотру из кода наверно. Меня очень волнует почему из функции void obzor() не регулярно вылетает в loop() онаж не должна!

вывод какой-то странный... делать что-то нужно "осознанно", а не "наверное". 

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

k4eha
Offline
Зарегистрирован: 27.03.2021

Спс. Дебагер :-)) Посоветуйте, пожалуйста, дебагер для ардуинского кода э... попроще который.  У меня Дебиан.

Точно знаю, не прогуглю, слишком не компентентен.

Знаю только IDE и там только компилятор.  Я экструдер для принтера предзаказал и принтер он важнее. Значит на зажаренной ардуине сидеть.

Если вы углядели проблему с электроникой о которой я не догадываюсь - подскажите, уж :-)

 

Гриша
Offline
Зарегистрирован: 27.04.2014

k4eha пишет:

Знаю только IDE и там только компилятор. 

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

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

Дебаг - не программа или еще что-то, это процедура отладки когда тупишь и не понимаешь где накосячил.

k4eha пишет:

Если вы углядели проблему с электроникой о которой я не догадываюсь - подскажите, уж :-)

пост 10 написана фигня, где аналоговые порты? сколько их? что за №17 я такого не знаю, можно фото?!!

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

k4eha пишет:

Спс. Дебагер :-)) Посоветуйте, пожалуйста, дебагер для ардуинского кода

Онлайн-дебаггер 80'th lvl тут каждый третий)) Сам изредка пользуюсь. Главное на пятницу не попадать))

k4eha
Offline
Зарегистрирован: 27.03.2021

Я тупо подзабыл куда первый раз лазер подключал и по дразнилкам здесь это понял и сразу всё гугланул.

Желание туда что то подключать неизбежно привело бы в гугол. 

Я пустые порты не стал упоминать - все ардуинки уно одинаковые той же версии если и это отвечал на вопрос куда что воткнуто. Всё оборудование в портах получает сигналы исправно или передаёт, шим - порты тоже без нареканий. Дебагер  приблизит к пониманию - железо или ПО.

Ой-й-й А как испод  андроид монитор порта по блютузу??? Всё время на юзби вынужден подключать для отслеживания выполнения. Есть arduino bluetooth controller запускаю консоль - командовать можно а в монитор не выводит. (юзби отключено)

HC-05 блютуз на пинах 0, 1  

Чтобы меньше запутаться подебажу сначала ещё не переделанную программу (со всем мусором).

Гриша
Offline
Зарегистрирован: 27.04.2014

k4eha пишет:

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

вот что за манера... это вы знаете, что они у вас не используются, а мы можем только догадываться, кроме прочего звучало, что все ноги закончились (выше сами поищите)... вам помощ нужна?

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

k4eha
Offline
Зарегистрирован: 27.03.2021

Сделаю совсем как следует - создам тему, придётся, создать и выложу туда электрическую схему машинки, абсолютно всё. Эта машинка всё равно типа испытательный стенд и проблемы огребать всё время с нею. Специально всё строго на разъёмы делал, впаивал штыри в щит - макетку и т. д. Это в выходной. Телевизор не смотри :-) а то тебе моё умалчивание части информации покажется верхом логики и сообразительности :-) Поболтать можно но не здесь а то уже спам начался.

k4eha
Offline
Зарегистрирован: 27.03.2021

Опять проблема. Оператор "and" и он же "&&" не слушается. Обкатываю два датчика малой дистанции.

Левый и правый но они "видят" и вперёд.

int           irsensorRig = 2;  //ПРОВОД ПРАВОГО ДАТЧИКА
int           irsensorLef = 12; //И ЛЕВОГО
int           sensorvalueRig;
int           sensorvalueLef; 
boolean       PrepRig =     false;
boolean       PrepLef =     false;
boolean       PrepFront =   false;
void  prepHortDetection(); //ФУНКЦИЯ ОПРОСА ДАТЧИКОВ


void setup() {
Serial.begin(2400); //запускаем серийный порт для связи с пк для отладки программы
pinMode (irsensorRig, INPUT);
pinMode (irsensorLef, INPUT);
}

void loop() {
prepHortDetection(); //ОПРОС ДАТЧИКОВ
Serial.println((String)PrepRig + "_СПРАВО_" + (String)PrepLef + "_СЛЕВА_" + (String)PrepFront + "_ВПЕРЕДИ_");
//ПРИМЕННЕНИЕ - ВЫВОД НА ЭКРАН
delay (1000);
}

void prepHortDetection()
{
//СЧИТЫВАЕМ ДАТЧИКИ
sensorvalueRig = digitalRead(irsensorRig);
sensorvalueLef = digitalRead(irsensorLef);

if (sensorvalueRig == 1) //СПРАВА
 {
  PrepRig = false; //СТЕНКИ НЕТ
 }
  else 
 {
 PrepRig = true;   //СТЕНКА ЕСТЬ
 }
  
if (sensorvalueLef == 1) //СЛЕВА
 {
  PrepLef = false; //СТЕНКИ НЕТ
 }
  else 
 {
  PrepLef = true;   //СТЕНКА ЕСТЬ
 }

if (sensorvalueLef and sensorvalueRig) //почему то достаточно заслонить лишь один датчик.
    {PrepFront = false;} 
    else
    {PrepFront = true;} //СТЕНКА, ВПЕРЕДИ
/*
Гдето вкралась ошибка, 
переменная PrepFront = true 
даже ели только один из двух датчиков загорожен.
Я хотел чтобы только если оба загорожены.
Там же пишут что здесь "sensorvalueLef and sensorvalueRig"
оба должны быть true чтобы if выполнил код.
*/
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А что он выдаёт когда заслонён 1 или 0?

А вообще поставьте печать значений обоих датчиков после строки №28. С чего Вы взяли, что Вы знаете чему они равны?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

k4eha пишет:

Опять проблема. Оператор "and" и он же "&&" не слушается. Обкатываю два датчика малой дистанции.

Левый и правый но они "видят" и вперёд.

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

А строка 48 работать правильно не будет (and не есть && - читайте операторы си).

k4eha
Offline
Зарегистрирован: 27.03.2021

В принципе любой сайт про С++ "  && логическое И. Есть аналог – оператор and "  Я оба пробовал.

Там есть раздел для профи, не не суюсь пока у меня то, что, попроще ещё не работает.

"//flagA = true, flagB = true;
(flagA and flagB); // true, т.к. оба true" Хоть один false - всё будет false. Неправильно!?
В мониторе порта всё нормально кроме _ВПЕРЕДИ_1 Попробую протиус (о нём первый раз слышу)
А в tinkercad ловить ошибку ни чем не лучше. Протиус не под линукс :-(  Ща буду перехваты ставить из println

 

 

В рассмотренных выше абстрактных примерах с a
и b
происходит следующее: скобка “возвращает” логическое значение, которое является результатом сравнения чисел. Например если у нас a = 10
и b = 20
, то скобка (a > b)
вернёт значение false
, потому что a
меньше b
. А например (a != b)
вернёт true
, т.к. а
действительно не равно b
. Для связи нескольких логических величин используются логические операторы:

    ! логическое НЕ, отрицание. Есть аналог – оператор not
    && логическое И. Есть аналог – оператор and
    || логическое ИЛИ. Есть аналог – оператор or

byte a = 10, b = 20;
(a > b);  // false
(a != b); // true
boolean flag = true;
flag;   // true
!flag;  // false !инверт
!(a > b); // true
//flagA = true, flagB = false;
(flagA && flagB); // false, т.к. B false
//flagA = true, flagB = true;
(flagA and flagB);  // true, т.к. оба true
//flagA = true, flagB = false;
(flagA || flagB); // true, т.к. хотя бы А true
//flagA = false, flagB = false;
(flagA or flagB);  // false, т.к. ни А ни В не true 

Результаты операторов сравнения можно использовать для работы с условиями, а также для цикла while
(речь о нём пойдёт в следующем уроке)

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

k4eha пишет:

В принципе любой сайт про С++ "  && логическое И. Есть аналог – оператор and "  Я оба пробовал.

and, если Вам он так уж нравится - это оператор &. С && он похоже пишется, но действие его другое. Почитайте - это полезно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

mykaida пишет:
and не есть &&
Почему? А в чём разница?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

mykaida пишет:

and, если Вам он так уж нравится - это оператор &. 

Вы что-то перепутали. Вот что говорится в стандарте языка:

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

k4eha,

так Вы сделали то, что я сказал в #23 ? Где результат, почему не выложили? Или ждёте. что А.С. Пушкин за Вас сделает?

k4eha
Offline
Зарегистрирован: 27.03.2021

В tinkercad смоделировал и заставил работать

int           irsensorRig = 2;  //ПРОВОД ПРАВОГО ДАТЧИКА
int           irsensorLef = 12; //И ЛЕВОГО
int           sensorvalueRig;
int           sensorvalueLef; 
boolean       PrepRig =     false;
boolean       PrepLef =     false;
boolean       PrepFront =   false;
void  prepHortDetection(); //ФУНКЦИЯ ОПРОСА ДАТЧИКОВ


void setup() {
Serial.begin(2400); //запускаем серийный порт для связи с пк для отладки программы
pinMode (irsensorRig, INPUT);
pinMode (irsensorLef, INPUT);
}

void loop() {
prepHortDetection(); //ОПРОС ДАТЧИКОВ
Serial.println((String)PrepRig + "_СПРАВО_" + (String)PrepLef + "_СЛЕВА_" + (String)PrepFront + "_ВПЕРЕДИ_");
//ПРИМЕННЕНИЕ - ВЫВОД НА ЭКРАН
delay (1000);
}

void prepHortDetection()
{
 PrepRig =     false;   //Внесённое изменение (всё как надо)
  PrepLef =     false;
  PrepFront =     false;
  
//СЧИТЫВАЕМ ДАТЧИКИ
sensorvalueRig = digitalRead(irsensorRig);
sensorvalueLef = digitalRead(irsensorLef);

if (sensorvalueRig == 1) //СПРАВА
 {
  PrepRig = false; //СТЕНКИ НЕТ
 }
  else 
 {
 PrepRig = true;   //СТЕНКА ЕСТЬ
 }
  
if (sensorvalueLef == 1) //СЛЕВА
 {
  PrepLef = false; //СТЕНКИ НЕТ
 }
  else 
 {
  PrepLef = true;   //СТЕНКА ЕСТЬ
 }

if (sensorvalueLef && sensorvalueRig) //почему то достаточно заслонить лишь один датчик.
    {PrepFront = false;} 
    else
    {PrepFront = true;} //СТЕНКА, ВПЕРЕДИ
/*
Гдето вкралась ошибка, 
переменная PrepFront = true 
даже ели только один из двух датчиков загорожен.
Я хотел чтобы только если оба загорожены.
Там же пишут что здесь "sensorvalueLef and sensorvalueRig"
оба должны быть true чтобы if выполнил код.
*/
}

правильно (туда код без изменений подходит) скопировал себе на железо и опять работает будто "OR"

k4eha
Offline
Зарегистрирован: 27.03.2021

Посмотрел в обзоре на датчик, Out - выход с датчика, при наличии препятствия 0, иначе 1  А ч-чёрт в КАД наоборот. Придумал ща попробую чтоб на стенку true было

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

k4eha,

третий раз спрашиваю, больше не буду, Вы сделали то, что я писал в #23 ?

Или Вы нихрена не читаете а только сам с собой беседу ведёте?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

ЕвгенийП пишет:

Вы что-то перепутали. Вот что говорится в стандарте языка:

Евгений - посыпаю голову пеплом.

k4eha
Offline
Зарегистрирован: 27.03.2021

Всё, заработало, спасибо вам вот с этим sensorvalueRig = !digitalRead(irsensorRig);
sensorvalueLef = !digitalRead(irsensorLef); инвертировал :-)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

k4eha пишет:
вот с этим sensorvalueRig = !digitalRead(irsensorRig);
И что мешало, как Вам писал в №23 просто напечатать эти переменные и увидеть, что они наоборот ещё утром и не трахать себе и остальным мозг? Всегда так делайте.

k4eha
Offline
Зарегистрирован: 27.03.2021

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

Не обратил внимания на то что датчик ки-и-и-тайский - при срабатывание "0"

у людей срабатывание должно быть "1". Вот и мучил код почём зря.

Да там пол кода на while переделать надо ... Переделаю, всё равно не могу на дачу.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

k4eha пишет:

датчик ки-и-и-тайский  ... Вот и мучил код почём зря.

Да, мы так и поняли.