В самом устройстве ничего особенного нет, но вот энкодер на 5000 имп/об. и при примерно 1200 имп/сек происходит сбой и ардуина в лучшем случае перестает считать импульсы с энкодера (но чаще начинает отсчитывать в обратную сторону). Есть ли программное решение данной проблемы или просто не хватает производительности? Помогите пожалуйста с решением данной проблемы. Код (C++): #include <SPI.h> enum { reg = 8 }; #define pinB 3 long g=0; void setup() { // Serial.begin(9600); SPI.begin(); pinMode(reg, OUTPUT); attachInterrupt(0, encoder1, FALLING); } long i=0; long a=0; long b=0; long c=0; long d=0; long e=0; long f=0; int delayTime=1; //коды цифр на семисегментнике (0-9 и пустота) static uint8_t digit[11] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; // коды позиций зажигаемого семисегментника (слева на право) static uint8_t pos[6]= {0xBF,0xDF,0xEF,0xF7,0xFB,0xFD}; void loop() { if (g>999995 || g<-999995) g=0; if (g < 0) { i=g-g*2; } else { i=g; } a=i/100000; b=(i-a*100000)/10000; c=(i-a*100000-b*10000)/1000; d=(i-a*100000-b*10000-c*1000)/100; e=(i-a*100000-b*10000-c*1000-d*100)/10; f=i-a*100000-b*10000-c*1000-d*100-e*10; if (a==0) a=10; if (a==10 && b==0)b=10; digitalWrite(reg, LOW); SPI.transfer(0x80); SPI.transfer(pos[2]); digitalWrite(reg, HIGH); delay(delayTime); digitalWrite(reg, LOW); SPI.transfer(digit[a]); SPI.transfer(pos[0]); digitalWrite(reg, HIGH); delay(delayTime); digitalWrite(reg, LOW); SPI.transfer(digit[b]); SPI.transfer(pos[1]); digitalWrite(reg, HIGH); delay(delayTime); digitalWrite(reg, LOW); SPI.transfer(digit[c]); SPI.transfer(pos[2]); digitalWrite(reg, HIGH); delay(delayTime); digitalWrite(reg, LOW); SPI.transfer(digit[d]); SPI.transfer(pos[3]); digitalWrite(reg, HIGH); delay(delayTime); digitalWrite(reg, LOW); SPI.transfer(digit[e]); SPI.transfer(pos[4]); digitalWrite(reg, HIGH); delay(delayTime); digitalWrite(reg, LOW); SPI.transfer(digit[f]); SPI.transfer(pos[5]); digitalWrite(reg, HIGH); delay(delayTime); } void encoder1() { if (digitalRead(pinB)) { g=g+5; } else { g=g-5; } }
Почему "или"? Решение нехватки производительности - более производительная программа. На чистом C под чистый AVR, без ардуино-прибабахов..
Как вообще можно было додуматься считывать импульсы где то там в теле без конечного цикла...еще и промышленный. Учите С ..... и с помощью ISR (INT0_vect) считайте....
Проблема в дребезге. Если посмотреть анализатором или осциллографом, то можно заметить, что вместо одного FALLING при одном щелчке энкодера их там несколько, и все будут обработаны прерыванием. Что нужно сделать? Проще всего добавить аппаратный антидребезг в виде игнорирования сработок чаще, скажем, 1 раза в миллисекунду. Или опрашивать ножку принудительно раз в миллисекунду вместо прерывания. Производительности на эту задачу хватит даже с ардуиновскими прибабахами.
По всей видимости вы не только сообщение не читали, но и в код не заглядывали: 1.Не может быть дребезга у промышленых энкодеров 2.К ардуине подключены пара сдвиговых регистров и 6 семисегментников, а ваш вариант и простейший энкодер в такой ситуации не считает. Ну вот и идите на специализированные форумы и там умничайте, а тут люди задают вопросы на которые ответ "иди учи чистый С" выгядит не просто глупо, но и невежественно. Модерам за такое уже б пара и банить.
А почему бы вам не пойти на специализированные форумы для сильно образованных и наглых? Вы явно сюда пришли не решать проблему, а характер продемонстрировать. Второе сообщение, а уже и правила свои установил, и модерами командует, каков молодец.
Промышленные энкодеры НЕ ГЛЮЧАТ! Идут как правило со своим шнурком... экранированным. Как правило предназначены для непосредственного подключения без промежуточных соединений. 5000 импульсов на оборот - это очень... ну уж очень круто. Прерывание и никак иначе... лучше конечно "аппаратная" логика Сам применял 360 импульсов на оборот. Правда скорость оборотов у меня.... ограничение 50 КГц у счётчика (СИ30 от ОВЕН). В вашем случае 1 оборот в секунду = 5 Кгц. Так часто будет прерывание для контрллера, в котором по наличию второго уровня (импульса) от энкодера надо ещё определить направление... это не считая сохранения и восстановления регистров при входе и выходе в/из прерывания. Ещё время реакции на прерывание. Очень жирно! Но уж очень если вы ещё что-то делаете в программе. Прерывание уже есть - простите не доглядел.
Я не понял, как связан энкодер со сдвиговыми регистрами? Мой вариант считывает любые энкодеры, я делал это минимум тремя способами и все работают. В последнее время, я выделяю под обработку энкодера отдельный МК (кстати, писал об этом на форуме с видео), который передает на главный МК готовые результаты освобождая его от этой работы, соответственно пропусков и ошибок практически нет. Частоту опроса подбирал опытным путем и по данным с анализатора, решил, что 1-2 мс самое то. И наконец, вы взяли на веру, что промышленные энкодеры (и конкретно ваш) не дребезжат или таки не поленились и убедились в этом при помощи осциллографа?
Подключил к оптике 250 имп/мм, на скорости 6м/мин полет нормальный. Если кто захотит повторить, семисегментники в коде с общим катодом Q0-A Q1-B Q2-C и т.д. (Q7-точка) Себистоимость УЦИ вышла примерно 400р. без учета стоимости индикаторных линеек. Косяк был в недостаточном питании энкодера