Стробоскоп на Nano

Aiden_ko

✩✩✩✩✩✩✩
12 Ноя 2022
2
0
Добрый день.

Сделал стробоскоп регулируемый на основе Ардуино Нано, за основу взял эту статью http://cyber-place.ru/showthread.php?t=2703

Но решил прикрутить к схеме экран (обычный, двухстрочный на 16 символов) по шине I2c. Строб работает, на экран идет информация. НО! В скетче, который использует автор, энкодер, как я понимаю, обрабатывается прерыванием, на это время моргает экран.

Более того, частота "проседания" экрана зависит от частоты включения светодиода, на частоте около 1 кГц экран обновляется заметно "слоями". На 10 кГц на экран можно смотреть просто как на светильник, толку с него нет.

Вопрос, можно как-то управлять высокочастотной импульсной нагрузкой так, что бы экран отражал все не зависимо от пульсаций нагрузки?

Схему включения прилагаю.
 

Вложения

poty

★★★★★★✩
19 Фев 2020
3,237
942
А скетч?
Что должно выводиться на экран? И зачем его обновлять так часто, что он интерферирует с обработкой энкодера и стробами? Вывод на экран - довольно затратная операция и, судя по I2C, может быть блокирующей. Обработка энкодера, если он завязан на прерывания, должна осуществляться не в самом прерывании, иначе возникает блокировка других функций. При частом прерывании (10кГц), если оно осуществляется не с помощью аппаратного таймера, большая часть тактов процессора будет занята обработкой процессов в прерывании.
Короче, здесь нужно реально оценить тайминги всех процессов.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,974
633
45
Я бы сделал по таймеру прерывание в котором делать включение/выключение строба, а уже в основном цикле делать обработку энкодера и дисплея. Но это при условии, что атмега позволяет динамически менять частоту таймера во время работы. Если не умеет, то можно перезапускать таймер при изменении частоты.
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
@Геннадий П, а зачем обрабатывать таймер процессором? Подключить управляющие цепи светодиода к выводу, поддерживающему ШИМ, запрограммировать таймер на toggle и всё. Частота таймера может изменяться во время работы.
Но здесь, я думаю, типичная ошибка новичка: засунуть всю обработку в прерывание.
 

Aiden_ko

✩✩✩✩✩✩✩
12 Ноя 2022
2
0
Именно так, я понял ошибку, обработка экрана в прерывании энкодера ) Спасибо за подталкивание в нужную сторону )

Иногда шаг вперед может быть результатом пинка под зад ))))

Вот скетч, доработанный мной, в нем не было изначально LCD.

C++:
//Скетч от Cyber-Place.ru

// Выводы ЭНКОДЕРА
#define CLK 3  // Clock Подключаем к INT1, нельзя переназначать
#define DT 4  // второй вывод энкодера
#define SW 5  // switch кнопка энкодера

#define Min 1 // минимальное значение
#define Max 20000 //максимальное значение
#define led_pin 12        // подключен светодиод
#define coil_pin A0

#define step_freq 1       // шаг изменения частоты плавно 0,1гц
#define step_timelght 100 // шаг приращивания в мкс
volatile float freq = 250; // частота в Гц умноженная на 10, для более плавной настройки
volatile float freqDisp; // частота в Гц Для отображения на дисплее
volatile uint32_t paus, time_light=2000; // время свечения светодиода в мкс
uint32_t oldcount;
boolean DT_last; // последнее состояние энкодера
//Screen
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей


void setup() 
{
  Serial.begin(9600);
  lcd.init();                     
  lcd.backlight();// Включаем подсветку дисплея
  pinMode(CLK,INPUT_PULLUP); // Clock Подключаем к INT1, нельзя переназначать
  pinMode(DT, INPUT_PULLUP); // второй вывод энкодера
  pinMode(SW, INPUT_PULLUP); // кнопка энкодера
  pinMode(led_pin, OUTPUT);    // управление симистором
  pinMode(coil_pin, OUTPUT);

  attachInterrupt(1, encoderTick, CHANGE); // прерывания от Энкодера
 
  DT_last = digitalRead(CLK);         // считываем положение CLK
}

void loop()
{
    
    lcd.clear();
    
    lcd.setCursor(0,0);
    lcd.print("FREQ: ");
    lcd.setCursor(0,1);
    lcd.print("LIGH: ");

    freqDisp=freq/10;
    lcd.setCursor(5,0);
    lcd.print(freqDisp, 1);
    lcd.setCursor(5,1);
    lcd.print(time_light);
    
    paus=5000000/freq;
    digitalWrite(coil_pin, 1);
    digitalWrite(led_pin, 1);
    
    oldcount = micros();
    while( (micros() - oldcount) < time_light){}   // длительность импульса выдержки         
    digitalWrite(led_pin, 0);
    while( (micros() - oldcount) < paus){}  // положительный полупериод
    digitalWrite(coil_pin, 0);
    
    oldcount = micros();
    while( (micros() - oldcount) < paus){} //отрицательный полупериод
}

//********************обработчики прерываний Энкодера*******************************
void encoderTick()     // Обратка прерываний от Энкодера
{
  uint8_t DT_now = digitalRead(CLK);       // считываем текущее положение CLK
 
  if (DT_now != DT_last && digitalRead(SW))   // если предыдущее и текущее положение не равны, значит был поворот
  {                     
    if (digitalRead(DT) != DT_now)    // если DT не равен CLK, значит вращение по часовой стрелке
    {                             
      if( freq < Max ) freq += step_freq;    // прибавить
    } else {                                   // если DT равен CLK, значит вращение против часовой
             if( freq > Min ) freq -= step_freq;  // убавить           
            }
  } else
          if (DT_now != DT_last && !digitalRead(SW)) //если нажата кнопка и было вращение
          {
           if (digitalRead(DT) != DT_now)         // если DT не равен CLK, значит вращение по часовой стрелке
            {                             
              if( time_light < paus ) { time_light += step_timelght; } // убавить длительность           
            } else  if( time_light > 0 ) time_light -= step_timelght;    // прибавить длительность импульса выдержки/
          }
          
  DT_last = DT_now;                   // сохранить положение CLK для следующей проверки
}
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
@Aiden_ko, честно сказать - плохо ориентируюсь в современных обучающих материалах. Обычно беру datasheet и делаю по нему. Или использую библиотеку, если нужно "прям вчера". У Гайвера есть библиотека и куча статей (здесь, здесь, здесь), там, вроде, есть все механизмы, которые Вам нужны.
Скетч посмотрю, как будет время. Возможно кто-то ещё подтянется.