Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Прост внутренняя подтяжка слабенькая. Я хочу сказать, что хуже не будет.
Дребезг примерно так:
Код:
#define ENCODER_DEBOUNCE 3
byte oldval=0;
byte encdeb=0;
void doEncoder(){
byte val=0;
if (digitalRead(encoder0PinA) == HIGH)
{
if (digitalRead(encoder0PinB) == LOW)
{
val=15;
}
else
{
val=24;
}
}
else
{
if (digitalRead(encoder0PinB) == LOW)
{
val=24;
}
else
{
val=15;
}
}
if(oldval != val)
{
if (encdeb < ENCODER_DEBOUNCE)
{
encdeb++;
return;
}
else
{
Serial.print(val,BYTE);
Serial.print(val,BYTE);
oldval=val;
encdeb =0;
}
}
}
Кондеры на 10 нФ устраняют дребезг, но при этом снижают максимальную частоту вращения ручки.
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Спасибо .
Попробую.
Внутренняя подтяжка 20 ком , что вполне достаточно
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Цитата:
Сообщение от
Urvin
Энкодер на резисторы вешать несколько некорректно - энкодер может давать такую частоту, что она будет "сьедаться" ацп - суть есть конденсатором + обработчиком напряжения на этом конденсаторе.
Если есть возможность, то надо делать на цифровых входах.
В схеме еще хорошо бы повесить сопротивления с сигналов энкодера на питание, для пущей надежности.
понимаю что лучше на цифровые входы повесить. Да энкодер размещаться на руле будет, а с руля 3 провода всего идут, так что вариант только с резисторами. К тому же цифровых входов на ардуине итак впритык, еще двух для энкодера просто нету.
На счет скорости - все ок. Проверял. Даже при быстром вращении все ловится корректно, проц успевает отловить.
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Ничерта короче не пойму.
Перепробовал кучу примеров работы с энкодерами.
Этот исходник, из проекта где все функции объеденены в ардуине.
Кондеры ставил которые по 0,1мкф.
Делал доп. анализ для дребезга, пропуска ложных срабатываний и.т.д.
СИтуевина одна и та же. Если просто вращать энкодер(хоть медленно), вперед то шаги выглядят примерно так (счетчик шагов):
..0
1
2
3
4
3
4
5
6
...
..20
19
18
17
18
17
16
15
Короче крутишь в одну сторону а он в противоположную срабатывает часто. Программа абсолютно симметрична в работе для направления по часовой и против. НО по часовой меньше ошибочных срабатываний энкодера.
Я вращаю энкодером шаговый. В итоге шпиндель шагового то нормально едет, то его колбасит. Не серьезно.
Последний исходник, который использовал:
Цитата:
volatile int encoder0Pos = 0;
void setup()
{
encoder0Pos = 0;
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH);
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH);
attachInterrupt(0, doEncoderA, CHANGE);
attachInterrupt(1, doEncoderB, CHANGE);
}
void doEncoderA()
{
if (digitalRead(encoder0PinA) == HIGH) {
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
else
{
if (digitalRead(encoder0PinB) == HIGH) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
}
void doEncoderB()
{
if (digitalRead(encoder0PinB) == HIGH) {
if (digitalRead(encoder0PinA) == HIGH) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
else {
if (digitalRead(encoder0PinA) == LOW) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
}
void loop()
{
//Rotate
if (encoder0Pos<0)
{
encoder0Pos++;
rotate_left(1);
}
if (encoder0Pos>0)
{
encoder0Pos--;
rotate_right(1);
}
}
Я уже подумываю что энкодер бракованый.
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
У меня код из шапки, с конденсаторами работает нормально, без кондеров глючит.
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
по 0,1 мкф к центральному, а его на землю?
кстати почему 24 и 15? просто так? :) почему не 0 и 1 к примеру?
или ты этот байт просто еще для чего-то используешь?
Можно еще вопросец по языку?
Цитата:
attachInterrupt(0, doEncoderA, FALLING); // настроить прерывание interrupt 0 на pin 2
где указывается что на пин №2? Как он определяет что прерывание по спаду именно на 2ом пине ? doEncoderA ведь просто имя функции, а дефайн encoder0PinA никуда в этом случае не подставится.
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Конденсаторы на землю и выход "C" энкодера на землю
Вот этот код
PHP код:
#define encoder0PinA 2
#define encoder0PinB 3
byte bytes[1] ;
void setup()
{
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // подключить подтягивающий резистор
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // подключить подтягивающий резистор
attachInterrupt(0, doEncoderA, FALLING); // настроить прерывание interrupt 0 на pin 2
attachInterrupt(1, doEncoderB, FALLING); // настроить прерывание interrupt 0 на pin 3
Serial.begin (115200);
}
void loop()
{
}
// обработка прерывания
void doEncoderA()
{
if(digitalRead(encoder0PinB)==HIGH){bytes[0]=24;}else{bytes[0]=15;}
Serial.write( bytes,1);
}
// обработка прерывания
void doEncoderB()
{
if(digitalRead(encoder0PinA)==HIGH){bytes[0]=15;}else{bytes[0]=24;}
Serial.write( bytes,1);
}
Использую программу Carduino монитор
Вот результат, как видишь нет пропусков ни в одну ни в другую сторону
Вложение 8022
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
мдя, видать чето я напутал в схеме.
вот я кручу по часовой стрелке энкодер, постепенно увеличивая скорость вращение