Димер, енкодер, олед дисплей

shamsing
Offline
Зарегистрирован: 17.06.2014

Всех приветствую, весь день бьюсь, с попыткой подружить димер и олед дисплей, по одельности работает каждый с 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);   // перенастроить прерывание
}
//----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------

 

shamsing
Offline
Зарегистрирован: 17.06.2014

Еще нашел что если убрать таймер на millis который возвращает из меню если не трогаешь енкодер то проблема пропадает, т.е. этот чсетчик связан с таймером в обработке димера 

sadman41
Offline
Зарегистрирован: 19.10.2016

Скорее всего вот это систему долбит и ничего делать не даёт:

  if(millis()-millist>=5000) {
    flagmenu = 0;
    oledd();
  }

 

shamsing
Offline
Зарегистрирован: 17.06.2014

это я нашел , только не понимаю как тормозит исполнение кода, это же не delay 

sadman41
Offline
Зарегистрирован: 19.10.2016

Так уберите, чтобы не тормозило. Зачем он нужен?

shamsing
Offline
Зарегистрирован: 17.06.2014

Сейчас что бы возвращал из поля настроек, затем все равно таймер нужен будет для дальнейшей программы 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Попробуй в начале loop() какой-нибудь переменной присваивать текущее значение миллис, а не вызывать его постоянно. Не факт, что поможет. Но ты попробуй.

loop () {
  mymillis = millis();
//.....
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

shamsing пишет:

Сейчас что бы возвращал из поля настроек, затем все равно таймер нужен будет для дальнейшей программы 

Тогда найдите разницу между своим фрагментом кода и правильным: http://arduino.ru/tutorials/BlinkWithoutDelay

b707
Offline
Зарегистрирован: 26.05.2017

shamsing пишет:

Сейчас что бы возвращал из поля настроек

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

Добавьте в программу переменную-флаг, которая будет показывать, в настроках вы или нет. Если да и прошло время таймера - значит делаем возврат. И СБРАСЫВАЕМ ФЛАГ, чтобы возврат происходил один раз.

Когда следующий раз входим в настройки - устанавливаем флаг снова.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Ну не постоянно, каждые 5 секунд так то...

shamsing
Offline
Зарегистрирован: 17.06.2014

sadman41 пишет:

shamsing пишет:

Сейчас что бы возвращал из поля настроек, затем все равно таймер нужен будет для дальнейшей программы 

Тогда найдите разницу между своим фрагментом кода и правильным: http://arduino.ru/tutorials/BlinkWithoutDelay

спасибо за ссылку посмотрел, нашел одно различие, исправил

shamsing
Offline
Зарегистрирован: 17.06.2014

добавил флаг нахождения в меню 

if (flagmenu == 1){
      
      if (enc1.isRight()) {
        if(speedmotor<100){
          speedmotor+= 5;
        }         
      }
      if (enc1.isLeft()){
        if(speedmotor>0){ 
          speedmotor-= 5;
        }
      }
      flag = 1;
    }
if(flag == 1){
    if(mymillis - millist > 5000) {
      flagmenu = 0;
      oledd();
      flag == 0;
    }
  }

 

не спасло 

shamsing
Offline
Зарегистрирован: 17.06.2014

BOOM пишет:

Ну не постоянно, каждые 5 секунд так то...

а почему каждые 5 секунд то, возврат происходит один раз, потому что 

millist = mymillis;

 присваивается только после нажатия или поворота, в другом случае условие 

if(mymillis - millist > 5000) {

не будет выполняться же и соответственно возврата не будет

shamsing
Offline
Зарегистрирован: 17.06.2014

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

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

BOOM пишет:

Ну не постоянно, каждые 5 секунд так то...

Ошибочка вышла, конечно же не каждые 5 секунд, а постоянно!

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

shamsing пишет:

millist = mymillis;

 присваивается только после нажатия или поворота, в другом случае условие 

if(mymillis - millist > 5000) {

не будет выполняться же и соответственно возврата не будет

Фигово у тебя с логикой. Давай считать вместе. Пусть millis() вернет 15 и это значение сохранится в millist. Программа выполняется и вот миллис натикал уже 21. Тогда условие:

if(millis() - millist  >  5) {
 // выполняем 
}

Примет вид:

if( 21 - 15  >  5) {  // выполнится, так как 6 > 5
 // выполняем 
}

и выполнится! Так? Ну а дальше millis() будет только расти, например, оно дойдет до значения 55. По твоему (55 - 15) больше или меньше 5? Считаем: 55 - 15 = 40 > 5. Ну и так далее, на каждом проходе цикла это условие будет выполняться ПОСТОЯННО. Ну и сбрасываться, если нажали кнопку или повернули энкодер.

shamsing
Offline
Зарегистрирован: 17.06.2014

BOOM пишет:

shamsing пишет:

millist = mymillis;

 присваивается только после нажатия или поворота, в другом случае условие 

if(mymillis - millist > 5000) {

не будет выполняться же и соответственно возврата не будет

Фигово у тебя с логикой. Давай считать вместе. Пусть millis() вернет 15 и это значение сохранится в millist. Программа выполняется и вот миллис натикал уже 21. Тогда условие:

if(millis() - millist  >  5) {
 // выполняем 
}

Примет вид:

if( 21 - 15  >  5) {  // выполнится, так как 6 > 5
 // выполняем 
}

и выполнится! Так? Ну а дальше millis() будет только расти, например, оно дойдет до значения 55. По твоему (55 - 15) больше или меньше 5? Считаем: 55 - 15 = 40 > 5. Ну и так далее, на каждом проходе цикла это условие будет выполняться ПОСТОЯННО. Ну и сбрасываться, если нажали кнопку или повернули энкодер.

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

b707
Offline
Зарегистрирован: 26.05.2017

shamsing пишет:

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

теперь еще раз проверьте, как вы добавили флаг входа в настройки. Правильно добавленный флаг решит вашу проблему.

shamsing
Offline
Зарегистрирован: 17.06.2014

b707 пишет:

shamsing пишет:

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

теперь еще раз проверьте, как вы добавили флаг входа в настройки. Правильно добавленный флаг решит вашу проблему.

так и сделал, еще до вашего сообщения и да спасло моё полождение, вся ошибка была в моей невнимательности

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Итог то будет? Работает?

shamsing
Offline
Зарегистрирован: 17.06.2014

BOOM пишет:

Итог то будет? Работает?

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