Skip to content

Instantly share code, notes, and snippets.

@mjbella
Last active June 25, 2017 21:16
Show Gist options
  • Save mjbella/86592d21e0b42188b33422f9157b9b65 to your computer and use it in GitHub Desktop.
Save mjbella/86592d21e0b42188b33422f9157b9b65 to your computer and use it in GitHub Desktop.
Basic ESP8266 blinkness using painlessMesh
//************************************************************
// this is a simple example that uses the painlessMesh library
//
// 1. sends a silly message to every node on the mesh at a random time betweew 1 and 5 seconds
// 2. prints anything it recieves to Serial.print
//
// prerequisites
// - Arduino JSON https://github.com/bblanchon/ArduinoJson
//
//
//
//************************************************************
#include "painlessMesh.h"
#include <NeoPixelAnimator.h>
#include <NeoPixelBrightnessBus.h>
#include <NeoPixelBus.h>
//#include <math.h>
#define MESH_PREFIX "RGB_LED"
#define MESH_PASSWORD "BurningMan"
#define MESH_PORT 5555
#define LEDPIN 4
#define NPLEN 4
extern int testData[200];
painlessMesh mesh;
uint32_t sendMessageTime = 0;
uint32_t sent = 0;
// Goertzel library
int sensorPin = A0;
const int N = 150;
const float SAMPLING_FREQUENCY = 8000;
//NeoPixelBus<NeoGrbFeature, NeoEsp8266Uart800KbpsMethod> strip(NPLEN, LEDPIN);
NeoPixelBus<NeoRgbFeature, NeoEsp8266Uart800KbpsMethod> strip(NPLEN, LEDPIN);
// ADC Data tmp location
short sound_data[N];
/* These two arrays need to be the same length! */
// Freqs to analyze
short bins[] = {50, 75, 100, 125, 150, 200, 1500}; // In Hz
// Results!
float amps[] = {0, 0, 0, 0, 0, 0, 0};
//https://sourceforge.net/p/freetel/code/HEAD/tree/misc/goertzal/goertzal.c#l256
float goertzal(short x[], int nmax, float coeff) {
int32_t coeff_q14;
int32_t z, zprev, zprev2;
int32_t mult, pz;
int32_t n;
coeff_q14 = (1<<14)*coeff;
zprev = 0;
zprev2 = 0;
for(n=0; n<nmax; n++) {
mult = (int32_t)coeff_q14 * (int32_t)zprev;
z = (x[n]>>6) + (mult>>14) - zprev2;
zprev2 = zprev;
zprev = z;
}
mult = (int32_t)coeff_q14*(int32_t)zprev;
pz = zprev2*zprev2 + zprev*zprev - ((int32_t)(mult>>14))*zprev2;
return (float)pz*pow(2.0,12);
}
float goertzal1(short x[], int nmax, float coeff) {
float s, power;
float sprev, sprev2;
int n;
sprev = 0;
sprev2 = 0;
for(n=0; n<nmax; n++) {
s = x[n] + coeff * sprev - sprev2;
sprev2 = sprev;
sprev = s;
//printf("%f\n", s);
}
power = sprev2*sprev2 + sprev*sprev - coeff*sprev*sprev2;
return power;
}
float calc_q(float freq, float fsamp){
float w, coeff;
w = 2.0 * 3.1415926 * ((float)freq/fsamp);
coeff = 2.0 * cos(w);
return coeff;
}
void sample_adc(){
for(int index = 0; index < N; index++){
sound_data[index] = analogRead(sensorPin);
}
}
void print_adc(){
for(int index = 0; index < N; index++){
Serial.print(sound_data[index]);
Serial.print(' ');
}
Serial.print("\n");
}
void offset_adc(){
float sum;
// Calculate the average value
for(int index = 0; index < N; index++){
sum += sound_data[index];
}
// Offset the data!
sum = sum / N;
//Serial.println(sum);
for(int index = 0; index < N; index++){
sound_data[index] = sound_data[index] - sum;
}
}
void scale_adc(){
for(int index = 0; index < N; index++){
sound_data[index] = sound_data[index] * 2;
}
}
void setup() {
Serial.begin(115200);
strip.Begin();
led_pattern();
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
mesh.setDebugMsgTypes( ERROR | STARTUP ); // set before init() so that you can see startup messages
mesh.init( MESH_PREFIX, MESH_PASSWORD, MESH_PORT );
mesh.onReceive(&receivedCallback);
mesh.onNewConnection(&newConnectionCallback);
mesh.onChangedConnections(&changedConnectionCallback);
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
}
void loop() {
mesh.update();
// get next random time to send a message
if ( sendMessageTime == 0 ) {
sendMessageTime = mesh.getNodeTime() + random( 1000000, 5000000 );
}
// if the time is ripe, send everyone a message!
if ( sendMessageTime != 0 && sendMessageTime < mesh.getNodeTime() ){
String msg = "Hello from node ";
msg += mesh.getNodeId();
mesh.sendBroadcast( msg );
sendMessageTime = 0;
}
sample_adc(); // Fill up the global list with enough adc data.
//print_adc();
offset_adc(); // Remove offset from ADC data
//print_adc();
scale_adc();
// Run the calculations for all of our freq bins and save the results
for(int a=0; a < 7; a++){
float tmp;
float q = calc_q(bins[a], SAMPLING_FREQUENCY);
tmp = goertzal1(sound_data, N, q);
amps[a] = tmp;
Serial.print(tmp, 4);
Serial.print(' ');
}
Serial.print('\n');
uint32_t mesh_time_us = mesh.getNodeTime(); //us time.
uint32_t modtime = mesh_time_us % 1000000;
strip.SetPixelColor( 0, RgbColor( (uint32_t)amps[0]/500, 0, 0 ) );
strip.SetPixelColor( 1, RgbColor( (uint32_t)amps[2]/500, 0, 0 ) );
strip.SetPixelColor( 2, RgbColor( (uint32_t)amps[4]/500, 0, 0 ) );
strip.SetPixelColor( 3, RgbColor( (uint32_t)amps[6]/500, 0, 0 ) );
strip.Show();
}
void led_pattern() {
for ( uint8_t i = 0; i < NPLEN; i++ ) {
strip.SetPixelColor(i, RgbColor( 0, 0, 0 ) );
}
strip.Show();
}
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
}
void newConnectionCallback(uint32_t nodeId) {
Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}
void changedConnectionCallback() {
Serial.printf("Changed connections %s\n",mesh.subConnectionJson().c_str());
}
void nodeTimeAdjustedCallback(int32_t offset) {
Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment