Димер, енкодер, олед дисплей
- Войдите на сайт для отправки комментариев
Всех приветствую, весь день бьюсь, с попыткой подружить димер и олед дисплей, по одельности работает каждый с Nano и енкодером, но вот вместе отказываются, без олед дисплея вывожу в сериал значение с эенкодера меняется, сохраняется и димер выдает нужное напряжение, без димера енкодером меняю значение на олед дисплее все меняеться сохраняется отображается, когда соединяется все вместе результат такой: дисплей не отображает не чего, димер не пропускает не чего, но если убрать контакт от димера для отслеживания 0 и ресетнуть ардуину дисплей включится, подсоединяем проводок обратно, димер тоже работает , НО только когда я меняю значение енкодером он стабильно пропускает напряжение, как только я сохранил параметр появляются скачки 30% от установленного значения, посмотрел библиотеки не одна с другой не связаны общими какими то обращениями к чему либо, прошу подсказки кто кому мешает.
дисплей вот этот
подключен SCK на A5 ; SDA на A4
енкодер вот этот
кнопка на D4 пины поворота на D5 и D6
димер вот этот
шим беру для димера с D9, сигнал с димера для отслеживания прохождения через ноль на D3 подключен (подключал и на D2) на оба пина что имеют прерывание пробовал
вот енкодер и диммер
#include <CyberLib.h> #define dimPin 9 #define zeroPin 3 volatile int tic, Dimmer; #include <GyverEncoder.h> #define CLK 5 //S2 #define DT 6 //S1 #define SW 4 //key Encoder enc1(CLK, DT, SW); #include <EEPROM.h> byte speedmotor = 0; void setup() { Serial.begin(9600); enc1.setType(TYPE2); pinMode(dimPin, OUTPUT); digitalWrite(dimPin, 0); pinMode(zeroPin, INPUT); // настраиваем порт на вход для отслеживания прохождения сигнала через ноль attachInterrupt(1, detect_up, FALLING); // настроить срабатывание прерывания interrupt1 на pin 3 на низкий уровень StartTimer1(timer_interrupt, 40); // время для одного разряда ШИМ StopTimer1(); // остановить таймер EEPROM.get(1, speedmotor); Serial.println("Start"); } void loop() { enc1.tick(); if (enc1.isTurn()) { if (enc1.isRight()) {// если был поворот if (speedmotor < 100){ speedmotor+=1; } Serial.println("Speed = " + String(speedmotor)); } if (enc1.isLeft()) { if (speedmotor > 0){ speedmotor-=1; } Serial.println("Speed = " + String(speedmotor)); } } if(enc1.isHolded()){ EEPROM.put(1, speedmotor); Serial.println("Save"); } Dimmer = map(speedmotor, 0, 100, 240, 0); } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- void timer_interrupt() { // прерывания таймера срабатывают каждые 40 мкс tic++; // счетчик if (tic > Dimmer) // если настало время включать ток digitalWrite(dimPin, 1); // врубить ток } void detect_up() { // обработка внешнего прерывания на пересекание нуля снизу tic = 0; // обнулить счетчик ResumeTimer1(); // перезапустить таймер attachInterrupt(1, detect_down, RISING); // перенастроить прерывание } void detect_down() { // обработка внешнего прерывания на пересекание нуля сверху tic = 0; // обнулить счетчик StopTimer1(); // остановить таймер digitalWrite(dimPin, 0); // вырубить ток attachInterrupt(1, detect_up, FALLING); // перенастроить прерывание } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
вот диплей и енкодер
// пины энкодера #define CLK 5 #define DT 6 #define SW 4 #include "GyverEncoder.h" Encoder enc1(CLK, DT, SW); byte flagmenu = 0; #include <OLED_I2C.h> OLED oled(SDA, SCL); extern uint8_t SmallFont[]; extern uint8_t BigNumbers[]; byte speedmotor = 0; byte oborot = 50; unsigned long millist; #include <EEPROM.h> void setup() { Serial.begin(9600); oled.begin(); oled.setFont(SmallFont); enc1.setType(TYPE2); EEPROM.put(1, speedmotor); } void loop() { enc1.tick(); if ( enc1.isSingle()){ // если было нажатие EEPROM.get(1, speedmotor); flagmenu += 1; if(flagmenu > 1) { flagmenu = 0; } oledd(); millist=millis(); } if (enc1.isTurn()) {// если был поворот if (flagmenu == 1){ if (enc1.isRight()) { if(speedmotor<100){ speedmotor+= 5; } } if (enc1.isLeft()){ if(speedmotor>0){ speedmotor-= 5; } } } oledd(); millist=millis(); } if(enc1.isHolded()){ EEPROM.put(1, speedmotor); oled.clrScr(); oled.setFont(SmallFont); oled.print("SAVE", CENTER, 30); oled.update(); } if(millis()-millist>=5000) { flagmenu = 0; oledd(); } // Dimmer = map(speedmotor, 0, 100, 240, 0); } void oledd(){ oled.clrScr(); if( flagmenu == 0){ oled.setFont(SmallFont); oled.print("Oborot", LEFT, 10); oled.setFont(BigNumbers); oled.print(String(oborot), RIGHT, 1); oled.setFont(SmallFont); } else if(flagmenu == 1){ oled.setFont(SmallFont); oled.print("Motor", LEFT, 40); oled.setFont(BigNumbers); oled.print(String(speedmotor), RIGHT, 30); } oled.update(); }
а вот я собираю все вместе и получаю ничего
#define CLK 5 #define DT 6 #define SW 4 #include "GyverEncoder.h" Encoder enc1(CLK, DT, SW); byte flagmenu = 0; #include <CyberLib.h> #define dimPin 9 #define zeroPin 3 volatile int tic, Dimmer; #include <OLED_I2C.h> OLED oled(SDA, SCL); extern uint8_t SmallFont[]; extern uint8_t BigNumbers[]; byte speedmotor = 0; byte oborot = 50; unsigned long millist; #include <EEPROM.h> void setup() { Serial.begin(9600); oled.begin(); oled.setFont(SmallFont); enc1.setType(TYPE2); pinMode(dimPin, OUTPUT); digitalWrite(dimPin, 0); pinMode(zeroPin, INPUT); // настраиваем порт на вход для отслеживания прохождения сигнала через ноль attachInterrupt(1, detect_up, FALLING); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень StartTimer1(timer_interrupt, 40); // время для одного разряда ШИМ StopTimer1(); // остановить таймер EEPROM.put(1, speedmotor); } void loop() { enc1.tick(); if ( enc1.isSingle()){ // если было нажатие EEPROM.get(1, speedmotor); flagmenu += 1; if(flagmenu > 1) { flagmenu = 0; } oledd(); millist=millis(); } if (enc1.isTurn()) {// если был поворот if (flagmenu == 1){ if (enc1.isRight()) { if(speedmotor<100){ speedmotor+= 5; } } if (enc1.isLeft()){ if(speedmotor>0){ speedmotor-= 5; } } } oledd(); millist=millis(); } if(enc1.isHolded()){ EEPROM.put(1, speedmotor); oled.clrScr(); oled.setFont(SmallFont); oled.print("SAVE", CENTER, 30); oled.update(); } if(millis()-millist>=5000) { flagmenu = 0; oledd(); } Dimmer = map(speedmotor, 0, 100, 240, 0); } void oledd(){ oled.clrScr(); if( flagmenu == 0){ oled.setFont(SmallFont); oled.print("Oborot", LEFT, 10); oled.setFont(BigNumbers); oled.print(String(oborot), RIGHT, 1); oled.setFont(SmallFont); } else if(flagmenu == 1){ oled.setFont(SmallFont); oled.print("Motor", LEFT, 40); oled.setFont(BigNumbers); oled.print(String(speedmotor), RIGHT, 30); } oled.update(); } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- void timer_interrupt() { // прерывания таймера срабатывают каждые 40 мкс tic++; // счетчик if (tic > Dimmer) // если настало время включать ток digitalWrite(dimPin, 1); // врубить ток } void detect_up() { // обработка внешнего прерывания на пересекание нуля снизу tic = 0; // обнулить счетчик ResumeTimer1(); // перезапустить таймер attachInterrupt(1, detect_down, RISING); // перенастроить прерывание } void detect_down() { // обработка внешнего прерывания на пересекание нуля сверху tic = 0; // обнулить счетчик StopTimer1(); // остановить таймер digitalWrite(dimPin, 0); // вырубить ток attachInterrupt(1, detect_up, FALLING); // перенастроить прерывание } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
Еще нашел что если убрать таймер на millis который возвращает из меню если не трогаешь енкодер то проблема пропадает, т.е. этот чсетчик связан с таймером в обработке димера
Скорее всего вот это систему долбит и ничего делать не даёт:
if
(millis()-millist>=5000) {
flagmenu = 0;
oledd();
}
это я нашел , только не понимаю как тормозит исполнение кода, это же не delay
Так уберите, чтобы не тормозило. Зачем он нужен?
Сейчас что бы возвращал из поля настроек, затем все равно таймер нужен будет для дальнейшей программы
Попробуй в начале loop() какой-нибудь переменной присваивать текущее значение миллис, а не вызывать его постоянно. Не факт, что поможет. Но ты попробуй.
Сейчас что бы возвращал из поля настроек, затем все равно таймер нужен будет для дальнейшей программы
Тогда найдите разницу между своим фрагментом кода и правильным: http://arduino.ru/tutorials/BlinkWithoutDelay
Сейчас что бы возвращал из поля настроек
"возвращаться из настроек" нужно один раз, а у вас это происходит бесконечно, сотни и тысячи раз. Поэтому все и тормозит, что контроллер занят только "возвратами из настроек".
Добавьте в программу переменную-флаг, которая будет показывать, в настроках вы или нет. Если да и прошло время таймера - значит делаем возврат. И СБРАСЫВАЕМ ФЛАГ, чтобы возврат происходил один раз.
Когда следующий раз входим в настройки - устанавливаем флаг снова.
Ну не постоянно, каждые 5 секунд так то...
Сейчас что бы возвращал из поля настроек, затем все равно таймер нужен будет для дальнейшей программы
Тогда найдите разницу между своим фрагментом кода и правильным: http://arduino.ru/tutorials/BlinkWithoutDelay
спасибо за ссылку посмотрел, нашел одно различие, исправил
добавил флаг нахождения в меню
не спасло
Ну не постоянно, каждые 5 секунд так то...
а почему каждые 5 секунд то, возврат происходит один раз, потому что
присваивается только после нажатия или поворота, в другом случае условие
не будет выполняться же и соответственно возврата не будет
Как связано то что пока я нахожусь в меню, выбора оборотов , изменяю их , сохраняю их, его работа стабильна, но как только выход из настройки на экран где отображаться должны реальные обороты сразу же начинается скачки
Ну не постоянно, каждые 5 секунд так то...
Ошибочка вышла, конечно же не каждые 5 секунд, а постоянно!
millist = mymillis;
присваивается только после нажатия или поворота, в другом случае условие
не будет выполняться же и соответственно возврата не будет
Фигово у тебя с логикой. Давай считать вместе. Пусть millis() вернет 15 и это значение сохранится в millist. Программа выполняется и вот миллис натикал уже 21. Тогда условие:
Примет вид:
и выполнится! Так? Ну а дальше millis() будет только расти, например, оно дойдет до значения 55. По твоему (55 - 15) больше или меньше 5? Считаем: 55 - 15 = 40 > 5. Ну и так далее, на каждом проходе цикла это условие будет выполняться ПОСТОЯННО. Ну и сбрасываться, если нажали кнопку или повернули энкодер.
millist = mymillis;
присваивается только после нажатия или поворота, в другом случае условие
не будет выполняться же и соответственно возврата не будет
Фигово у тебя с логикой. Давай считать вместе. Пусть millis() вернет 15 и это значение сохранится в millist. Программа выполняется и вот миллис натикал уже 21. Тогда условие:
Примет вид:
и выполнится! Так? Ну а дальше millis() будет только расти, например, оно дойдет до значения 55. По твоему (55 - 15) больше или меньше 5? Считаем: 55 - 15 = 40 > 5. Ну и так далее, на каждом проходе цикла это условие будет выполняться ПОСТОЯННО. Ну и сбрасываться, если нажали кнопку или повернули энкодер.
спасибо я идиот, а я ведь каждый шаг кода просмотрел уже не один раз, не заметил что значение то будет расти
спасибо я идиот, а я ведь каждый шаг кода просмотрел уже не один раз, не заметил что значение то будет расти
теперь еще раз проверьте, как вы добавили флаг входа в настройки. Правильно добавленный флаг решит вашу проблему.
спасибо я идиот, а я ведь каждый шаг кода просмотрел уже не один раз, не заметил что значение то будет расти
теперь еще раз проверьте, как вы добавили флаг входа в настройки. Правильно добавленный флаг решит вашу проблему.
так и сделал, еще до вашего сообщения и да спасло моё полождение, вся ошибка была в моей невнимательности
Итог то будет? Работает?
Итог то будет? Работает?
уехал на работу, закончилось на том что скачок напряжения есть одинарный, раз в 9 секунд, как будет вести себя мотор пока не понятно, но явно это не правильно как вернусь буду искать дальше