Help (энкодер)
- Войдите на сайт для отправки комментариев
Приветствую, я совсем недавно приобрел Arduino UNO, и мне необходимо с ее помощью выполнить маленький проект. Но у меня возникла проблема, которую я никак не могу решить. Заключается она вследующем: вращая вал энкодера (ROTARY ENCODER E30S4-200-6-L-5) по часовой, срабатывает прерывание и количество импульсов считается, как только направление вращение вала меняется, мне необходимо, запомнить количество импульсов до смены направления вращения вала, и зная количество ипульсов, посчитать угол, так как этот энкодер на 200 импульсов, следовательно 1 импульс = 1,8 (град), затем зная угол, определить cos() и выдать в порт, и ожидать следующего поворота вала по часовой. И Я УЖЕ 3 ДЕНЬ не могу понять, как мне вытянуть quantity_of_impulses, помогите пожалуйста.
volatile unsigned int last_quantity_of_impulses, quantity_of_impulses = 0;
//========================================================================
void setup() {
Serial.begin (9600);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
attachInterrupt(0, ai0, RISING);
}
//========================================================================
void loop() {
if( quantity_of_impulses != last_quantity_of_impulses ){
Serial.println (quantity_of_impulses);
last_quantity_of_impulses = quantity_of_impulses;
;
}
}
//========================================================================
void ai0() {
if(digitalRead(3)==LOW) {
quantity_of_impulses++;
}else{
detachInterrupt(ai0);
quantity_of_impulses=0;
}
}
//========================================================================
Так Вы ничего не вытяните. Для начала гуглите работу с энкодером. С ним не так работают.
Хорошо, прошу подскажите, в чем моя ошибка?
У Вас не ошибка, у Вас в корне неверный подход к работе с энкодером. Например, Вы читаете только rise одного пина, и наличие сигнала на втором, ... в общем ... это Вам надо с нуля рассказывать как устроен энкодер. Найдите какую-нибудь статью и почитайте пр энкодер, по код Грея, а то мне придётся учебник переписывать..
Может так
volatile unsigned int quantity_of_impulses = 0; volatile bool f_enkod = 0; //======================================================================== void setup() { Serial.begin (9600); pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); attachInterrupt(0, ai0, RISING); } //======================================================================== void loop() { if(!f_enkod){ Serial.println (quantity_of_impulses); quantity_of_impulses = 0; f_enkod = 1; } } //======================================================================== void ai0() { if(digitalRead(3)==LOW) { quantity_of_impulses++; } else{ f_enkod = 0; } } //========================================================================А про енкодер можно посмотреть здесь хороший пример ( http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=2#comm... )
У Вас не ошибка, у Вас в корне неверный подход к работе с энкодером. Например, Вы читаете только rise одного пина, и наличие сигнала на втором, ... в общем ... это Вам надо с нуля рассказывать как устроен энкодер.
А что не так? Rise на одном пине и уровень на втором дают однозначное направление вращения квадратурного энкодера если отсутствует дебезг (подавлен аппаратно).
Так в том и дело, что нигде не сказано об аппаратном подавлении, а значит надо читать и rising, и falling и анализировать ситуацию. Там получается автомат, часть состояний которого отбрасывается ввиду нереальности.
а так?
volatile unsigned int impulseNumber = 0; volatile unsigned long startTime, time = 0; //===================================================================================================================== void setup() { Serial.begin (9600); pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(2), ai0, RISING); startTime = millis(); } //===================================================================================================================== void loop() { //если количество импульсов не соответствует старому, выводить новое количсетво импульсов if(time == 0) { startTime = millis(); } time = millis() - startTime; if( time >= 2000 && impulseNumber != 0 && impulseNumber > 7 ) { Serial.print ("Wheel diameter = "); //float wheelD = wheelDCalculator(impulseNumber); Serial.println (impulseNumber); impulseNumber = 0; } } //===================================================================================================================== void ai0() { if (digitalRead(2) == digitalRead(3)) { impulseNumber++; time=0; } } //=====================================================================================================================