I am implementing a oscilloscope GUI to visualize the data coming from the I2S mic connected to ESP32. The data is transmitted to ESP32 over WiFi through TCP socket connection to PC client where the GUI is made.
This is ESP32, server side code.
void setup() {
const i2s_config_t i2s_config = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), // Receive, not transfer
.sample_rate = 16000, // 16KHz
.bits_per_sample = I2S_BITS_PER_SAMPLE_24BIT, // could only get it to work with 32bits
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // although the SEL config should be left, it seems to transmit on right
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // Interrupt level 1
.dma_buf_count = 4, // number of buffers
.dma_buf_len = 8 // 8 samples per buffer (minimum)
};
};
void loop() {
WiFiClient client = wifiServer.available();
if (client) {
while (client.connected()) {
while (client.available()>0) {
int32_t sample = 0;
int bytes_read = i2s_pop_sample(I2S_PORT, (char *)&sample, portMAX_DELAY); // no timeout
String samplestring = String(sample*0.00000059);
client.println(samplestring);
}
delay(10);
}
client.stop();
Serial.println("Client disconnected");
}
}
I am plotting it on a GUI in winform. But when I plot it doesn't give the correct wave format (I tried with 1kHz sine wave).
I am loading the data to a textbox and getting converted to double to plot the data.
What is wrong here?
int t;
private void Timer1_Tick(object sender, EventArgs e)
{
one = new Thread(test);
one.Start();
t++;
}
public void test()
{
byte[] bytes = new byte[client.ReceiveBufferSize];
var readCount = stream.Read(bytes, 0, bytes.Length);
string datastring = Encoding.UTF8.GetString(bytes);
txtdata.Invoke((MethodInvoker)(() => txtdata.Text = datastring.Substring(0, 100)));
txtno.Invoke((MethodInvoker)(() =>
txtno.Text = ("\nnumber of bytes read: " + readCount)
));
String ch1 = txtdata.Text; ;
String[] ch1y = ch1.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
for (int a = 1; a < ch1y.Length - 1; a++)
{
chart1.Invoke((MethodInvoker)(() =>
chart1.Series[0].Points.AddXY(t, Convert.ToDouble(ch1y[a]))
));
}
}
I edited the above code like this
private void Timer1_Tick(object sender, EventArgs e)
{
byte[] bytes = new byte[client.ReceiveBufferSize];
var readCount = stream.Read(bytes, 0, bytes.Length);
string datastring = Encoding.UTF8.GetString(bytes);
txtdata.Invoke((MethodInvoker)(() =>
txtdata.Text = datastring.Substring(0, 100)));
txtno.Invoke((MethodInvoker)(() =>
txtno.Text = ("\nnumber of bytes read: " + readCount)));
String ch1 = txtdata.Text; ;
String[] ch1y = ch1.Split(new char[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
double[] val = new double[ch1y.Length];
for (int a = 1; a < ch1y.Length - 1; a++)
{
val[a] = double.Parse(ch1y[a]);
chart1.Series[0].Points.Add(val[a]);
}
if (chart1.Series[0].Points.Count > 5)
chart1.Series[0].Points.RemoveAt(0);
chart1.ChartAreas[0].AxisX.Minimum = double.NaN;
chart1.ChartAreas[0].AxisX.Maximum = double.NaN;
}