Water-like simulation for miniblip

Dependencies:   PixelArray mbed

main.cpp

Committer:
erpheus
Date:
2016-01-23
Revision:
0:ba73ace939cd

File content as of revision 0:ba73ace939cd:

// miniblip led matrix demo

#include "mbed.h"
#include "neopixel.h"

// Matrix led output pin
#define DATA_PIN P0_9
#define NLEDS 25

AnalogIn b1(P0_11);
AnalogIn b2(P0_12);
AnalogIn b3(P0_13);
AnalogIn b4(P0_14);
AnalogIn b5(P0_15);

PwmOut speaker(P0_8);

#define WIDTH 1.2
#define SPEED 8.0 // depends on tick_freq
#define POWER 50

#define tick_freq 20.0
#define maxdistance 8 // ceil(sqrt(5^2+5^2))   5 = width = height

neopixel::PixelArray array(DATA_PIN);
neopixel::Pixel buffer[NLEDS];

AnalogIn buttons[5] = {b1,b2,b3,b4,b5};

void setPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
  if(x < 0 || x > 4 || y < 0 || y > 4) return;
  int posicion=x+y*5;
  buffer[posicion].red=red;
  buffer[posicion].green=green;
  buffer[posicion].blue=blue;
}

unsigned int counter = 0;

unsigned int waves[5] = {0,0,0,0,0};

void checkButton(){
    int i;
    for (i = 0; i < 5; i++){
        if (waves[i] && (counter - waves[i]) > (maxdistance * tick_freq / SPEED)){
            waves[i]=0;
        }else if(!waves[i]){
            if (buttons[i].read() == 0.00){
                waves[i] = counter;
            }
        }
    }
}

void count(void){
    counter++;
    checkButton();
}


struct position {
    int x, y;
};

struct color {
    uint8_t red, green, blue;  
};

float distance(position pos1, position pos2){
    return sqrt(pow((pos1.x - pos2.x)*1.0,2.0)+pow((pos1.y - pos2.y)*1.0,2.0));
}



position startpositions[5] = {{3,-1},{-1,0},{-2,2},{-1,4},{0,5}}; 

color colorForPixel(unsigned int* waves, position p){
    int colors[3] = {0,0,0};
    int i;
    float d, wave_spread, delta;
    for(i = 0; i < 5; i++){
        if (waves[i]==0){ continue; }
        d = distance(startpositions[i],p);
        wave_spread = ((counter - waves[i])*SPEED)/tick_freq;
        delta = d - wave_spread;
        if (delta > WIDTH || delta < -WIDTH) {
            continue;
        }
        colors[i%3] = colors[i%3] + sinf((WIDTH-fabs(delta))/WIDTH * 3.141592/2) * POWER ;
        /*if (colors[i%3] > 255) {
            colors[i%3] = 255;
        }*/

    }
    color res = {0,0,0};
    res.red = colors[0];
    res.green = colors[1];
    res.blue = colors[2];
    return res;
}

Ticker tick;

int main() {
    
    speaker = 0.0;
    
    tick.attach(count, 1.0 / tick_freq);
    
    
    
    
    int i,j;
    position p;
    
    while(true){
        
        for(i=0; i<5; i++){
            for(j=0; j<5; j++){
                p.x = i;
                p.y = j;
                color c = colorForPixel(waves,p);
                setPixel(i, j, c.red, c.green, c.blue);        
            }
        }
        array.update(buffer, NLEDS);
        wait_ms(1);
    }
}