1 (edited by gorchakov 2023-04-04 03:31:28)

Topic: лабораторный эксперимент-опыт Кундта

Трубка Кундта на основе микроконтроллера WeMos D1

Для проведения опыта Кундта со стоячими волнами в трубе можно воспользоваться возможностями современных микроконтроллеров. Для создания установки понадобятся трубка стеклянная или пластиковая диаметром от 12 мм и больше и длиной 50 см, микроконтроллер с WiFi-  nodemcu или  WeMos, зуммер KY-006  и микрофонный модуль. Зуммер и микрофонный модуль помещаются на края трубки и подключаются к микроконтроллеру по схеме

Рисунок 1. Схема установки Кундта с изменением частоты звука
Программа создается в оболочке RemoteXY в следующем виде

Рисунок 2. Интерфейс управления установкой
После этого мы получаем заготовку кода и добавляем в нее свой код в соответствии с текстом
#define REMOTEXY_MODE__ESP8266WIFI_LIB_POINT
#include <ESP8266WiFi.h>

#include <RemoteXY.h>

// настройки соединения
#define REMOTEXY_WIFI_SSID "doublems"
#define REMOTEXY_WIFI_PASSWORD "12345678"
#define REMOTEXY_SERVER_PORT 6377
const byte dynPin=2;
//генерация звука на втором пине
const int IN_PIN = A0;
//прием звука на аналоговом пине а0
const int MAX_ADC_VALUE = 1023;//возможно изменить на 255
int frec;

// конфигурация интерфейса 
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =   // 43 bytes
  { 255,1,0,8,0,36,0,16,31,1,68,17,1,1,60,49,8,36,68,17,
  2,52,59,40,8,36,2,0,21,93,22,6,2,26,31,31,79,78,0,79,
  70,70,0 };

 
// структура определяет все переменные и события вашего интерфейса управления
struct {

    // input variables
  uint8_t switch_1; // =1 если переключатель включен и =0 если отключен

    // output variables
  float onlineGraph_1;
  float onlineGraph_2;

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////



void setup()
{
RemoteXY_Init ();
  pinMode(dynPin,OUTPUT);
  pinMode(IN_PIN, INPUT);
frec=3000;//исходное значение частоты 3000 Гц
}

void loop()
{ RemoteXY_Handler ();
   
   if ((RemoteXY.switch_1!=0)and(frec<5000)){
      //инициализируем переменные
int mn = 1024;
int mx = 0;
tone(dynPin,frec);//запускаем генератор звука
for (int i=0; i < 1000; ++i) {
   
  //ищем макс и мин значения амплитуды
int val = analogRead(IN_PIN);
mn = min(mn, val);
mx = max(mx, val);
}
//нашли размах амплитуды
       noTone(dynPin);//отключаем звук
    delayRXY(250); 
    RemoteXY.onlineGraph_1 = float (frec);
    RemoteXY.onlineGraph_2 = float (5.0 / MAX_ADC_VALUE* (mx - mn));
     frec=frec+10;//увеличиваем частоту на 100 для следующего измерения
}
else {if (RemoteXY.connect_flag==0) //если соединение смартфона и контроллера разорвалось, то

   {RemoteXY.switch_1=0; //устанавливаем выключатель в положение OFF.

   } //в этом случае при повторном соединении эффекты не запустятся самопроизвольно
   
  }
  }
  void delayRXY (uint32_t ms) {
  uint32_t t = millis ();
  while (millis () - t < ms) RemoteXY_Handler ();
   
}
Общая идея программы состоит в следующем: по включении тумблера микроконтроллер начинает генерировать звуковую волну заданной частотой и в течении 1000 циклов ищет максимальное и минимальное значение амплитуды сигнала, после чего выдает на график значение частоты и амплитуды. Затем увеличивает значение частоты и повторяет то же самое до тех пор, пока не достигнет граничного значения, строя таким образом одновременно два графика-зависимости частоты и амплитуды от времени.

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