#include "bhoreal.h" #include "Adafruit_NeoPixel.h" // Variables for interpreting the serial commands byte tempR; byte tempC; byte lastread; byte command = 0; byte ready = true; uint16_t IntensityMAX = 100; // Default draw colour. Each channel can be between 0 and 4095. int red = 0; int green = IntensityMAX; int blue = 0; // Auxiliary analog output definitions #define ANALOG0 A5 //POTENCIOMETRO #define ANALOG1 A1 boolean adc[2] = { //On or off state 0, 0}; byte analogval[2]; //The last reported value byte tempADC; //Temporary storage for comparison purposes uint16_t MODEL = MINISLIM; //Modelo uint16_t MAX = 4; int NUM_LEDS = 16; #define PIN 11 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800); boolean pressed[8][8] = { {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1} }; byte remap[8][8] = { {48,49,51,52, 12,13,14,15}, {50,53,54,55, 11,10, 9, 8}, {56,57,58,59, 7, 6, 5, 2}, {63,62,61,60, 4, 3, 1, 0}, {32,33,35,36, 28,29,30,31}, {34,37,38,39, 27,26,25,24}, {40,41,42,43, 23,22,21,18}, {47,46,45,44, 20,19,17,16}, }; const byte remapmini[4][4] = { {3, 4, 11, 12}, {2, 5, 10, 13}, {1, 6, 9, 14}, {0, 7, 8, 15}, }; int levelR[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int levelG[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int levelB[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte row[4] = {13, 5, 10, 9}; byte column[4] = {8, 6, 12, 4}; void Bhoreal::begin(uint16_t DEVICE, uint32_t BAUD) { for(byte x = 0; x < MAX; ++x){ for(byte y = 0; y = 0; r--) { if(pressed[c][r] != digitalRead(column[r])) { // read the state pressed[c][r] = digitalRead(column[r]); if(pressed[c][r]) on_press(c, r); else on_release(c, r); } } digitalWrite(row[c],LOW); } } // Run this animation once at startup. Currently unfinished. void Bhoreal::startup(){ for(byte x = 0; x < MAX; ++x){ for(byte y = 0; y < MAX; ++y) { //levelR[remap[x][y]] = 0; levelR[remap[x][0]] = IntensityMAX; levelB[remap[0][y]] = IntensityMAX; levelG[remap[x][y]] = IntensityMAX; } } for(int x = 0; x < NUM_LEDS; ++x) strip.setPixelColor(x, levelR[x], levelG[x], levelB[x]); strip.show(); } void Bhoreal::checkADC(){ // For all of the ADC's which are activated, check if the analog value has changed, // and send a message if it has. if(adc[0]){ tempADC = (analogRead(ANALOG0) >> 2); if(abs((int)analogval[0] - (int)tempADC) > 3 ){ analogval[0] = tempADC; Serial.write(14 << 4); Serial.write(analogval[0]); } } if(adc[1]){ if(analogval[1] != (analogRead(ANALOG1) >> 2)){ analogval[1] = (analogRead(ANALOG1) >> 2); Serial.write(14 << 4 | 1); Serial.write(analogval[1]); } } } /*TIMER*/ ISR(TIMER3_OVF_vect) { //sei(); //Reenable global interrupts, otherwise serial commands will get dropped // makemagic(); do{ // This do ensures that the data is always parsed at least once per cycle if(Serial.available()){ if(ready){ // If the last command has finished executing, read in the next command and reset the command flag command = Serial.read(); ready = false; } switch (command >> 4) { //Execute the appropriate command, but only if we have received enough bytes to complete it. We might one day add "partial completion" for long command strings. case 1: // set colour if( Serial.available() > 2 ) { red = Serial.read(); green = Serial.read(); blue = Serial.read(); ready=true; } break; case 2: // led_on if( Serial.available() ) { lastread = Serial.read(); tempR = lastread >> 4; tempC = lastread & B1111; if ((tempR < MAX)&&(tempC < MAX)) { levelR[remap[tempC][tempR]] = red; levelG[remap[tempC][tempR]] = green; levelB[remap[tempC][tempR]] = blue; strip.setPixelColor(remap[tempC][tempR], red, green, blue); strip.show(); } ready = true; } break; case 3: // led_off if( Serial.available() ) { lastread = Serial.read(); tempR = lastread >> 4; tempC = lastread & B1111; if ((tempR < MAX)&&(tempC < MAX)) { levelR[remap[tempC][tempR]] = 0; levelG[remap[tempC][tempR]] = 0; levelB[remap[tempC][tempR]] = 0; strip.setPixelColor(remap[tempC][tempR], 0, 0, 0); strip.show(); } ready = true; } break; case 4: // led_row1 if( Serial.available() ) { tempR = command & B1111; lastread = Serial.read(); if (tempR < MAX) { for(tempC = 0; tempC < MAX; ++tempC){ if(lastread & (1 << tempC) ){ levelR[remap[tempR][tempC]] = red; levelG[remap[tempR][tempC]] = green; levelB[remap[tempR][tempC]] = blue; strip.setPixelColor(remap[tempR][tempC], red, green, blue); } else { levelR[remap[tempR][tempC]] = 0; levelG[remap[tempR][tempC]] = 0; levelB[remap[tempR][tempC]] = 0; strip.setPixelColor(remap[tempR][tempC], 0, 0, 0); } } strip.show(); } ready = true; } break; case 5: // led_col1 if( Serial.available() ) { tempC = command & B1111; lastread = Serial.read(); if (tempC < MAX) { for(tempR = 0; tempR < MAX; ++tempR){ if(lastread & (1 << tempR) ){ levelR[remap[tempR][tempC]] = red; levelG[remap[tempR][tempC]] = green; levelB[remap[tempR][tempC]] = blue; strip.setPixelColor(remap[tempR][tempC], red, green, blue); } else { levelR[remap[tempR][tempC]] = 0; levelG[remap[tempR][tempC]] = 0; levelB[remap[tempR][tempC]] = 0; strip.setPixelColor(remap[tempR][tempC], 0, 0, 0); } } strip.show(); } ready = true; } break; case 8: //frame if( Serial.available() > 7 ) { for(tempR=0; tempR < MAX; ++tempR){ lastread = Serial.read(); for(tempC = 0; tempC < MAX; ++tempC){ if(lastread & (1 << tempC) ){ levelR[remap[tempR][tempC]] = red; levelG[remap[tempR][tempC]] = green; levelB[remap[tempR][tempC]] = blue; strip.setPixelColor(remap[tempR][tempC], red, green, blue); } else { levelR[remap[tempR][tempC]] = 0; levelG[remap[tempR][tempC]] = 0; levelB[remap[tempR][tempC]] = 0; strip.setPixelColor(remap[tempR][tempC], 0, 0, 0); } } strip.show(); } ready = true; } break; case 9: //clear if(command & 1){ byte TEMPMAX = MAX*MAX; for(int x = 0; x< TEMPMAX;++x){ levelR[x] = red; levelG[x] = green; levelB[x] = blue; strip.setPixelColor(x, red, green, blue); } strip.show(); } else{ byte TEMPMAX = MAX*MAX; for(int x = 0; x< TEMPMAX;++x){ levelR[x] = 0; levelG[x] = 0; levelB[x] = 0; strip.setPixelColor(x, 0, 0, 0); } strip.show(); } ready = true; break; case 12: switch(command & 15){ case 0: adc[0] = true; analogval[0] = (analogRead(ANALOG0) >> 2); Serial.write(14 << 4); Serial.write(analogval[0]); break; case 1: adc[1] = true; analogval[1] = (analogRead(ANALOG1) >> 2); Serial.write(14 << 4 | 1); Serial.write(analogval[1]); break; default: break; } ready = true; break; case 13: adc[command & 15] = false; ready = true; break; default: break; } } } // If the serial buffer is getting too close to full, keep executing the parsing until it falls below a given level // This might cause flicker, or even dropped messages, but it should prevent a crash. while (Serial.available() > TOOFULL); } void Bhoreal::timer3Initialize() { TCCR3A = 0; TCCR3B = 0<