【花雕动手做】有趣好玩的音乐可视化项目(03)---RGB律动灯
项目之一:Arduino 的 HSV 淡入淡出/反弹律动灯
实验开源代码
- /*
- 【花雕动手做】有趣好玩的音乐可视化项目(03)---RGB律动灯
- 项目之一:Arduino 的 HSV 淡入淡出/反弹律动灯
- 实验接线: max9814接A0,蓝色LED接D13
- RGB模块 Ardunio Uno
- GND---------GND接地线
- Rpin D9
- Gpin D10
- Bpin D11
- */
-
- #define Indicator_LED 13
- #define RED 9 // pin for red LED
- #define GREEN 10 // pin for green - never explicitly referenced
- #define BLUE 11 // pin for blue - never explicitly referenced
- #define MIC A0//8 // Microphone
- #define SIZE 220
- #define DELAY 20
- #define HUE_MAX 5.0
- #define HUE_DELTA 0.01//0.01
-
- /*TEST autogain code*/
- const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
- unsigned int sample;
- uint8_t volume = 0;
- /*///////////////////*/
-
- //long deltas[3] = { 5, 6, 7 };
- long rgb[3];
- long rgbval;
- //float rand;
- boolean flag = false;
-
- int val;
- // for reasons unknown, if value !=0, the LED doesn't light. Hmm ...
- // and saturation seems to be inverted
- float hue = 0.0, last_hue = 0.0, saturation = 1, value = 1;
-
- /*
- chosen LED SparkFun sku: COM-09264
- has Max Luminosity (RGB): (2800, 6500, 1200)mcd
- so we normalize them all to 1200 mcd -
- R 250/600 = 107/256
- G 250/950 = 67/256
- B 250/250 = 256/256
- */
- long bright[3] = { 107, 67, 256};
- //long bright[3] = { 256, 256, 256};
-
- long k, temp_value;
-
- void setup () {
- pinMode(Indicator_LED, OUTPUT);
- digitalWrite(Indicator_LED, LOW);
-
- //Serial.begin(9600);/*Tempo*/
-
- randomSeed(analogRead(4));
- for (k = 0; k < 3; k++) {
- pinMode(RED + k, OUTPUT);
- rgb[k] = 0;
- analogWrite(RED + k, rgb[k] * bright[k] / 256);
- }
- //pinMode(MIC, INPUT);
- }
-
- void loop() {
- /*TEST autogain code*/
- unsigned long startMillis = millis(); // Start of sample window
- unsigned int peakToPeak = 0; // peak-to-peak level
-
- unsigned int signalMax = 0;
- unsigned int signalMin = 1024;
-
- // collect data for 50 mS
- while (millis() - startMillis < sampleWindow)
- {
- sample = analogRead(MIC);
- if (sample < 1024) // toss out spurious readings
- {
- if (sample > signalMax)
- {
- signalMax = sample; // save just the max levels
- }
- else if (sample < signalMin)
- {
- signalMin = sample; // save just the min levels
- }
- }
- }
- peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude
- double volts = (peakToPeak * 5.0) / 1024; // convert to volts
- bool pulse = (sample - signalMin) > (peakToPeak * 0.50) && peakToPeak > 130;
- //Serial.println(peakToPeak);
- /*if(pulse){
- }*/
- /*///////////////////*/
-
- //flag = false
- //val = digitalRead(MIC);//Board bleu
- //val = !digitalRead(MIC);//Board Rouge
-
- if ( /*volume > 0*/peakToPeak >= 260/*pulse*/)
- {
- /*if(flag)
- {
- digitalWrite(Indicator_LED, HIGH);
- }
- else
- {
- digitalWrite(Indicator_LED, LOW);
- }
- flag = !flag;*/
-
- do
- {
- hue = random(601) / 100;
- } while (hue == last_hue);//break only when value is different
- last_hue = hue;
-
- //hue += HUE_DELTA;
- digitalWrite(Indicator_LED, HIGH);
- delay(50);
- digitalWrite(Indicator_LED, LOW);
- }
- /*hue += HUE_DELTA;
- if (hue > HUE_MAX) {
- hue=0.0;
- }*/
- rgbval = HSV_to_RGB(hue, saturation, value);
- rgb[0] = (rgbval & 0x00FF0000) >> 16; // there must be better ways
- rgb[1] = (rgbval & 0x0000FF00) >> 8;
- rgb[2] = rgbval & 0x000000FF;
- for (k = 0; k < 3; k++) { // for all three colours
- analogWrite(RED + k, rgb[k] * bright[k] / 256);
- }
-
- /* //If there is a decent change in volume since the last pass, average it into "avgBump"
- if (volume - last > 10) avgBump = (avgBump + (volume - last)) / 2.0;
- //If there is a notable change in volume, trigger a "bump"
- // avgbump is lowered just a little for comparing to make the visual slightly more sensitive to a beat.
- bump = (volume - last > avgBump * .9);
- //If a "bump" is triggered, average the time between bumps
- if (bump) {
- avgTime = (((millis() / 1000.0) - timeBump) + avgTime) / 2.0;
- timeBump = millis() / 1000.0;
- }*/
-
- //delay(DELAY);
- }
-
- long HSV_to_RGB( float h, float s, float v ) {
- /* modified from Alvy Ray Smith's site: http://www.alvyray.com/Papers/hsv2rgb.htm */
- // H is given on [0, 6]. S and V are given on [0, 1].
- // RGB is returned as a 24-bit long #rrggbb
- int i;
- float m, n, f;
-
- // not very elegant way of dealing with out of range: return black
- if ((s < 0.0) || (s > 1.0) || (v < 0.0) || (v > 1.0)) {
- return 0L;
- }
-
- if ((h < 0.0) || (h > 6.0)) {
- return long( v * 255 ) + long( v * 255 ) * 256 + long( v * 255 ) * 65536;
- }
- i = floor(h);
- f = h - i;
- if ( !(i & 1) ) {
- f = 1 - f; // if i is even
- }
- m = v * (1 - s);
- n = v * (1 - s * f);
- switch (i) {
- case 6:
- case 0:
- return long(v * 255 ) * 65536 + long( n * 255 ) * 256 + long( m * 255);
- case 1:
- return long(n * 255 ) * 65536 + long( v * 255 ) * 256 + long( m * 255);
- case 2:
- return long(m * 255 ) * 65536 + long( v * 255 ) * 256 + long( n * 255);
- case 3:
- return long(m * 255 ) * 65536 + long( n * 255 ) * 256 + long( v * 255);
- case 4:
- return long(n * 255 ) * 65536 + long( m * 255 ) * 256 + long( v * 255);
- case 5:
- return long(v * 255 ) * 65536 + long( m * 255 ) * 256 + long( n * 255);
- }
- }
复制代码
|