Помогите разобраться с энкодером

psn26
psn26 аватар
Offline
Зарегистрирован: 12.03.2014
Всем привет. Помогите, пожалуйста. Я уже вторые сутки за компом, кушать очень хочется...
 
Есть вот такя связка мотор-редукто и энкодер.
 
Есть вот такой код
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
const byte encoder0pinB = 4;//B pin -> the digital pin 4
byte encoder0PinALast;
int duration;//the number of the pulses
boolean Direction;//the rotation direction 


void setup()
{  
  Serial.begin(57600);//Initialize the serial port
  EncoderInit();//Initialize the module
}

void loop()
{
  Serial.print("Pulse:");
  Serial.println(duration);
  duration = 0;
  delay(100);
}

void EncoderInit()
{
  Direction = true;//default -> Forward  
  pinMode(encoder0pinB,INPUT);  
  attachInterrupt(0, wheelSpeed, CHANGE);
}

void wheelSpeed()
{
  int Lstate = digitalRead(encoder0pinA);
  if((encoder0PinALast == LOW) && Lstate==HIGH)
  {
    int val = digitalRead(encoder0pinB);
    if(val == LOW && Direction)
    {
      Direction = false; //Reverse
    }
    else if(val == HIGH && !Direction)
    {
      Direction = true;  //Forward
    }
  }
  encoder0PinALast = Lstate;

  if(!Direction)  duration++;
  else  duration--;
}

 

Ту часть кода, которая управляет мотором, я не стал сюда выкладывать, дабы было меньше информации.
Это всё работает, и моторы и с энкодера поступают данные, но я их не понимаю и поэтому дальше работать с ними не могу.
Когда я открываю "Монитор порта", там "бегут" то 0 то 1 то -1, фигего знает куда это сувать....
 
Как с этой гадины, получить понятные показания?
Напрвление вращения - не нужно.
Нужно понять только скорость вращения, ну например кол-во оборотов или импльсов в секунду или минуту, это уже не столь важно, главное хотя бы что-то понятное....
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А использовать millis() не судьба?

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

psn26 пишет:

Как с этой гадины, получить понятные показания?
А какие показания Вам понятны?
psn26
psn26 аватар
Offline
Зарегистрирован: 12.03.2014

qwone пишет:

А использовать millis() не судьба?

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

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

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

psn26 пишет:

Как с этой гадины, получить понятные показания?
А какие показания Вам понятны?

Если бы в этот код дописать какую-то переменную, которая принимала бы значение равное количеству импульсов в данный момент времени (импульс/секунда или миллисекунда), то дальше я бы смог сам разобраться.
Сейчас эта переменная "duration" и она принимает не понятные для меня значения, то 0 то 1 то -1. Думаю, это примерно то, что мне нужно, но в какой-то другой системе исчислений, видимо на языке какой-то другой цивилизации)
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, по идее, если двигатель крутится в одну и туже сторону (не переключается) Ваша duration равна количеству срабатываний энкодера в течение 100 ms. Если нужен другой временной интервал, поменяйте в строке 19.

Но переменные объявлены неправлильно.

1. Добавьте слово volatile в начало строк 3-5
2. Проинициализируйте переменные, т.е. в тех строка 3-5, присвойте им начальные значения.

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

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

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

Ну, по идее, если двигатель крутится в одну и туже сторону (не переключается) 

Переключается. Он крутится в разное время в разных направлениях, но мне не нужно понимать это с помощью энкодера, т.е. эти данные для дальнейших вычислений, мне не нужны.

Спасибо за помощь.

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

Погодите, тогда я не понимаю, что Вам нужно.

Дело в том, что duration при обнаружении движения в одну сторону - увеличивается на 1, а в другую - уменьшается на 1.

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

Но это никак не отменяет необходимости сделать то, о чём я писал - это просто ошибки и их по-любому надо исправить.

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

ЕвгенийП пишет:
давайте его сюда вместе с копипастой того, что он в сериал выводит.

Честно говоря, Я не совсем понимаю что такое копипаста, но догадываюсь )))

Вот так выглядит "монитор порта"

Pulse:0
Pulse:1
Pulse:0
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:0
Pulse:1
Pulse:1
Pulse:0
Pulse:0
Pulse:1
Pulse:1
Pulse:0
Pulse:0
Pulse:-1
Pulse:0
Pulse:-1
Pulse:0
Pulse:-1
Pulse:0
Pulse:-1
Pulse:0
Pulse:0
Pulse:-1
Pulse:-1
Pulse:0
Pulse:0
Pulse:-1
Pulse:0
Pulse:-1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0
Pulse:1
Pulse:0

 

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

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

Но это никак не отменяет необходимости сделать то, о чём я писал - это просто ошибки и их по-любому надо исправить.

Ок. Попробую разобраться в этом.

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

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

В общем, пока толком не объясните что нужно - говорить не о чем.

Наверно надо написать, то для чего мне нужны эти данные...

Постараюсь коротко)))

Сейчас я управляю мотором с помощью переменного резистора. Беру данные с резистора (0-1023), и отправляю их на ШИМ (0-255), но только я поделил 1023 на три куска, это необходимо для реверса и остановки.

        int m1 = 5; //скорость вращения мотора
        int m2 = 7; //направление вращения мотора
        int r1 = A4; //переменный резистор

void setup() {
        pinMode(m1, OUTPUT);
        pinMode(m2, OUTPUT);
        pinMode(r1, INPUT);
}

void loop() {

//крутим мотор вперёд
        if (analogRead(r1) <= 461){
          analogWrite(m1, map(analogRead(r1), 1, 461, 255, 40));
          digitalWrite(m2, LOW);}

//крутим мотор назад
        else if (analogRead(r1)>=563){
          analogWrite(m1, map(analogRead(r1), 563, 1022, 40, 255));
          digitalWrite(m2, HIGH);}

//остановка
        else if (analogRead(r1)>=462&&analogRead(r1)<=562){
          digitalWrite(m1, LOW);
          digitalWrite(m2, LOW);
}

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

Данные с переменного резистора (0-1023) отправлять не напрямую в ШИМ, а как бы через энкодер. Т.е. с помощью резистора я задаю необходимое мне кол-во импульсов в секунда (ну или об/мин), Ардуина посмотрит на кол-во импульсов на энкодере, и уже сама добавит или уменьшит ШИМ (0-255). Примерно так.

Если короче, то мне нужно получить с энкодера некое целое число (от 0 до фиг его знает, например 50), которое будет отображать текущее кол-во импульсов в данный момент.

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

...Нет ребята всё не так, всё не так ребята...
Сделайте как все делают, резистором задаём скрость вращения, а энкодером - направление

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

ua6em пишет:

...Нет ребята всё не так, всё не так ребята...
Сделайте как все делают, резистором задаём скрость вращения, а энкодером - направление

)))))))))

Мне необходимо контролировать кол-во об/мин, и если оно отклонятся от заданного резистором, из-за нагрузки на валу двигателя, то нужно программно уменьшить или увеличить уровень ШИМ.

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

А чем контролируете обороты? Заставьте это делать саму ардуину, вроде бы с колёсами и датчик оборотов был, с него снимаем число импульсов, сравниваем, корректируем ШИМ в ту или иную сторону

 

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

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

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

Ничего не понял. Кто крутит енкодер? Ваш мотор? Сколько импльусо енкодера Вы получаете за один оборот двигателя? Или Вы его рукой крутите вместо переменного резистора? Может рарисуете типа схему, чтоб понятно было "кто на ком стоял" :))

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Ва необходимо посчитать количество например единиц котырые поступают с енкодера за определенный  период времени, отсюда и узнаете скорость. Можно поцепить енкодер на прерывание и считать по возрастающему фронту

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Ему нужно посчитать сколько и пульсов даёт энкодер, карточек те -1 надо конвертировать в +1тогда будет сумма импульсов, но для измерения скорости этого недостаточно. Нужно высчитывать сколько суммарный импульсов для промежутка времени.

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

Энкодером? Офигеть!!! И жить ему оставалось???
Для этого есть оптические датчики, раздербаньте любую старую мышку и будет вам два готовых датчика оборотов!
Я по цифровым следящим приводам не специалист, только по аналоговым, но идея и там и здесь одинаковая, там с датчика снимается напряжение, сравнивается с заданным, если меньше операционный усилитель увеличивает ток в обмотке якоря, если больше уменьшает, для высокой стабильности скорости количество импульсов на один оборот двигателя (не колеса а именно двигателя) должно быть максимально возможным, если на колесе получится достаточно медленная следящая система, можно снимать пульсации прясо с коллектора двигателя, усливать-преобразовывать-оцифровывать, но тут надо с паяльнико дружить,
Так что мышь как загашник деталюшек ваше всё

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

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

Ничего не понял. Кто крутит енкодер? Ваш мотор? Сколько импльусо енкодера Вы получаете за один оборот двигателя? Или Вы его рукой крутите вместо переменного резистора? Может рарисуете типа схему, чтоб понятно было "кто на ком стоял" :))

Энкодер крутит мотор. А вот сколько импульсов выдаёт энкодер, не могу посчитать, а мне как раз именно это и нужно. Энекодер выдаёт ту хрень про которую я написал выше (то 0 то 1 то -1), точнее не энкодер, а проограмма/код/скетч, который написал производитель энкодера.

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

vosara пишет:

Ва необходимо посчитать количество например единиц котырые поступают с енкодера за определенный  период времени, отсюда и узнаете скорость. Можно поцепить енкодер на прерывание и считать по возрастающему фронту

Я понимаю, что мне нужно как-то упорядочить те данные, которые выдаёт энкодер. В идеале мне нужно получить целое число: количество импульсов за еденицу времени. Но, к сожалению, моих знаний не хватает чтобы написать код для этого... :(

У энкодера два "сигнальных" провода, один из которых как раз и подцеплен к входу Ардуино (2) поддерживающему прерывание, а второй к входу (4), собственно так и рекомендует производитель.

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

Что-то на фото не увидел энкодера, может там как раз датчик оборотов??? Сделайте для народа побольше фотографий

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

knack пишет:
Ему нужно посчитать сколько и пульсов даёт энкодер, карточек те -1 надо конвертировать в +1тогда будет сумма импульсов, но для измерения скорости этого недостаточно. Нужно высчитывать сколько суммарный импульсов для промежутка времени.

Ураааа! Меня кто-то понял! Да, мне нужно, наверное, посчитать кол-во этих ипульсов. Но у меня есть сомнения, что нужно всеголишь посчитать эти импульсы, я почемуто думаю, что эти цифры в другой системе исчислений, двоичной или как там её.... а может в сколькито битной.... вообщем фиг знает...

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

ua6em пишет:

Что-то на фото не увидел энкодера, может там как раз датчик оборотов??? Сделайте для народа побольше фотографий

Не знаю можно ли на этом форуме выкладывать ссылки на магизины, но выкладываю.

Вот с такой хренью я борюсь http://www.robototehnika.ru/e-store/catalog/202/1277/

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

Там просто импульсы )))
+1 и -1 это наверное передний и задний фронты

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

ua6em пишет:

Там просто импульсы )))
+1 и -1 это наверное передний и задний фронты

Это для Вас "там просто импульсы", а для меня это....

Как мне из этих нафиг импульсов, сделать целое число отображающее кол-во импульсов за какую-то еденицу времени....?

Помогите пожалуйста......

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

psn26 пишет:

ua6em пишет:

Там просто импульсы )))
+1 и -1 это наверное передний и задний фронты

Это для Вас "там просто импульсы", а для меня это....

Как мне из этих нафиг импульсов, сделать целое число отображающее кол-во импульсов за какую-то еденицу времени....?

Помогите пожалуйста......


Проводим на форуме счётчик оборотов. val = val+ abs(Pulse); выбирай промежуток времени и сбрасывай счётчик.

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

knack пишет:
Проводим на форуме счётчик оборотов. val = val+ abs(Pulse); выбирай промежуток времени и сбрасывай счётчик.

Ща попробую что-то с этим "val = val + abs(Pulse)" сделать

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Попробуйте разобраться так

int state;
int sped;//Скорость
unsigned long millis_old;

void setup(){
	attachInterrupt(0, blink, CHANGE); // привязываем 0-е прерывание к функции blink().
}

void blink()
{
	state++ ;                    // Считае импульсы
}


void loop (){
	if(millis()- millis_old >= 10){ //За 10 милис.
		sped = state / 10;
		state = 0;
		millis_old = millis();
	}
	
}

 

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

knack пишет:
Проводим на форуме счётчик оборотов. val = val+ abs(Pulse); выбирай промежуток времени и сбрасывай счётчик.

))))))))

Если быть до конца честным, то я не понимаю что надо с этим сделать... ))))))))

Можно Вас попросить написать, внести дополнения в указанный выше код, чтобы переменная "duratio" приняла вид из "10010-1.... " в "например 42", ну или появилась новая переменная с необходимым для меня значением

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

vosara пишет:

Попробуйте разобраться так

Спасибо.

Ща буду пробовать