1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-15 00:02:49 +03:00

I2s input API and examples (#4539)

Enables I2S stereo input via DMA using new API calls:

. i2s_rxtx_begin(bool rx, rool tx);
. i2s_read_sample(uint32_t *l, uint32_t *r);

Original API calls will only enable TX, so this is backwards compatible.

Add simple I2S input example code using Arduino serial plotter.

Add UDP transmit of I2S microphone data to a PC (remote microphone).

Clean up and reorganize code to share RX and TX logic as much as
possible.  Fix a potential WDT error while in blocking sample read
and write.
This commit is contained in:
Earle F. Philhower, III
2018-04-02 07:37:21 -07:00
committed by GitHub
parent 7ae8f98e57
commit 8ae553d99e
4 changed files with 479 additions and 141 deletions

View File

@ -0,0 +1,55 @@
/*
I2S stereo microphone (input) example
Run using the Arduion Serial Plotter to see waveform.
Released to the Public Domain by Earle F. Philhower, III
For the Google AIY Voice Hat Microphone daughterboard, part
of the Raspberry Pi AIY cardboard box, the I2S stereo pinout
looking at the board top with the RPI logo on the left hand
side:
+-- ------------------------------------ --+
left RPI | (1) GND (2) DIN (3) BCLK (4) LRCLK (5) 3.3V | AIY right
+---------------------------------------------+
The I2S pins are on different pins depending on your board.
The *internal GPIO number* which is NOT NECESSARIALY the
same as the pin numbers, are as follows:
I2SI_DATA = GPIO12
IS2I_BCK = GPIO13
I2SI_WS/LRCLK = GPIO14
On the D1 mini the I2SI pins map to the following D pins:
I2SI_DATA = GPIO12 = D6
IS2I_BCK = GPIO13 = D7
I2SI_WS/LRCLK = GPIO14 = D5
Expect different D pins on different ESP8266 boards, and of
course be sure to wire up VCC(3.3V) and GND.
*/
#include <ESP8266WiFi.h>
#include <i2s.h>
void setup() {
Serial.begin(115200);
WiFi.forceSleepBegin();
delay(500);
i2s_rxtx_begin(true, false); // Enable I2S RX
i2s_set_rate(11025);
delay(1000);
while (1) {
int16_t l, r;
i2s_read_sample(&l, &r, true);
char withScale[256];
sprintf(withScale, "%d %d", l, r);
Serial.println(withScale);
yield();
}
}
void loop() {
/* Nothing here */
}

View File

@ -0,0 +1,75 @@
/*
I2S stereo microphone (input) UDP transmitter
Needs a UDP listener (netcat/etc.) on port 8266 on the PC
Under Linux:
nc -u -p 8266 -l | play -t raw -r 11025 -b 16 -c 2 -e signed-integer -
Released to the Public Domain by Earle F. Philhower, III
*/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <i2s.h>
// Set your network here
const char *SSID = "....";
const char *PASS = "....";
WiFiUDP udp;
// Set your listener PC's IP here:
const IPAddress listener = { 192, 168, 1, 2 };
const int port = 8266;
int16_t buffer[100][2]; // Temp staging for samples
void setup() {
Serial.begin(115200);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(SSID);
WiFi.begin(SSID, PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("My IP: ");
Serial.println(WiFi.localIP());
i2s_rxtx_begin(true, false); // Enable I2S RX
i2s_set_rate(11025);
Serial.print("\nStart the listener on ");
Serial.print(listener);
Serial.print(":");
Serial.println(port);
Serial.println("ex: nc -u -p 8266 -l | play -t raw -r 11025 -b 16 -c 2 -e signed-integer -");
udp.beginPacket(listener, port);
udp.write("I2S Receiver\r\n");
udp.endPacket();
}
void loop() {
static int cnt = 0;
// Each loop will send 100 raw samples (400 bytes)
// UDP needs to be < TCP_MSS which can be 500 bytes in LWIP2
for (int i = 0; i < 100; i++) {
i2s_read_sample(&buffer[i][0], &buffer[i][1], true);
}
udp.beginPacket(listener, port);
udp.write((uint8_t*)buffer, sizeof(buffer));
udp.endPacket();
cnt++;
if ((cnt % 100) == 0) {
Serial.printf("%d\n", cnt);
}
}