Skip to content

Instantly share code, notes, and snippets.

@blippy
Created June 26, 2019 20:39
Show Gist options
  • Save blippy/f9d008d7c6a7db1018bd3929f2352e12 to your computer and use it in GitHub Desktop.
Save blippy/f9d008d7c6a7db1018bd3929f2352e12 to your computer and use it in GitHub Desktop.
Streaming audio on an ESP32 with a blinkt
#include <Arduino.h>
#include <WiFi.h>
#include <driver/dac.h>
const int dataPin = 4; // Blinkt pin 16
const int clockPin = 5; // blinkt pin 18
const int numLEDs = 8;
uint8_t pixels[numLEDs * 3];
void spi_out(uint8_t n) {
for (uint8_t i = 8; i--; n <<= 1) {
if (n & 0x80) digitalWrite(dataPin, HIGH);
else digitalWrite(dataPin, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
void show() {
uint8_t i;
uint8_t n = numLEDs;
uint8_t *ptr = pixels;
for (i = 0; i < 4; i++) spi_out(0x00); // 4 byte start-frame marker
do { // For each pixel...
spi_out(0xFF); // Pixel start
for (i = 0; i < 3; i++) spi_out(*ptr++); // Write R,G,B
} while (--n);
for (i = 0; i < ((numLEDs + 15) / 16); i++) spi_out(0xFF); // end-frame marker
}
void setPixelColour(uint8_t pos , uint8_t r, uint8_t g, uint8_t b) {
pos *= 3;
pixels[pos++] = b;
pixels[pos++] = g;
pixels[pos] = r;
}
void update_blinkt(uint8_t vol)
{
vol = abs(vol-128)/16;
uint8_t r;
for(int i=0; i<8; ++i) {
r = i<= vol ? 25 : 0;
setPixelColour(i, r, 0, 0);
}
show();
}
const char* ssid = "...";
const char* password = "...";
const char* host = "192.168.0.???";
WiFiClient client;
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
#define BUFFFERMAX 8000
uint8_t dataBuffer[BUFFFERMAX];
int readPointer = 0, writePointer = 1;
bool play = false;
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
// play data:
if (play) {
dac_output_voltage(DAC_CHANNEL_1, dataBuffer[readPointer]);
if(readPointer % 200 == 0) update_blinkt(dataBuffer[readPointer]);
readPointer++;
if (readPointer == BUFFFERMAX) {
readPointer = 0;
}
if ( getAbstand() == 0 ) {
Serial.println("Buffer underrun!!!");
play = false;
}
}
portEXIT_CRITICAL_ISR(&timerMux);
}
int getAbstand() {
int abstand = 0;
if (readPointer < writePointer ) abstand = BUFFFERMAX - writePointer + readPointer;
else if (readPointer > writePointer ) abstand = readPointer - writePointer;
return abstand;
}
void setup() {
Serial.begin(115200);
dac_output_enable(DAC_CHANNEL_1);
pinMode(33, INPUT_PULLUP);
pinMode(32, INPUT_PULLUP);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
pinMode(dataPin , OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(dataPin , LOW);
digitalWrite(clockPin, LOW);
show();
const int port = 4444;
while (!client.connect(host, port)) {
Serial.println("connection failed");
delay(1000);
}
timer = timerBegin(0, 2, true); // use a prescaler of 2
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 5000, true);
timerAlarmEnable(timer);
}
void loop() {
int abstand = getAbstand();
if (abstand <= 800) play = true;
if ( abstand >= 800) {
client.write( B11111111 ); // send the command to send new data
// read new data:
while (client.available() == 0);
while (client.available() >= 1) {
uint8_t value = client.read();
dataBuffer[writePointer] = value;
writePointer++;
if (writePointer == BUFFFERMAX) writePointer = 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment