Skip to content

Instantly share code, notes, and snippets.

@lzpel
Last active November 21, 2021 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lzpel/2b6fdf4fd1fd83c457f89b06a9332db2 to your computer and use it in GitHub Desktop.
Save lzpel/2b6fdf4fd1fd83c457f89b06a9332db2 to your computer and use it in GitHub Desktop.
441hz sin wave for Arduino IDE and ESP32-CAM
// 参考
// https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/esp32/include/driver/include/driver/i2s.h
#include <driver/i2s.h>
static const int sample_rate=44100;
static const i2s_port_t i2s_num = I2S_NUM_0 ; // i2s port number
static const int wave_hz = 441; // 100hzは男性の声に近い周波数
static const int sample_per_cycle=sample_rate/wave_hz;
static const int max_volume=15000;
uint16_t samples_data[sample_per_cycle];
void setup_waves(void){
double sin_float;
for(int i = 0; i < sample_per_cycle; i++) {
sin_float = sin(2 * i * PI / (double)sample_per_cycle);
samples_data[i] = (uint16_t)((sin_float + 1) * max_volume);
Serial.printf("%d\n",samples_data[i]); //信号の確認
}
}
void setup(){
Serial.begin(115200);
Serial.printf("Output frequency: %d\n", sample_rate);
setup_waves();
i2s_config_t i2s_config = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = sample_rate, // The format of the signal using ADC_BUILT_IN
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT ,
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,// 1ch(I2S_CHANNEL_FMT_ONLY_RIGHT or I2S_CHANNEL_FMT_ONLY_LEFT) 2ch(I2S_CHANNEL_FMT_ONLY_LEFT or I2S_CHANNEL_FMT_ALL_RIGHT or I2S_CHANNEL_FMT_ALL_LEFT)
.communication_format = I2S_COMM_FORMAT_STAND_I2S,//warning: 'I2S_COMM_FORMAT_I2S' is deprecated
.dma_buf_count=3,//このバッファがグルグル回る
.dma_buf_len=sizeof(samples_data)//byte単位
};
i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
static const i2s_pin_config_t pin_config = {
.bck_io_num = 14,// IO14 pin connected to BCRK
.ws_io_num = 16,// IO16 pin connected to LRCRK
.data_out_num = 15,// IO15 pin connected to DIN
//IO0,2,4はADCが使えるので別用途に予約したい
.data_in_num = I2S_PIN_NO_CHANGE
};
i2s_set_pin(i2s_num, &pin_config);
//i2s_set_dac_mode(I2S_DAC_CHANNEL_DISABLE);//カメラで使われている可能性があるので手を付けない
}
void loop() {
size_t bytes_written;
esp_err_t result;
result=i2s_write(i2s_num, samples_data, sizeof(samples_data), &bytes_written, portMAX_DELAY);
//portMAX_DELAYはバッファが空くまで待機か?なら0ならバッファが空いていなければ即返か?
Serial.printf("bytes_written: %d, result: %d, millis: %d \n",bytes_written,result,millis());
//bytes_written==sizeof(samples_data)==882 is correct 正解
//20msに2回呼ばれていて20/2=10ms;100hz*10ms=1000ms=1sで辻褄が合う
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment