Проблема в коде

RubanZ
Offline
Зарегистрирован: 12.03.2014

Здраствуйте, у меня в этом коде не работает motorлевый, а точнее не подается ШИМ сигнал на 5-pin.

С другой программой работает.
 

#include "leOS.h"  
leOS myOS;
//motorПравый
#define dir1PinA   8 //Серый
#define dir2PinA   7 //Белый
#define speedA     10
//motorЛевый
#define dir1PinB   4 //Чёрный
#define dir2PinB   2 //Коричневый
#define speedB     5 //вот этот pin
//Sensors//
#define outputPin  6 //подключил к ШИМ Ультрозвуковой датчик
#define inputPin   9 //Echo
//Random//
#define TimeDelay random(500, 3500)

void setup()
{
  Serial.begin(9600);
  myOS.begin();
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT);
  pinMode(dir2PinB, OUTPUT);
  pinMode(inputPin, INPUT);   //УЗ-датчик
  pinMode(outputPin, OUTPUT); //УЗ-датчик
  myOS.addTask(sensor1, 300); //выполнение задачи раз в 100 мс
}

void sensor1()
  {
    //sensor//
  digitalWrite(outputPin, LOW);
  delayMicroseconds(2);
  digitalWrite(outputPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(outputPin, LOW);
  int distance = (pulseIn(inputPin, HIGH))/58;
  Serial.print(distance);
  Serial.print(" cm");
  Serial.println("  ");
  // действи на значение sensor
  if(distance < 25) travel(HIGH,LOW,HIGH,LOW,80); //едем назад 
  } 
  
void loop()
{
 //едем куда хотим
    byte napravlenie = random(1, 5);
    switch (napravlenie)
    {
    case 1: travel(HIGH,LOW,LOW,HIGH,80);  //поворачиваем направо
    case 2: travel(LOW,HIGH,HIGH,LOW,80);  //поворачиваем налево
    case 3: travel(LOW,HIGH,LOW,HIGH,80);  //едем Вперед
    case 4: travel(LOW,LOW,LOW,LOW,0);      //стоп
    } 
} 

void travel(bool zadRight, bool perRight, bool zadLeft, bool perLeft, byte speedRL)
{
  digitalWrite(dir1PinA, zadRight);
  digitalWrite(dir2PinA, perRight);
  digitalWrite(dir1PinB, zadLeft);
  digitalWrite(dir2PinB, perLeft);
  analogWrite(speedA, speedRL);
  analogWrite(speedB, speedRL);
  delay(TimeDelay);
}

 

RubanZ
Offline
Зарегистрирован: 12.03.2014

Не работает даже если поменять на другой пин

 

leshak
Offline
Зарегистрирован: 29.09.2011

pinMode?

kentik
Offline
Зарегистрирован: 28.03.2013

попробуйте добавить в setup()

pinMode(speedB, OUTPUT);

RubanZ
Offline
Зарегистрирован: 12.03.2014

не работает

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Мож быть  leOs пакостит? :)

leshak
Offline
Зарегистрирован: 29.09.2011

dimax пишет:

Мож быть  leOs пакостит? :)

Кстати вполне вероятно. Она похоже использует Timer2 для диспетчерезации, то есть все функции которые на нее превешены выполняются, фактически, "внутри обработчика прерывания". А мы видим, внутри превешенной функции и delay, pulseIn и serial.print.... вообщем почти все способы "выстрелить себе в ногу" применены.

Не считая того, что она может дергать travel одновременно с его же вызовами из loop()

RubanZ
Offline
Зарегистрирован: 12.03.2014

тогда передложите замену leOS (параллельное выполнение программы)

leshak
Offline
Зарегистрирован: 29.09.2011

На 8-ми битниках, паралельного выполнения - не бывает. В том числе и с leOs. Только "псевдо".

А заменой является отказ от delay(), pulseIn и проч. блокирующий функций (которые останавливают скетч).

Все писать только с использованием millis()/micros(), запоминанием времени в переменные, просмотром в loop() "настало время или нет", в обработчких прерывание выставлять какие-нибудь "флаги/переменные", указывающие "нужно что-то сделать" (скажем вывести переменную в Serial). А сам вывод - делать в loop().

Начинать разбирательство "какая бывает жизнь без delay()". Можно с примера:Мигаем светодиодом без delay()

Ну и сам форум пошерстить на эту тему. Веток связанных с этим можно найти не одну и не две. Десятки минимум.

leshak
Offline
Зарегистрирован: 29.09.2011

Но.... прежде чем "начать все переделывать с нуля". Закоментируйте, для начала, эту leOs и функцию sensor1(). Убедитесь что причина именно в ней. Что, после этого, на пине появится желанный PWM.

RubanZ
Offline
Зарегистрирован: 12.03.2014

без него работает, спасибо большое

leshak
Offline
Зарегистрирован: 29.09.2011

Ну тогда переделывайте, на безделейность (leOs) - нафиг. sensor1() - пока оставте. Просто временно не вызывайте. Пригодится чуть позже.

Суть переделки примерно такова:

нам нужно разбить функцию travel(), на две функции. setTravel(bool zadRight, bool perRight, bool zadLeft, bool perLeft, byte speedRL) и doTravel()

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

doTravel() - постоянно вызвается из loop(). Как можно чаще. Делает она одно - берет значение из переменных (которые заполнила setTravel()) и выставляет эти значение на пины.

Саму setTravel(), мы вызваем "переодически", но переодичность обеспечивает не с помощью delay(), а с помощью механизма Мигаем светодиодом без delay() . Только вы будете не диод включать, а делать свой random() и setTravel()

И наверное менять направление каждые 80 мсек - это будут "пляски святого вита". Чуть поболее время возмите...

 

 

RubanZ
Offline
Зарегистрирован: 12.03.2014
//motorПравый
#define dir1PinA   8 //Серый
#define dir2PinA   7 //Белый
#define speedA     10
//motorЛевый
#define dir1PinB   4 //Чёрный
#define dir2PinB   2 //Коричневый
#define speedB     5
//Sensors//
#define outputPin  6 //подключил к ШИМ Ультрозвуковой датчик
#define inputPin   9 //Echo
//Random//
#define TimeDelay random(500, 3500)
long previousMillis = 0;
long interval = 1000;
long Time = 0;

void setup()
{
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT);
  pinMode(dir2PinB, OUTPUT);
  pinMode(speedB, OUTPUT);
  pinMode(inputPin, INPUT);   //УЗ-датчик
  pinMode(outputPin, OUTPUT); //УЗ-датчик
}
/*
void sensor1()
  {
    //sensor//
  digitalWrite(outputPin, LOW);
  delayMicroseconds(2);
  digitalWrite(outputPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(outputPin, LOW);
  int distance = (pulseIn(inputPin, HIGH))/58;
  // действи на значение sensor
  if(distance < 25) travel(HIGH,LOW,HIGH,LOW,80); //едем назад 
  } 
*/  
void loop()
{
 sensor1();
 doTravel();
 unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
  previousMillis = currentMillis;
  if (ledState == LOW) //я тут в тупике не понимаю что дальше
      ledState = HIGH;
    else
      ledState = LOW;
setTravel();
}
} 

void motor()
{
 //едем куда хотим
    switch (napravlenie)
    {
    case 1: travel(HIGH,LOW,LOW,HIGH,80);  //поворачиваем направо
    case 2: travel(LOW,HIGH,HIGH,LOW,80);  //поворачиваем налево
    case 3: travel(LOW,HIGH,LOW,HIGH,80);  //едем Вперед
    case 4: travel(LOW,LOW,LOW,LOW,0);      //стоп
    } 
} 

void setTravel(bool zadRight, bool perRight, bool zadLeft, bool perLeft, byte speedRL)
{
  digitalWrite(dir1PinA, zadRight);
  digitalWrite(dir2PinA, perRight);
  digitalWrite(dir1PinB, zadLeft);
  digitalWrite(dir2PinB, perLeft);
  analogWrite(speedA, speedRL);
  analogWrite(speedB, speedRL);
}

void doTravel();
{
  delay(TimeDelay);
  byte napravlenie = random(1, 5);
}

Я в тупике. 

leshak
Offline
Зарегистрирован: 29.09.2011

>Я в тупике. 

OK. Поехали тогда пошагово.

setTravel(). "вместо "сразу выставить пины" в то что ей передали, она просто сохраняет свои параметры в глобальные переменные "

1. Завидите пять глобальных переменных
2. setTravel, вместо вызова digitalWrite() должна просто сохранять свои входные параметры в эти переменные.

Вот примерно так: (пример сохранения одного параметра, а у вас их пять):

bool gBlaBla; // глобальная переменная где граним бла-бла

void setup(){
}

void loop(){

}

void setBlaBla(bool blabla){
  
   // digitalWrite(PIN,blalba); - раньше мы передавали параметр на пин
   // , а теперь просто сохраняем его в переменную
   gBlaBla=blabla; // сохранили параметр в глобальную переменную
}

Сделайте, по аналогии, setTravel и покажите ее тут (вместе с объявлением глобальных переменных). Остальное - пока не нужно.