VCO с чистым звуком

antonx
Offline
Зарегистрирован: 29.12.2019

Здравствуйте

Вот программа генератора, но частота здесь меняется скачками и звук получзается не чистой.
Как сделать  чтобы частота менялась плавно ?
void setup() {
  pinMode(9, OUTPUT);
}

void loop() {

  int frequencyinput = analogRead(A0);
  frequencyinput = map(frequencyinput, 0, 1203, 50, 5000);
  tone(9, frequencyinput);
  delay(100);
}

 

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Чистый звук можно получить только синусоидой, а прямоугольник по определению имеет кучу гармоник. Переключение частот, если Вам надо плавно лучше кнопками или энкодером. Кроме того - избавьтесь от delay().

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

и строка 8 должна быть иной, как минимум

 frequencyinput = map(frequencyinput, 0, 1023, 50, 5000);

А так не лучше будет?

#include <Arduino.h>
#define BUF_SIZE 32 //размер буфера - должен быть стпенью двойки
#define BUF_MASK (BUF_SIZE-1)
 
const uint8_t sum_of_numbers[] = {0,1,3,6,10,15,21,28,36,45,55}; 
const uint16_t sum_of_squares[] = {0,1,5,14,30,55,91,140,204,285,385}; 

class Data_Buffer{
  public:
  uint8_t count=0;
 
  
  void reset() {
     count =0;
     idxIN = 0;
     idxOUT = 0;
  }
  
  void put(const int val) {
     buffer[idxIN++] = val;
     idxIN &= BUF_MASK;
     if (count < BUF_MASK) count++;
  }
  
  int get() {
     if ( ! count) return -9999;
     idxOUT = idxIN - 1;
     idxOUT &= BUF_MASK;
     return  buffer[idxOUT];
  }
  
  int average(uint8_t norm) {
     long sum =0;
   if (norm >= count) norm = count;
   if ( ! norm) return -9999;
   
   idxOUT = idxIN - 1;
   idxOUT &= BUF_MASK;
   for (int i =0; i<norm; i++)  {
        sum += buffer[idxOUT--];
      idxOUT &= BUF_MASK;
      }
   return sum/norm;
    
  } 
  
   int trend(uint8_t norm) {
     long sum =0;
   if (norm > count) norm = count;
   if (norm > 10) norm = 10;
   if ( norm <4 ) return -9999;
   
   idxOUT = idxIN - 1;
   idxOUT &= BUF_MASK;
         for (int i = norm-1; i>0; i--) {
     sum += buffer[idxOUT--] * i;
           idxOUT &= BUF_MASK;
    }
     return ((sum - sum_of_numbers[norm-1] * buffer[idxOUT])) / sum_of_squares[norm-1];
   }
 
  Data_Buffer() {
   reset();
   }
  
  private:
  uint16_t buffer [BUF_SIZE];
  uint8_t idxIN, idxOUT;
  };
  Data_Buffer MyBuffer;
  
#define READ_PIN A0
volatile int frequencyinput;
  
void setup() {
pinMode(9, OUTPUT);
for(int i=0; i<16;i++){
frequencyinput = analogRead(A0);
MyBuffer.put(frequencyinput);
 }
}

void loop() {
  frequencyinput = analogRead(A0);
  MyBuffer.put(frequencyinput);
  frequencyinput = MyBuffer.average(10);
  frequencyinput = map(frequencyinput, 0, 1023, 50, 5000);
  tone(9, frequencyinput);
}

 

antonx
Offline
Зарегистрирован: 29.12.2019

Спасибо, звук лучше, пробовал тоже с  STM32F103 ,  но с ним не работает, пины kонечно поменял.

 

antonx
Offline
Зарегистрирован: 29.12.2019

Вот ещё одна программа, измеритель постоянного напряжения, отчет в мВ.

#include "LiquidCrystal.h"

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

float input_voltage = 0.0;
float temp=0.0;


void setup()
{
   Serial.begin(9600);     //  opens serial port, sets data rate to 9600 bps
   lcd.begin(16, 2);       //// set up the LCD's number of columns and rows: 
   lcd.print("DIGITAL VOLTMETER");
}
void loop()
{

//Conversion formula for voltage
   
   int analog_value = analogRead(A0);
   input_voltage = (analog_value * 5.0) / 1.0240; // мВ

   
   if (input_voltage < 0.1) 
   {
     input_voltage=0.0;
   } 
    Serial.print("v= ");
    Serial.println(input_voltage);
    lcd.setCursor(0, 1);
    lcd.print("Voltage= ");
    lcd.print(input_voltage);
    delay(300);
}
Как поменять мВ на герцы, звук - pinMode(9, OUTPUT); ?
 
sadman41
Онлайн
Зарегистрирован: 19.10.2016

Тут всё просто: frequency = f(voltage);

antonx
Offline
Зарегистрирован: 29.12.2019
int volt;
int  frequency;
int f;
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
void setup() {
  pinMode(PA6, INPUT_ANALOG);
  pinMode(PC13, OUTPUT);
  lcd.begin(16, 2);
}

void loop() {
  float volt = analogRead(PA6);
  volt = (volt * 3.3) / 4.0950; // мВ
  frequency = f(volt);
  tone(PC13, frequency);

  lcd.setCursor(0, 0);
  lcd.print(volt);
}

 

antonx
Offline
Зарегистрирован: 29.12.2019

VCO_mV:15:21: error: 'f' cannot be used as a function

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Отлично. Теперь нужно в функцию f() поместить формулу пересчёта mV в Hz. Ведь только Вам она известна.

antonx
Offline
Зарегистрирован: 29.12.2019

frequency = volt;

void loop() {
  float volt = analogRead(PA6);
  volt = (volt * 3.3) / 4.0950; // мВ
  frequency = volt;
  tone(PC13, frequency);

  lcd.setCursor(0, 0);
  lcd.print(volt);

Сделал так, но звук меняется не плавно, вместо  - tone - нужно чти то другое.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

в среднем человек слышит изменение частоты на 7 герц и более, если взять 10 герц на единицу то 1023 дадут изменение на 10 килогерц, а вам надо 5, осталось убрать скачки с аналогового пина и изменять частоту на 10 герц, если значение с аналогового пина изменилось на 2 единицы...

выше приводил код, где сигнал с аналогового пина усредняется, вывести значение в монитор порта и посмотреть, на сколько единиц скачет, это и будет дискретность (значение +1), 1023 / (значение +1) = количество градаций,  4500 / количество градаций = цена градации в герцах

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

antonx, строго говоря, получить от цифрового (АКА дискретного) устройства плавное (АКА непрерывное) изменение чего либо - задача принципиально невыполнимая.

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

Судя по Вашим сообщениям, у Вас явно недостаточно знаний, чтобы грамотно сформулировать техническую задачу. Поэтому попытайтесь описать, чего именно Вы хотите добиться. В частности, что именно Вам нужно: "частота" или "звук".

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

в среднем человек слышит изменение частоты на 7 герц и более...

Кто Вам это сказал?

Слуховой анализатор человека (ухо) обладает логарифмической характеристикой по обеим осям (частоты и амплитуды), поэтому "изменение частоты" для него следует измерять не в Герцах, а в процентах.

Но это имеет смысл обсуждать только в случае, если ТС нужен именно "звук". Ведь он может, скажем, использовать частотомер для индикации напряжения, а на слух проверять работу схемы лишь при отладке.

rkit
Offline
Зарегистрирован: 23.11.2016

andriano пишет:

"изменение частоты" для него следует измерять не в Герцах, а в процентах.

Звук на слух измеряют в октавах.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

anatoli_nik
Offline
Зарегистрирован: 17.01.2019

Погуглите на тему DDS генератора. Даже на ардуине можно несколько килогерц синусоиды выжать, или несколько десятков килогерц прямоугольников.

antonx
Offline
Зарегистрирован: 29.12.2019

Есть генератор на NE555 частота меняется плавно, с tone(PC13, frequency); сперва меняется скважность   импульсов - 0% -100% , когда она превышает 100%, частота увеличивается вдвое и снова меняется скважность   0% -100%, то что  видно на осциллографе, так что проблема не в потенциометре, а в tone.

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

andriano пишет:

"изменение частоты" для него следует измерять не в Герцах, а в процентах.

Звук на слух измеряют в октавах.

ты это японцам скажи )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

antonx пишет:

Есть генератор на NE555 частота меняется плавно, с tone(PC13, frequency); сперва меняется скважность   импульсов - 0% -100% , когда она превышает 100%, частота увеличивается вдвое и снова меняется скважность   0% -100%, то что  видно на осциллографе, так что проблема не в потенциометре, а в tone.

это не проблема, это особенности реализации функции

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

rkit пишет:

andriano пишет:

"изменение частоты" для него следует измерять не в Герцах, а в процентах.

Звук на слух измеряют в октавах.

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

Обычно используются более мелкие единицы, например, в музыке используется полутон - 1/12 октавы. А для более точных вещей - цент: 1/100 полутона или 1/1200 октавы.

В среднем здоровый человек различает интервал 6-20 центов, а люди с развитым музыкальным слухом - 3-4 цента.

В общем, IMHO вполне вменяемым интервалом для того, чтобы человеческий слух воспринимал изменение высоты тона как плавное, можно считать 1/32 тона (1/384 октавы, 3.1 цента). http://arduino.ru/forum/proekty/analog-analogovogo-sintezatora

rkit
Offline
Зарегистрирован: 23.11.2016

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

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

rkit пишет:

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

Извините, уважаемый, но Вы наверное очень умный и знаете чем отличается синусоида от пилы или прямоугольника. Тогда купите генератор синусоиды, подключите к ардуинке и не парьте нам мозги. Если Вы хотите получить ЧИСТЫЙ звук на цифровом аппарате - Вам в любом случае надо пользоваться ЦАП. В том или ином виде.

antonx
Offline
Зарегистрирован: 29.12.2019

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

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

antonx пишет:

 проблема не в потенциометре, а в tone.

Ну хорошо, попробуйте вот такой код и скажите - на ваш слух частота меняется плавно?

 

void setup() {
  pinMode(9, OUTPUT);
}

int freq = 50;
void loop() {

  tone(9, freq);
  delay(5000/freq);
  ++freq;
}

 

antonx
Offline
Зарегистрирован: 29.12.2019

Есть интервалы, когда частота меняется плавно.

Здесь частота  меняется плавно.

https://www.szynalski.com/tone-generator/

Вы можете там выбрать прямоугольник . На частоте около 30 Гц вы можете услышать изменение на 1 Гц.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

antonx пишет:

Есть интервалы, когда частота меняется плавно.

А конкретнее?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

antonx пишет:

Есть интервалы, когда частота меняется плавно.

Здесь частота  меняется плавно.

https://www.szynalski.com/tone-generator/

Вы можете там выбрать прямоугольник . На частоте около 30 Гц вы можете услышать изменение на 1 Гц.

нет, это интермодуляционные

antonx
Offline
Зарегистрирован: 29.12.2019

asam пишет:

antonx пишет:

Есть интервалы, когда частота меняется плавно.

А конкретнее?

В начале.

Слышно два звуковых сигнала, один громкий частота меняется плавно  второй потише  ШИМ.

В конце.
Звучит, как будто кто-то играет на пиано.