This program has three modes: clock, sound and text. The mode button toggles between the different modes. The code for each mode is explained in more detail in their respective tutorials: see the
Heart Matrix Clock
and the
Sound Sensing Heart Matrix
tutorials for example. Here we wrap the clock and sound logic in their own functions. This allows us to have a very simple main loop that dispatches to the proper function based on the current mode:
void loop() { if(mode == 0) sound_display(); else if(mode == 1) clock_display(); else if(mode == 2) text_display(); check_buttons();}
The check_buttons() function checks to see if the mode button was pressed or if the potentiometer was spun to change the scrolling speed:
void check_buttons(){ if(digitalRead(9) == HIGH && millis() - last_press > 250){ mode = ++mode % num_modes; last_press = millis(); } hm.set_scroll_wait(max(20, analogRead(0)/4)); }
The variable
last_press
is an unsigned long and it is used to debounce the button press. This is necessary because the arduino is looping through the main function far faster than our fingers move over the buttons. So the check_Buttons function might be called many times during a single button push. The last_press variable and the check:
millis() - last_press > 250
in the if statement prevents the mode from changing if it has already changed once in the past 250 milliseconds. See the entire code below.
/* LucidTronix Heart Matrix LEO LED Display. * Demoing the heart matrix clock and sound sensor * For instructions details and schematic, See: * http://www.lucidtronix.com/tutorials/57 */#include #include #include #include // dataPin is on 5, Latch is on 6, and clock is on 7HeartMatrix hm = HeartMatrix(5,6,7);MCP79410 clock = MCP79410();int mode = 0;int num_modes = 3;unsigned long last_press = 0;// clock global variablesString stime = "";unsigned int last_update = 0;// sound global variablesconst int buffer_size = 15;int noises[buffer_size];const int num_cols = 10;int volumes[num_cols];int cur_index = 0;unsigned long last_shift = 0;int mic_pin = 1;int delay_speed = 40;unsigned long max_var = 0;unsigned long min_var = 99999999;void setup() { Serial.begin(9600); MsTimer2::set(1,displayer2); MsTimer2::start(); for (int i = 0 ; i < num_cols; i++) volumes[i] = 8; for (int i = 0 ; i < buffer_size; i++) noises[i] = random(300,612); hm.animate(); Wire.begin(); //clock.setDateTime(__DATE__,__TIME__);}void loop() { if(mode == 0) sound_display(); else if(mode == 1) clock_display(); else if(mode == 2) text_display(); check_buttons();}void displayer2(){ hm.displayer();}void check_buttons(){ if(digitalRead(9) == HIGH && millis() - last_press > 250){ mode = ++mode % num_modes; if(mode == 0) hm.animate(); if(mode == 2) hm.set_message(" Hello I'm the Heart Matrix! "); last_press = millis(); } hm.set_scroll_wait(max(20, analogRead(0)/4)); }void text_display(){ hm.on(); }void clock_display(){ hm.on(); if (millis() - last_update > 1000){ stime = " "; byte a_hour = clock.hour24(); String a_hour_s = String(a_hour,HEX); int hour_int = a_hour_s.toInt(); String ampm = "am "; if (hour_int >= 12){ ampm = "pm "; hour_int -= 12; a_hour_s = String(hour_int); } if (a_hour == 0 || a_hour == 12 ) stime += String(12); else stime += a_hour_s; stime += ":"; byte a_min = clock.minute(); if (a_min < 10 ) stime += String(0); stime += String(a_min,HEX); stime += ":"; byte a_sec = clock.second(); if (a_sec < 10 ) stime += String(0); stime += String(a_sec,HEX); hm.set_message(stime+ampm ); last_update = millis(); }}void sound_display(){ // Get a value from the electret microphone noises[cur_index] = analogRead(mic_pin) ; cur_index++; if(cur_index == buffer_size) cur_index = 0; // Control the scroll speed with a potentiometer on analog pin 0 delay_speed = max(10, (analogRead(0)/4)); // Shift the waveform over one column if (millis() - last_shift > delay_speed){ last_shift = millis(); unsigned int avg = average(noises, buffer_size); unsigned long var = variance(noises, buffer_size); max_var = max(var, max_var); min_var = min(var, min_var); var = map(var,min_var , max_var, 0, 9); for (int i = 1 ; i < num_cols; i++){ volumes[i-1] = volumes[i]; } volumes[num_cols-1] = var; } // Write the wave form to LED display for (int i = 0 ; i < num_cols; i++){ for (int j = 0 ; j < volumes[i]; j++){ hm.set_pixel(i, j, true); } for (int j = volumes[i] ; j < 8; j++){ hm.set_pixel(i, j, false); } } }int average(int* array, int length){ int sum = 0; int i; for(i = 0; i < length ; i++){ sum += array[i]; } int avg = sum / length ; return avg;}unsigned long variance(int* array, int length){ long sum = 0; long avg = average(array, length); for(int i = 0; i < length ; i++){ sum += (array[i] - avg)*(array[i] - avg); } unsigned long var = sum / length; return var;}