Ротари Энкодер

Радждардж
Чт, 5 ноября 2015 г., 10:27 утра
Кому -нибудь удалось получить одну из опубликованных библиотек или любых локальных кодов, работающих с Mini STM32 и этим роторным энкодером?
http: // henrysbench.Капнфац.com/henrys- ... Er-Manual/

Я вижу, как цифровые расчет изменяется и т. Д., Не уверен, что описание разведений является точным.
В настоящее время я использую D17 (a), D18 (b) и D19 (Buttton).
У доски встроенные подтягивания, и я использую 3.3В .

Это проблема с аппаратным обеспечением или программное обеспечение?

Мадиас
Чт, 05 ноября 2015 г., 14:07
Нет. Я этого не сделал, но почему ты не используешь мой код?
http: // www.STM32duino.com/viewtopic.PHP?F = 18&t = 15

с уважением
Матиас

Бьянкифан
Чт, 05 ноября 2015 г., 17:13
На рынке есть несколько различных ротажных, с от 12 до 36 задержков и от 9 до 36 импульсов.
Задержание Sotimes равняется импульсам, иногда не.
Некоторые типы будут нанесены на фазу «B», поэтому вы не можете оценить.

Некоторое время назад я заказал пару дешевых китайских EC11, абсолютно дерьмо!
Иногда они генерируют один импульс, иногда два, иногда не.

Альп -эндоугольники намного дороже..Но они сохраняют сердечные приступы ;)

Радждардж
Пт 06 ноября 2015 г. 10:23 утра
Мадиас написал:Нет. Я этого не сделал, но почему ты не используешь мой код?
http: // www.STM32duino.com/viewtopic.PHP?F = 18&t = 15

с уважением
Матиас

Радждардж
Пт 06 ноября 2015 г. 10:38 утра
Рассматриваемый энкодер находит на моем Arduino Mega ADK
(Я использовал библиотеку Encoder Clic.
https: // github.com/0xpit/encoder/tree/arduino
Я перемещаю вывод A и вывод B на 18 и 19 (PB 4, PB3), потому что они предназначены для толерантных выводов 5 В.
У доски есть свои 10 -километровые подтягивания.
но на 3.3 и 5V я вообще не получаю, с любой библиотекой или фрагментом кода.
На меге это работает отлично.

Rogerclark
Пт 06 ноября 2015 г., 19:42
5 В толерант - это не то же самое, что принятие логических уровней 5 В

Возможно, что логика низко от этого устройства только что -то вроде 1.8 В, которая будет логикой, низко на системе 5 В купить все еще высокую логику на 3.3 V Система


В этом случае я сомневаюсь, что это проблема, но поскольку эти устройства обычно механические, я не знаю, почему вы не запускаете ее с 3.3V, или альтернативно используйте сеть разделителей резисторов, чтобы правильно изменить уровни логики 5V на 3.3В

Использование периферийных устройств 5 В, по моему опыту, больше не является нормой для большинства современных MCUS.

Ахулл
Пт 06 ноября 2015 г., 19:54
Rogerclark написал:5 В толерант - это не то же самое, что принятие логических уровней 5 В
Возможно, что логика низко от этого устройства только что -то вроде 1.8 В, которая будет логикой, низко на системе 5 В купить все еще высокую логику на 3.3 V Система

Rogerclark
Пт 06 ноября 2015 г., 21:15
Я не был уверен, было ли у OP какое -либо испытательное оборудование.

Они могли бы использовать аналоговый вход, но я не уверен, что его платеж на 5 В (вероятно, нет), чтобы им понадобился разделитель напряжения

Ахулл
Сб 07 ноября 2015 г. 1:04
Rogerclark написал:Я не был уверен, было ли у OP какое -либо испытательное оборудование.

Они могли бы использовать аналоговый вход, но я не уверен, что его платеж на 5 В (вероятно, нет), чтобы им понадобился разделитель напряжения

Ахулл
Сб 07 ноября 2015 г. 1:06
Ахулл написал:Rogerclark написал:Я не был уверен, было ли у OP какое -либо испытательное оборудование.

Они могли бы использовать аналоговый вход, но я не уверен, что его платеж на 5 В (вероятно, нет), чтобы им понадобился разделитель напряжения

Саймонф
Сб 07 ноября 2015 г., 21:02
Я использовал многие из этих Caeep Rotary Encoders в качестве регулятора громкости для AMPS. Я написал небольшую библиотеку, которая утонит.
struct EncoderSetings { uint8_t PinA; uint8_t PinB; uint8_t PinC; uint8_t Min; uint8_t Max; uint8_t GreyCode; uint8_t mutePin; volatile uint8_t Val; bool GoingUp; bool GoingDown; volatile bool IsDirty; bool muted; } ; void ScanEncoder(EncoderSetings &ThsEnc) { uint8 OldGreyCode; //hostSerial.println("Reading the encoder... press a key to abort."); if (digitalRead(ThsEnc.mutePin)==LOW && !(ThsEnc.muted)){ // mute pressed ThsEnc.muted= true; ThsEnc.IsDirty = true; RotaryIsDirty = true; } { OldGreyCode = ThsEnc.GreyCode; ReadGreyCode(ThsEnc); if ( ThsEnc.GreyCode != OldGreyCode) { // "Forward" is shown by the position going from (0 to 1) or (1 to 3) // or (3 to 2) or (2 to 0). Anything else indicates that the user is // turning the device the other way. Remember: this is Gray code, not // binary. if (OldGreyCode == 3) { // Starting Rotation ThsEnc.GoingUp = ((ThsEnc.GreyCode == 1)); ThsEnc.GoingDown = ((ThsEnc.GreyCode == 2)); } else { if (ThsEnc.GreyCode == 3) { // Ending Rotation if ((ThsEnc.GoingUp) && (OldGreyCode == 2)) { if (ThsEnc.Val < ThsEnc.Max) { ThsEnc.Val++; ThsEnc.IsDirty = true; RotaryIsDirty = true; } } if ((ThsEnc.GoingDown) && (OldGreyCode == 1)) { if (ThsEnc.Val > ThsEnc.Min) { ThsEnc.Val--; ThsEnc.IsDirty = true; RotaryIsDirty = true; } } ThsEnc.GoingDown = false; // Back In the Parked Position ThsEnc.GoingUp = false; // Back In the Parked Position } } // debounce the pot // if ((ThsEnc.GreyCode!=OldGreyCode) && (OldGreyCode=3)) _delay_ms(10); if (ThsEnc.muted ) { ThsEnc.muted=false; ThsEnc.IsDirty = true; RotaryIsDirty = true; ThsEnc.GoingDown = false; // Back In the Parked Position ThsEnc.GoingUp = false; // Back In the Parked Position } } } } void SetupEncoder( uint8 Index, uint8 PinA , uint8 PinB, uint8 PinC, uint8 mutepin, uint8 Min, uint8 Max, uint8 Val ) { Rotary[Index].Min = Min; Rotary[Index].Max = Max; Rotary[Index].PinA = PinA ; Rotary[Index].PinB = PinB; Rotary[Index].PinC = PinC; Rotary[Index].mutePin = mutepin ; Rotary[Index].Val = Val ; Rotary[Index].GoingDown = false ; Rotary[Index].GoingUp = false ; Rotary[Index].IsDirty = false ; Rotary[Index].muted = false ; ResetPins(Rotary[Index]); ReadGreyCode(Rotary[Index]); } void ResetPins(EncoderSetings &ThisEncoder) { // Rotary encoder input lines // Configure as input, turn on pullup resistors pinMode(ThisEncoder.PinA , INPUT_PULLUP ); pinMode(ThisEncoder.PinB, INPUT_PULLUP ); pinMode(ThisEncoder.mutePin , INPUT_PULLUP ); pinMode(ThisEncoder.PinC, OUTPUT ); digitalWrite(ThisEncoder.PinC, LOW); } void ReadGreyCode(EncoderSetings &MyEncoder) { MyEncoder.GreyCode = ((digitalRead(MyEncoder.PinB) * 2) + digitalRead(MyEncoder.PinA)); } bool RotaryHasChanged(uint8_t &Ind) { return Rotary[Ind].IsDirty; } uint8_t ReadRotaryValue(uint8_t &Ind) { Rotary[Ind].IsDirty = false; if (Rotary[Ind].muted) return 0; else return Rotary[Ind].Val ; } void ScanAllEncoders() { for (uint8_t index = 0; index < EncoderCount; index++ ) { ScanEncoder(Rotary[index]); } } bool ARotaryHasChanged() { if (RotaryIsDirty) { RotaryIsDirty = false; return true; } else return false; }

Rogerclark
Ср 27 июня 2018 11:59
@Simonf

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

Я подозреваю, что у вас есть некоторые глобалы, которые вы не включили в пост

Если возможно, вы можете опубликовать отсутствующий код ?

Спасибо

Роджер

Дэнниф
Чт 28 июня 2018 г., 11:23
Я написал небольшую библиотеку, которая утонит. Это большой код для вождения роторного энкодера.

моя здесь: https: // github.com/dannyf00/my-mcu-libr ... Encoder1.в

Он использует государственную машину, реализованную через массив. Невероятно устойчив к отскокам - я часто использую его без какого -либо декоративного оборудования.

компилируется практически для любого MCU.

Стивестронг
Чт 28 июня 2018 г., 11:29
Этот код из @dannyf очень простой и, следовательно, эффективный код.
Единственный вопрос, в котором возникает интервал времени, при каких обстоятельствах.
Пусть достаточно назвать это в ISR, прикрепленном к Systick (E.глин. Каждый 1 мс, частота 1 кГц)?

Fredbox
Чт 28 июня 2018 г., 19:26
моя здесь: https: // github.com/dannyf00/my-mcu-libr ... Encoder1.в //determine increment / decrement of the encoder unsigned char encoder1_read(void) { static const signed char encoder_states[]={0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; ... return encoder_states[ABs]; //return the relative value (+1 = clockwise, 0, -1 = counterclockwise)

Дэнниф
Чт 28 июня 2018 г. 20:32
это зависит. Код допускает возврат либо относительного (+/- 1, или 0), либо абсолютной - часть кода.

В зависимости от ваших потребностей, вы можете включить или выключить либо.

Rogerclark
Чт 28 июня 2018 г., 21:58
Спасибо, ребята, я попробую @Dannf’S код

В идеале я надеялся избежать необходимости использовать сеть RC для оборудования.

Rogerclark
Пт 6 июля 2018 г. 10:53 утра
Наконец -то пришел к тому, чтобы посмотреть на код, Дэнниф, но, похоже, это не для STM32 ??
Похоже, это для PIC32

Zoomx
Пт, 6 июля 2018 г. 13:37
Да, я тоже верю, но, может быть...
#define ENC1_PORT PORTB //inputs on portb #define ENC1_DDR TRISB #define ENC1_A (1<<10) //rotary A on p.2 #define ENC1_B (1<<11) //rotary B on p.5

Дэнниф
Пт, 6 июля 2018 г., 14:23
Похоже, это для PIC32 Первоначально он был написан для некоторого AVR, затем PIC, а затем PIC24. Но код является агностиком платформы.

Например, если вы хотите реализовать в среде STM32Duino, просто используйте соответствующий GPIO.час/.c файлы. или жесткая карта макросов GPIO, как это:
#define IO_IN(ddr, pin) pinMode(pin, INPUT) //or with pull-up #define IO_GET(port, pin) digitalRead(pin) //read a digital pin

Дэнниф
Пт, 6 июля 2018 г., 15:08
Я должен был немного расширить.

Две строки кода здесь:
if (ENC1_PORT & ENC1_A) ABs |= 0x02; //set the 1st bit if A is high now; if (ENC1_PORT & ENC1_B) ABs |= 0x01; //set the 0th bit if B is high;

Fredbox
Пт, 6 июля 2018 г., 22:13
Является ли этот код роторного энкодера, предназначенный для использования с роторными энкодерами в стиле KY-040, которые изменяют состояния четыре раза на каждом щелчке? Когда я тестирую этот код, я получаю около четырех счетов за щелчок. 360 градусов вращения изменяют счет на примерно 80.// called from systick once per millisecond void encoder1_read(void) { volatile static const signed char encoder_states[]={0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; volatile static unsigned char ABs=0x00; //AB key read out, Previous in the high 2 bits and current in the low two bits; ABs = (ABs << 2) & 0x0f; //left 2 bits now contain the previous AB key read-out; if (digitalRead(ENC_CLK)) ABs |= 0x02; //set the 1st bit if A is high now; if (digitalRead(ENC_DATA)) ABs |= 0x01; //set the 0th bit if B is high; encoderCount += encoder_states[ABs]; }

Fredbox
Сб, 07 июля 2018 г., 2:39
Имеет смысл, что счет изменится на четыре:
ABS [0x0d], ABS [0x04], ABS [0x02], ABS [0x0b] All = 1
ABS [0x0e], ABS [0x08], ABS [0x01], ABS [0x07] All = -1

Я упростил код, чтобы проверить только на 0x0d и 0x0e для увеличения и уменьшения.
Теперь я получаю хороший устойчивый счет 1 за клик без видимого отскока. Никаких конденсаторов не требуется.// call this from the systick interrupt every millisecond // modified from the original code by dannyf // at https://github.com/dannyf00/My-MCU-Libraries---2nd-try/blob/master/encoder1.c void encoder1_read(void) { volatile static uint8_t ABs = 0; ABs = (ABs << 2) & 0x0f; //left 2 bits now contain the previous AB key read-out; ABs |= (digitalRead(ENC_CLK) << 1) | digitalRead(ENC_DATA); switch (ABs) { case 0x0d: encoderCount++; break; case 0x0e: encoderCount--; break; } }

Пито
Сб -7 июля 2018 г. 8:06 утра
@fredbox&Дэнниф: Есть 2 вида кодеров (см. Ниже). Может быть, добавление второй версии Encoder (1/4 One) создаст «Ultimate Encoder Solution» : идея:
Encoders.jpg
Энкодеры.JPG (33.31 киб) просмотрено 357 раз

Rogerclark
Сб -7 июля 2018 г. 8:14 утра
У моих кодеров, кажется, никогда не связаны с a или b с GND, в устойчивом состоянии.

я.e Если я измеряю энкодер с настройкой сопротивления на мультимере, ни A, ни B не подключены к среднему штифту.

Если я прикрепляю ISR к падающему краю выхода A и прочитаю значение выхода B, направление вращения определяется либо B, подключенным к GND или нет

Я не уверен, что я неправильно подключил энкодер, как я предполагал, что средний штифт был общим / GND -штифтом и Overt, где вывод A и B

В любом случае.
Я использую оборудование дебаун, и это хорошо работает.

Пито
Сб -7 июля 2018 г. 8:24 утра
[Rogerclark - СЕД 7 июля 2018 г., 8:14] - У моих кодеров, кажется, никогда не связаны с a или b с GND, в устойчивом состоянии.
Это полный тип цикла/стока (см. Рисунок выше, «Открыто в стабильном состоянии»).

Если вы подключите 2 резисторы подтягивания (то есть 10K), он будет читать «1» в обоих в устойчивом состоянии (в целе, но есть кодеры без задержанных, они вращаются «плавно»). В то время как приращение (CW/CCW) он пройдет через «O» и вернется к «1» в устойчивом состоянии.

Тип 1/4 останется в «1» или «0» в целеустремленном зачете на основе фактической позиции.

Rogerclark
Сб -7 июля 2018 г. 8:57 утра
@pito

Спасибо

Я использую 10K и 220NF (вероятно, может использовать 100NF), с резисторами как на зарядке, так и на стороне разряда энкодера.

Кажется, очень надежно работает только с одним ISR и чтением другой вывод.

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

Дэнниф
SAT 07 июля 2018 12:37
Будучи государственным подходом на основе обработки, код очень устойчив к отскокам. Я часто запускаю его голым, без какого -либо программного / оборудования Debouncer - не рекомендуется. Из двух, мой любимый оборудование на основе RC Debouncer-.

Тем не менее, будьте осторожны, что типичные дебаунсеры 1R+1C могут сбросить сброс в сочетании с хорошим переключателем / кодером. Если это произойдет, поместите туда небольшой серийный резистор, чтобы разграничить ток разгрузки.

Для дебюра программного обеспечения Kuhn Debouncer очень хорош для его простоты: https: // dannyelectronics.WordPress.ком/ ... Дебюн/

о 1/4 приращениях против. 1/1 приращения, одна из частей кода, связанных ранее, имеет такие функции. Но модификация Fredfox тоже очень хороша.

Fredbox
Сб, 07 июля 2018 г., 16:26
Энкодеры, которые у меня есть, установлены на печатной плате с подтягивающими резисторами. Поиск модуля KY-040 на ALI или eBay. Они недороги (5 шт. За 2 доллара.50 США).

Есть хорошее обсуждение дебауна на Hackaday (включая метод Куна) в https: // chackaday.com/2015/12/09/Enced-W ... NS-Part-I/ и https: // chackaday.com/2015/12/10/interd-w ... S-Part-II/.

Я использую список "test_for_press_only" в конце части II, чтобы прочитать кратковременный переключатель кнопки на энкодере и маленькие тактильные переключатели.

Пито
Сб, 7 июля 2018 г., 17:44
К вашему сведению - я использую эти бурны

https: // www.бурнс.com/продукты/энкодер ... Roduct/ECW

Они стоили мне 5 долларов каждый около Y2K. Получил их с затратом и без, 1Cycle, 1/4 и т. Д. В то время испортился с DDS VFO, поэтому я сделал инвестиции :рулон: (Кстати, я видел это в разрыве OSCO DSO DSO, так что, возможно, они будут длиться долго..).

Какова другая особенность реализации с помощью библиотеки Ultimate Rotary Encoder, - это «ускорение» - когда вы поворачиваете ручку быстрее, чем обычно, приращения начинают расти в геометрической прогрессии (т.е. 2, 4, 8, 16.. На основе угловой скорости и/или продолжительности быстрого «удара»).

Таким образом, с медленным вращением, вы увеличиваете/уменьшаются на 1, с более быстрым поворотом вы можете сделать «тысячи». У меня есть это в моих старых VFO, но это древний код ASM PIC16, не заслуживающий. Он работает нормально, я могу набрать смену XMHZ с несколькими быстрыми ударами ручки с 1 кГц "медленной" ступенькой или десятками кГц со ступеньком 1 Гц..

PS: «Ускоренный вход» может быть сделан, например, путем измерения «истешенного миллиса, в то время как входы a и b incoder incr/уменьшение», и каждый «xnumber_of_elapsed_millis» удваивает шаг INCR/уменьшение, пока Millis2Millis изменится на и B.

Rogerclark
Sun 8 июля 2018 г. 2:55 утра
Я использую свой для управления VFO, но я подозреваю, что мне нужно заменить эти дешевые механические версии на более высокие версии производительности (возможно, у этого нет шагов), он работает нормально в целевом радио
(Это не мое радио, это чье -то другое, поэтому я даже не узнаю, работает ли оно, пока я не отправлю его им для тестирования, но это работает на моем испытательном стенде)

Дэнниф
Sun 8 июля 2018 г. 10:47 утра
Попробуйте эти оптические энкодеры, как правило, для чувства скорости на двигателях. Нетрудно найти 512/1024 PPR.

Modbus Master and Slave на STM32F103 и Uno