Не могу разобраться с объектами

ande0
Offline
Зарегистрирован: 04.11.2019

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

Ломаю стары

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

ande0 пишет:

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

Ломаю стары

ande0
Offline
Зарегистрирован: 04.11.2019

Пока пишу, кто-то успеет постебаться))) Наздоровье)

Попытка 2

Ломаю принтер. У него на подачу и движение каретки стоят коллекторные двигатели и энкодеры. Решил освоить для себя классы и объекты. Есть у меня переменная-флаг moveDone внутри класса, которая должна меняться в прерывании. Столкнулся с проблемой: она то ли не меняется, то ли возвращает неправильное значение, когда ее же использует другой объект.

class Motor {
  public:
    Motor (byte pinEnable, byte pinA, byte pinB);
    void move(boolean moveDirection, byte moveSpeed, int distance);
    void stop();
    void hardStop();
    volatile boolean moveDone = true; 
    int upperLimit;
    int lowerLimit;
    int pos;
    
  private:
    byte _pinEnable;
    byte _pinA;
    byte _pinB;
};



boolean A,B;
Motor head(10,11,12);
Motor feed(10,14,15);
int prevHeadPosition;
volatile boolean temp;


  
void setup() {
  Serial.begin(9600);
  attachInterrupt(0, headMove, CHANGE);
  attachInterrupt(1, feedMove, CHANGE);
  pinMode (4, INPUT);
  pinMode (5, INPUT);
  pinMode (13, OUTPUT);
}



void loop() {
  feed.pos = 0;
  feed.move (0,255, -200);
  while (!feed.moveDone){
  digitalWrite (13,HIGH); 
  }
  waitms(100);
  feed.pos = 0;
  feed.move (1,255, 31000);
  while (!feed.moveDone){
   digitalWrite (13,LOW); 
  } 
  
  while (1){
    Serial.println(feed.pos);
    waitms (100);
  }
}

void waitms(int ms){
  unsigned long myTimer;
  myTimer = millis()+ms;
  while (millis() < myTimer){} 
}


Motor::Motor (byte pinEnable, byte pinA, byte pinB) // конструктор класса
{
   _pinEnable = pinEnable;
   _pinA = pinA;
   _pinB = pinB;
   pinMode (pinA, OUTPUT); 
   pinMode (pinB, OUTPUT);  
}

void Motor::move(boolean moveDirection, byte moveSpeed, int distance){ // метод класса который вращает мотор до нужного значения
  moveDone = false;
  analogWrite (_pinEnable, moveSpeed);
  if (moveDirection) {
    upperLimit = distance;
    lowerLimit = pos - 500;
    digitalWrite (_pinA, HIGH);  
    digitalWrite (_pinB, LOW);  
  } else {
    lowerLimit = distance;
    upperLimit = pos + 500;
    digitalWrite (_pinA, LOW);  
    digitalWrite (_pinB, HIGH); 
  }  
}

void Motor::stop() {// остановка мотора
    moveDone = true;
    digitalWrite (_pinEnable, LOW);
    digitalWrite (_pinA, LOW);  
    digitalWrite (_pinB, LOW);
}

void Motor::hardStop() {// остановка мотора с торможением
    moveDone = true;
    digitalWrite (_pinEnable, HIGH);
    digitalWrite (_pinA, LOW);  
    digitalWrite (_pinB, LOW);
}

void headMove(){
  A=digitalRead(2);
  B=digitalRead(7);
  if (B==A) {
    head.pos--;
//    if (head.pos < head.lowerLimit) head.stop(); 
  }
  else {
    head.pos++;
//    if (head.pos > head.upperLimit) head.stop();
  }
}

void feedMove(){
 A=digitalRead(3);
 B=digitalRead(5);
  if (B==A) {
    feed.pos--;
    if (feed.pos < feed.lowerLimit) feed.stop(); 
  }
  else {
    feed.pos++;
    if (feed.pos > feed.upperLimit) feed.stop();
  }
}

Все работает как должно, но если в headMove раскомментировать строки с if все перестает работать. Навечно остаюсь в цикле while и жду изменения feed.moveDone при том, что двигатель останавливается. Не могу понять как вообще программа попадает в прерывание moveHead, но даже если попадает и даже если выполняется условие, то head.stop должно менять moveDone в объекте head.

ande0
Offline
Зарегистрирован: 04.11.2019

Забыл еще один вопрос. В строках 43 и 49 дергаю 13 ногой, потому что пустой цикл как будто вообще игнорируется и программа выполняется дальше. Почему не едут лыжи?)

baby_in_Arduino
Offline
Зарегистрирован: 21.07.2019

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

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

baby_in_Arduino пишет:
а как вообще отлаживать программки на ардуинке? можно запустить дебуггер и пошагово выполнять и видеть состояние регистров переменных?

Без приложения усилий - нет

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

DetSimen пишет:

baby_in_Arduino пишет:
а как вообще отлаживать программки на ардуинке? можно запустить дебуггер и пошагово выполнять и видеть состояние регистров переменных?

Без приложения усилий - нет

ЕвгенийП рекомендовал выводить в сериал

ande0
Offline
Зарегистрирован: 04.11.2019

Конечно и в сериал выводил и лампочками мигал, чтобы понять. 2 дня уже сижу с этой ерундой. Уже почти решил все простыми функциями отдельными для feed и для head сделать. Но тут так красиво. Не хотелось бы сдаваться.

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

ande0 пишет:

Почему не едут лыжи?)

Отвечать? Или "ну его на"?

ande0 пишет:

2 дня уже сижу ... Не хотелось бы сдаваться.

Когда у меня возникает проблема, я нормально отношусь к тому, что она требует пару недель для своего решения. Но за пару недель, обычно, решаются. Так что, не сдавайтесь, у Вас ещё много времени.

ande0
Offline
Зарегистрирован: 04.11.2019

Видимо помог коллективный дух.

Переписал все на отдельных функциях для каждого мотора (исключил объекты). Проблема не ушла. Потихоньку ковырял функции и я разобрался! Случилась эврика!!! У энкодера, видимо, какое-то пограничное состояние может быть. И когда мотор стоит все-равно генерятся прерывания и позиция то +1, то -1, либо еще выбег (инерция от предыдущего движения). В итоге оно срабатывало в момент, когда строка 75 (moveDone = false) уже выполнилась но до задания пределов (строка 78, 79) еще не дошло. А в прерывании срабатывало условие и метод stop, а в нем moveDone опять становился true. Поэтому и цикл while не выполнялся (я думал какой то глюк).

В итоге перенес строку 75 после 87, а в прерывании в условии добавил, что метод stop срабатывает только если мы думаем, что движемся (moveDone = false). Теперь все работает и с объектами. Они были не при чем. И цикл наладился. На него тоже грешил.

И как же хорошо, что чудес все-таки не бывает.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

ЕвгенийП как талисман )))