1

Тема: VU meter + oled 0.96'

http://forum.rcl-radio.ru/uploads/images/2022/08/0fb0df97983b79c2044776b7a42f9687.png


#include <Wire.h> 
#include <OLED_I2C.h>           // http://rcl-radio.ru/wp-content/uploads/2022/01/OLED_I2C.zip

#define GAIN      100
#define STEP      3
#define LOW_SOUND 100
#define MAX_SOUND 600

  OLED  myOLED(SDA, SCL, 8);
  extern uint8_t SmallFont[];
  int strela=-45;
  int hMeter = 65;                      
  int vMeter = 85;                      
  int rMeter = 80;
  int ur,urr;
  unsigned long times;
  

void setup() {
  Serial.begin(9600);
  Wire.begin();Wire.setClock(400000L);
  myOLED.begin();
  myOLED.setBrightness(100);
  //  myOLED.invert(true);// invert
  myOLED.clrScr();
  myOLED.setFont(SmallFont);
  analogReference(INTERNAL);  // если очень маленький уровень сигнала
  pinMode(A0,INPUT);
}

void loop() {
 // times=millis(); 
  strela = map(log(analogRead(A0))*GAIN, LOW_SOUND,MAX_SOUND, -45,45);
  strela = constrain(strela, -45, 45);
  urr = strela;if(urr<ur){ur=ur-STEP;}else{ur = strela;}  
   
/////// PRINT //////////////////////////////////////////////////////////////// 
  myOLED.clrScr();
  myOLED.drawLine(10, 20, 85, 20);// line 1
  myOLED.drawLine(88, 20, 125, 20);myOLED.drawLine(88, 19, 125, 19);// line 2
  myOLED.drawLine(3, 23, 85, 23);// line3

  byte b1_2[10]{95,108,124,10,33,60,84,50,68,77};
  byte c1_2[10]{15,17,15,15,15,15,15,17,18,18};
  for(int i=0;i<10;i++){myOLED.drawLine(b1_2[i], 20, b1_2[i], c1_2[i]);} 
  byte b3[5]{3,25,48,67,84};
  for(int i=0;i<5;i++){myOLED.drawLine(b3[i], 23, b3[i], 27);}

  myOLED.print(F("20  10   3   0 1"), 3, 5);
  myOLED.print(F("0  25"), 0, 30);
  myOLED.print(F("50"), 42, 30);
  myOLED.print(F("75"), 61, 30);
  myOLED.print(F("100"), 75, 30);
  myOLED.print(F("2"), 106, 5);
  myOLED.print(F("3"), 120, 5);
  myOLED.print(F("-"), 3, 50);myOLED.print(F("+"), 119, 50);
  myOLED.print(F("VU meter"), CENTER, 50);
 
  int a1 = (hMeter + (sin(ur / 57.296) * rMeter)); // meter needle horizontal coordinate
  int a2 = (vMeter - (cos(ur / 57.296) * rMeter)); // meter needle vertical coordinate
  myOLED.drawLine(a1, a2, hMeter, vMeter);  
  myOLED.update();
 // Serial.println(millis()-times);
//////// END PRINT /////////////////////////////////////////////////////////
}

2 (2022-09-28 02:54:20 отредактировано highprofi)

Re: VU meter + oled 0.96'

Здравствуйте.
А стерео сигнал и два дисплея одна ардуина потянет?
Возможно это сделать?

3

Re: VU meter + oled 0.96'

Точно не могу ответить, надо пробовать, но у меня нет второго экрана. С интерфейсом SPI точно можно 2 использовать, а I2C не знаю.

4

Re: VU meter + oled 0.96'

Могу проверить, у меня как раз два дисплея в наличии)
Если скетч допишете...

5

Re: VU meter + oled 0.96'

Изучил вопрос, с интерфейсом i2c ни чего не выйдет, библиотека рассчитана на работу только с одним дисплеем.

6

Re: VU meter + oled 0.96'

Печаль конечно (
А какой чип минимально можно использовать?
Чтоб памяти хватило
Жалко две не дешёвых ардуинки

7

Re: VU meter + oled 0.96'

Ни чего кроме lgt8f328p atmega168 и atmega328 не подойдет.

8

Re: VU meter + oled 0.96'

Понял, спасибо вам)

9

Re: VU meter + oled 0.96'

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

помогите пожалуйста как быть.

10

Re: VU meter + oled 0.96'

Александр ,доброго времени суток. Подскажите ,как адаптировать скетч vu meter под дисплей 240х320 ST7789 ? Использую для дисплея библиотеки Adafruit ST7789 и Adafruit GFX .Не могу понять ,как затирать старое изображение стрелки при ее перемещении . Стрелка работает,но оставляет за собой старые положения ,где ранее была по всей шкале. Я так понял в данной библиотеке нет замещения изображения.

11

Re: VU meter + oled 0.96'

Нужно затирать предыдущее значение отрисовки шкалы

Вот как я это делал на примере осциллографа

 tft.drawLine(i*mn, 230-data_old[i],i*mn+mn-1, 230-data_old[i+1], ILI9341_BLACK);
 tft.drawLine(i*mn, 230-data1[i+i2],i*mn+mn-1, 230-data1[i+1+i2],  ILI9341_RED);i++;}i=0;
 while(i<639){data_old[i]=data1[i+i2];i++;}i=0; 

12

Re: VU meter + oled 0.96'

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#define CS        5
#define DC        2
#define MOSI      23
#define SCLK       18
#define RST       4

Adafruit_ST7789 tft = Adafruit_ST7789(CS, DC, RST);

#define GAIN      100 //1
#define STEP      3
#define LOW_SOUND 50 //1
#define MAX_SOUND 600 //260 // для первого дисплея

#define GAIN_TWO     1 // 100
#define STEP_TWO      3
#define LOW_SOUND_TWO 1 //50
#define MAX_SOUND_TWO 700 //600 // для второго дисплея

  int strela=-45;
  int hMeter = 65;                      
  int vMeter = 85;                      
  int rMeter = 80;
  int ur,urr;
 
  int strela_two=-45;
  int hMeter_two = 65;                      
  int vMeter_two = 85;                      
  int rMeter_two = 80;
  int ur_two,urr_two;
  int strela_up = 0;
  int strela_ups = 0;
  
void setup(void) {
    SPI.begin();
    tft.setSPISpeed(20000000);
    //Serial.begin(9600);
    tft.init(240, 320,SPI_MODE3);
    tft.setRotation(3);
    tft.fillScreen(ST77XX_BLACK);
    delay(100);
    tft.setTextColor(ST77XX_GREEN);
    tft.setTextSize(1);
    //tft.setCursor(18, 82);
    //tft.print("Hello world!");
    pinMode(19, OUTPUT);
    digitalWrite(19,0);
    pinMode(32, INPUT);
}

void loop() {
         tft.setTextSize(1);
       strela = map(log(analogRead(32))*GAIN, LOW_SOUND,MAX_SOUND, -45,45);
       strela = constrain(strela, -45, 45);
       urr = strela;if(urr<ur){ur=ur-STEP;}else{ur = strela;}

       strela_two = map(analogRead(33)*GAIN_TWO, LOW_SOUND_TWO,MAX_SOUND_TWO, -45,45);
       strela_two = constrain(strela_two, -45, 45);
       urr_two = strela_two;if(urr_two<ur_two){ur_two=ur_two-STEP_TWO;}else{ur_two = strela_two;}
      // adc0 = analogRead(33);
      // Serial.print("Voltage: ");
      // Serial.println(adc0);//Serial.println(" ");
 
       /////////////////////////////////// PRINT ///////////////////////////////////////// 
       //tft.fillScreen(ST77XX_BLACK);
       //tft.drawLine(28, 102, 84, 20, ST77XX_BLUE);// line 1
       //tft.drawLine(106, 102, 124, 20, ST77XX_BLUE);tft.drawLine(106, 101, 124, 19, ST77XX_BLUE);// line 2
       //tft.drawLine(21, 105, 84, 23, ST77XX_BLUE);// line3
       /*display.drawLine(10, 20, 84, 20, 1);// line 1
       display.drawLine(88, 20, 124, 20, 1);display.drawLine(88, 19, 124, 19, 1);// line 2
       display.drawLine(3, 23, 84, 23, 1);// line3*/
 
       byte b1_2[10]{95,108,124,10,33,60,84,50,68,77};
       byte c1_2[10]{15,15,15,15,15,15,15,17,17,17};

       byte b2_2[10]{95,108,124,10,33,60,84,50,68,77};
       byte c2_2[10]{15,15,15,15,15,15,15,17,17,17};

  
       //for(int i=0;i<10;i++){tft.drawLine(b1_2[i]+18, 102, b1_2[i], c1_2[i], ST77XX_BLUE);//display.drawLine(b2_2[i], 20, b2_2[i], c2_2[i], 1);} 
       byte b3[5]{3,25,48,67,84};
       byte b4[5]{3,25,48,67,84};
       //for(int i=0;i<5;i++){tft.drawLine(b3[i]+18, 105, b3[i], 27, ST77XX_BLUE);//display.drawLine(b4[i], 23, b4[i], 27, 1);}

       tft.setCursor(23, 87);
       tft.print("20");
       tft.setCursor(46, 87);
       tft.print("10");
       tft.setCursor(76, 87);
       tft.print("3");
       tft.setCursor(100, 87);
       tft.print("0");
       tft.setCursor(111, 87);
       tft.print("1");
       /*display.setCursor(5, 5);
       display.print("20");
       display.setCursor(28, 5);
       display.print("10");
       display.setCursor(58, 5);
       display.print("3");
       display.setCursor(82, 5);
       display.print("0");
       display.setCursor(93, 5);
       display.print("1");*/
       tft.setCursor(19, 112);
       tft.print("0");
       tft.setCursor(38, 112);
       tft.print("25");
       /*display.setCursor(1, 30);
       display.print("0");
       display.setCursor(20, 30);
       display.print("25");*/
       tft.setCursor(61, 112);
       tft.print("50");
      // display.setCursor(43, 30);
      // display.print("50");
       tft.setCursor(79, 112);
       tft.print("75");
      // display.setCursor(61, 30);
      // display.print("75");
       tft.setCursor(94, 112);
       tft.print("100");
      // display.setCursor(76, 30);
     //  display.print("100");
       tft.setCursor(124, 87);
       tft.print("2");
     //  display.setCursor(106, 5);
     //  display.print("2");
       tft.setCursor(140, 87);
       tft.print("3");
     //  display.setCursor(122, 5);
     //  display.print("3");
       tft.setCursor(21, 132);tft.print("-");tft.setCursor(137, 132);tft.print("+");
       tft.setCursor(58, 132);tft.print("VU meter");
     //  display.setCursor(3, 50);display.print("-");display.setCursor(119, 50);display.print("+");
    //   display.setCursor(40, 50);display.print("VU meter");
 
       int a1 = (hMeter + (sin(ur / 57.296) * rMeter)); // meter needle horizontal coordinate
       int a2 = (vMeter - (cos(ur / 57.296) * rMeter)); // meter needle vertical coordinate

      // int a3 = (hMeter_two + (sin(ur_two / 57.296) * rMeter_two)); // meter needle horizontal coordinate
     //  int a4 = (vMeter_two - (cos(ur_two / 57.296) * rMeter_two)); // meter needle vertical coordinate
  
       tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLUE);
       //display.drawLine(a3, a4, hMeter_two, vMeter_two, 1);
       
     
       if (ur != strela_ups) {
       tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLACK);
          //tft.drawLine(a1+19, a2+83, hMeter+15, vMeter+85, ST77XX_BLACK);
       strela_ups = ur;}
}

13

Re: VU meter + oled 0.96'

Александр,прошу помощи. Не могу догнать ,как правильно затирать стрелку ?

14

Re: VU meter + oled 0.96'

У вас же меняются переменные а1 и а2

значит
a1_old = a1;
a2_old = a2;

сначала стираем

tft.drawLine(a1_old+18, a2_old+82, hMeter+18, vMeter+82, ST77XX_BLACK);

потом рисуем

tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLUE);
a1_old = a1;
a2_old = a2;

Примерно так

15

Re: VU meter + oled 0.96'

liman324 пишет:

У вас же меняются переменные а1 и а2

значит
a1_old = a1;
a2_old = a2;

сначала стираем

tft.drawLine(a1_old+18, a2_old+82, hMeter+18, vMeter+82, ST77XX_BLACK);

потом рисуем

tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLUE);
a1_old = a1;
a2_old = a2;

Примерно так

Спасибо,сейчас попробую.

16 (2026-02-18 16:14:39 отредактировано honda473)

Re: VU meter + oled 0.96'

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#define CS        5
#define DC        2
#define MOSI      23
#define SCLK       18
#define RST       4

Adafruit_ST7789 tft = Adafruit_ST7789(CS, DC, RST);

#define GAIN      100 //1
#define STEP      3
#define LOW_SOUND 50 //1
#define MAX_SOUND 600 //260 // для первого дисплея

#define GAIN_TWO     1 // 100
#define STEP_TWO      3
#define LOW_SOUND_TWO 1 //50
#define MAX_SOUND_TWO 700 //600 // для второго дисплея

  int strela=-45;
  int hMeter = 65;                      
  int vMeter = 85;                      
  int rMeter = 80;
  int ur,urr;
 
  int strela_two=-45;
  int hMeter_two = 65;                      
  int vMeter_two = 85;                      
  int rMeter_two = 80;
  int ur_two,urr_two;
  int a1_old, a2_old;
  
void setup(void) {
    SPI.begin();
    tft.setSPISpeed(20000000);
    //Serial.begin(9600);
    tft.init(240, 320,SPI_MODE3);
    tft.setRotation(3);
    tft.fillScreen(ST77XX_BLACK);
    delay(100);
    tft.setTextColor(ST77XX_GREEN);
    tft.setTextSize(1);
    //tft.setCursor(18, 82);
    //tft.print("Hello world!");
    pinMode(19, OUTPUT);
    digitalWrite(19,0);
    pinMode(32, INPUT);
}

void loop() {
         tft.setTextSize(1);
       strela = map(log(analogRead(32))*GAIN, LOW_SOUND,MAX_SOUND, -45,45);
       strela = constrain(strela, -45, 45);
       urr = strela;if(urr<ur){ur=ur-STEP;}else{ur = strela;}

       strela_two = map(analogRead(33)*GAIN_TWO, LOW_SOUND_TWO,MAX_SOUND_TWO, -45,45);
       strela_two = constrain(strela_two, -45, 45);
       urr_two = strela_two;if(urr_two<ur_two){ur_two=ur_two-STEP_TWO;}else{ur_two = strela_two;}
      // adc0 = analogRead(33);
      // Serial.print("Voltage: ");
      // Serial.println(adc0);//Serial.println(" ");
 
       /////////////////////////////////// PRINT ///////////////////////////////////////// 
       //tft.fillScreen(ST77XX_BLACK);
       //tft.drawLine(28, 102, 84, 20, ST77XX_BLUE);// line 1
       //tft.drawLine(106, 102, 124, 20, ST77XX_BLUE);tft.drawLine(106, 101, 124, 19, ST77XX_BLUE);// line 2
       //tft.drawLine(21, 105, 84, 23, ST77XX_BLUE);// line3
       /*display.drawLine(10, 20, 84, 20, 1);// line 1
       display.drawLine(88, 20, 124, 20, 1);display.drawLine(88, 19, 124, 19, 1);// line 2
       display.drawLine(3, 23, 84, 23, 1);// line3*/
 
       byte b1_2[10]{95,108,124,10,33,60,84,50,68,77};
       byte c1_2[10]{15,15,15,15,15,15,15,17,17,17};

       byte b2_2[10]{95,108,124,10,33,60,84,50,68,77};
       byte c2_2[10]{15,15,15,15,15,15,15,17,17,17};

  
       //for(int i=0;i<10;i++){tft.drawLine(b1_2[i]+18, 102, b1_2[i], c1_2[i], ST77XX_BLUE);//display.drawLine(b2_2[i], 20, b2_2[i], c2_2[i], 1);} 
       byte b3[5]{3,25,48,67,84};
       byte b4[5]{3,25,48,67,84};
       //for(int i=0;i<5;i++){tft.drawLine(b3[i]+18, 105, b3[i], 27, ST77XX_BLUE);//display.drawLine(b4[i], 23, b4[i], 27, 1);}

       tft.setCursor(23, 87);
       tft.print("20");
       tft.setCursor(46, 87);
       tft.print("10");
       tft.setCursor(76, 87);
       tft.print("3");
       tft.setCursor(100, 87);
       tft.print("0");
       tft.setCursor(111, 87);
       tft.print("1");
       /*display.setCursor(5, 5);
       display.print("20");
       display.setCursor(28, 5);
       display.print("10");
       display.setCursor(58, 5);
       display.print("3");
       display.setCursor(82, 5);
       display.print("0");
       display.setCursor(93, 5);
       display.print("1");*/
       tft.setCursor(19, 112);
       tft.print("0");
       tft.setCursor(38, 112);
       tft.print("25");
       /*display.setCursor(1, 30);
       display.print("0");
       display.setCursor(20, 30);
       display.print("25");*/
       tft.setCursor(61, 112);
       tft.print("50");
      // display.setCursor(43, 30);
      // display.print("50");
       tft.setCursor(79, 112);
       tft.print("75");
      // display.setCursor(61, 30);
      // display.print("75");
       tft.setCursor(94, 112);
       tft.print("100");
      // display.setCursor(76, 30);
     //  display.print("100");
       tft.setCursor(124, 87);
       tft.print("2");
     //  display.setCursor(106, 5);
     //  display.print("2");
       tft.setCursor(140, 87);
       tft.print("3");
     //  display.setCursor(122, 5);
     //  display.print("3");
       tft.setCursor(21, 132);tft.print("-");tft.setCursor(137, 132);tft.print("+");
       tft.setCursor(58, 132);tft.print("VU meter");
     //  display.setCursor(3, 50);display.print("-");display.setCursor(119, 50);display.print("+");
    //   display.setCursor(40, 50);display.print("VU meter");
 
       int a1 = (hMeter + (sin(ur / 57.296) * rMeter)); // meter needle horizontal coordinate
       int a2 = (vMeter - (cos(ur / 57.296) * rMeter)); // meter needle vertical coordinate

      // int a3 = (hMeter_two + (sin(ur_two / 57.296) * rMeter_two)); // meter needle horizontal coordinate
     //  int a4 = (vMeter_two - (cos(ur_two / 57.296) * rMeter_two)); // meter needle vertical coordinate
       
       
       tft.drawLine(a1_old+18, a2_old+82, hMeter+18, vMeter+82, ST77XX_BLACK);
       tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLUE);
       //display.drawLine(a3, a4, hMeter_two, vMeter_two, 1);
       a1_old = a1;
       a2_old = a2;
     
      // if (ur != strela_ups) {
      // tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLACK);
          //tft.drawLine(a1+19, a2+83, hMeter+15, vMeter+85, ST77XX_BLACK);
      // strela_ups = ur;}
}

17

Re: VU meter + oled 0.96'

Стало затирать,но стрелка с периодичностью мерцает примерно раз в полсекунды.

18

Re: VU meter + oled 0.96'

попробуйте сделать задержку после
tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLUE);

delay(5);

19

Re: VU meter + oled 0.96'

liman324 пишет:

попробуйте сделать задержку после
tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLUE);

delay(5);

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

20

Re: VU meter + oled 0.96'

Не до конца затирает?

21

Re: VU meter + oled 0.96'

liman324 пишет:

Не до конца затирает?

До конца затирает,но когда стрелка в нуле(без сигнала),то стрелка мерцает.Когда стрелка перемещается,то мерцания не замечено.

22

Re: VU meter + oled 0.96'

я так понял,что когда стрелка стоит на месте,то происходит мерцания.

23

Re: VU meter + oled 0.96'

Тогда можно добавить условие

if(a1!=a1_old && a2!=a2_old){
  tft.drawLine(a1_old+18, a2_old+82, hMeter+18, vMeter+82, ST77XX_BLACK);
}

24

Re: VU meter + oled 0.96'

 if(a1!=a1_old && a2!=a2_old){
       tft.drawLine(a1_old+18, a2_old+82, hMeter+18, vMeter+82, ST77XX_BLACK);}
       tft.drawLine(a1+18, a2+82, hMeter+18, vMeter+82, ST77XX_BLUE);
       //display.drawLine(a3, a4, hMeter_two, vMeter_two, 1);
        delay(5);
       a1_old = a1;
       a2_old = a2;

25

Re: VU meter + oled 0.96'

liman324 пишет:

Тогда можно добавить условие

if(a1!=a1_old && a2!=a2_old){
  tft.drawLine(a1_old+18, a2_old+82, hMeter+18, vMeter+82, ST77XX_BLACK);
}

Добавил условие,мерцание перестало,но в начале слева оставляет стрелку и по центру 5 стрелок.Сейчас фото попробую загрузить.