Skip to content

Instantly share code, notes, and snippets.

@loleg
Created October 30, 2020 17:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loleg/26634152fdf240947f973a8b24ad2fbf to your computer and use it in GitHub Desktop.
Save loleg/26634152fdf240947f973a8b24ad2fbf to your computer and use it in GitHub Desktop.
A zombie remix of tamberg's SwissCovid-detector and ganda1f's PartyNoise-detector
// Just getting my hands dirty with Arduino! Please don't be upset ...
/* Sources:
*
* https://github.com/gand417/mz2020_audio/blob/main/mz2020_audio.ino
* https://github.com/make-zurich/makezurich-hardware-intro/blob/master/Arduino/Neno33BleSense_CoronaAppScanner/Neno33BleSense_CoronaAppScanner.ino
*/
#include <Adafruit_NeoPixel.h>
#include <ArduinoBLE.h>
#include <PDM.h>
// Make Zurich 2020 badge LED configuration
#define LED_PIN 4
#define LED_COUNT 11
#define CORONA_APP_SERVICE_UUID "fd6f"
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Pink <3
#define LED_R 1
#define LED_G 6
#define LED_B 1.3
int nOfCoronaApps = 0;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[256];
// Number of samples read
volatile int samplesRead;
void setup() {
// Initialize serial monitor for debugging
Serial.begin(9600);
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Set the gain, defaults to 20
PDM.setGain(30);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate
if (!PDM.begin(1, 16000)) {
Serial.println("Failed to start PDM!");
while (1);
}
strip.begin();
strip.show(); // all off
strip.setBrightness(50); // max 255
if (!BLE.begin()) {
Serial.println("BLE not ready, press reset!");
while (1) {} // wait for reset
}
Serial.println("BLE central scanning for Corona apps ...");
BLE.scanForUuid(CORONA_APP_SERVICE_UUID);
}
void loop() {
BLEDevice peripheral = BLE.available();
if (peripheral) {
nOfCoronaApps++; // TODO: skip duplicates
Serial.print("Discovered Corona app ");
Serial.println(peripheral.address());
}
// Wait for samples to be read
if (samplesRead) {
// Iterate over all samples in the buffer
for (int i = 0; i < samplesRead; i++) {
int volume = abs(sampleBuffer[i]);
// Cancel background noise
if (volume < 32) {
volume = 0;
}
// Set all pixels accordingly
for(int i=0; i<LED_COUNT; i++) {
strip.setPixelColor(i, strip.Color((volume/LED_R), volume/LED_G, (volume/LED_B)));
}
// Set Corona-pixels
int n = min(nOfCoronaApps, LED_COUNT);
for (int i = 0; i < n; i++) {
strip.setPixelColor(i, strip.Color(0, 255, 0));
}
// Send the updated pixel colors to the LED strip
strip.show();
}
// Clear audio sample buffer read count
samplesRead = 0;
}
}
void onPDMdata() {
// Query the number of bytes available
int bytesAvailable = PDM.available();
// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment