Blame | Last modification | View Log | RSS feed
#include <Encoder.h>// Delays for certain events in msconst int ROTARY_DELAY = 100; // Time between checking for rotary turnsconst int BUTTON_DELAY = 800; // Button debouncing, and repeatingconst int FLASH_DELAY = 600; // How long to flash the entire row after button pressconst int CURSOR_DELAY = 200; // How quickly to flash the cursor led// Pin Assignmentsuint8_t rota = 2;uint8_t rotb = 3;uint8_t button = 4;uint8_t dataIn = 5;uint8_t load = 6;uint8_t clock = 7;uint8_t trigger = 12;int maxInUse = 1;uint8_t x = 0;byte max7219_reg_noop = 0x00;byte max7219_reg_digit0 = 0x01;byte max7219_reg_digit1 = 0x02;byte max7219_reg_digit2 = 0x03;byte max7219_reg_digit3 = 0x04;byte max7219_reg_digit4 = 0x05;byte max7219_reg_digit5 = 0x06;byte max7219_reg_digit6 = 0x07;byte max7219_reg_digit7 = 0x08;byte max7219_reg_decodeMode = 0x09;byte max7219_reg_intensity = 0x0a;byte max7219_reg_scanLimit = 0x0b;byte max7219_reg_shutdown = 0x0c;byte max7219_reg_displayTest = 0x0f;Encoder knobLeft(rota, rotb);char id=0;void putByte(byte data) {byte i = 8;byte mask;while(i > 0) {mask = 0x01 << (i - 1); // get bitmaskdigitalWrite( clock, LOW); // tickif (data & mask){ // choose bitdigitalWrite(dataIn, HIGH);// send 1}else{digitalWrite(dataIn, LOW); // send 0}digitalWrite(clock, HIGH); // tock--i; // move to lesser bit}}void maxSingle( byte reg, byte col) {//maxSingle is the "easy" function to use for a //single max7219digitalWrite(load, LOW); // beginputByte(reg); // specify registerputByte(col);//((data & 0x01) * 256) + data >> 1); // put datadigitalWrite(load, LOW); // and load da shitdigitalWrite(load,HIGH);}void maxAll (byte reg, byte col) { // initialize all MAX7219's in the systemint c = 0;digitalWrite(load, LOW); // beginfor ( c =1; c<= maxInUse; c++) {putByte(reg); // specify registerputByte(col);//((data & 0x01) * 256) + data >> 1); // put data}digitalWrite(load, LOW);digitalWrite(load,HIGH);}void maxOne(byte maxNr, byte reg, byte col) {//maxOne is for adressing different MAX7219's,//whilele having a couple of them cascadedint c = 0;digitalWrite(load, LOW); // beginfor ( c = maxInUse; c > maxNr; c--) {putByte(0); // means no operationputByte(0); // means no operation}putByte(reg); // specify registerputByte(col);//((data & 0x01) * 256) + data >> 1); // put datafor ( c =maxNr-1; c >= 1; c--) {putByte(0); // means no operationputByte(0); // means no operation}digitalWrite(load, LOW); // and load da shitdigitalWrite(load,HIGH);}void setup () {pinMode(dataIn, OUTPUT);pinMode(clock, OUTPUT);pinMode(load, OUTPUT);pinMode(button, INPUT);pinMode(trigger, OUTPUT);digitalWrite(button, HIGH);digitalWrite(13, LOW);digitalWrite(trigger, LOW);//initiation of the max 7219maxAll(max7219_reg_scanLimit, 0x07);maxAll(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)maxAll(max7219_reg_shutdown, 0x01); // not in shutdown modemaxAll(max7219_reg_displayTest, 0x00); // no display testfor (x=1; x<=8; x++) { // empty registers, turn all LEDs offmaxAll(x,0);}maxAll(max7219_reg_intensity, 0x01 & 0x0f); // the first 0x0f is the value you can set range: 0x00 to 0x0f}// Value to display a single LED on a rowuint8_t values[9] = {0, 1, 2, 4, 8, 16, 32, 64, 128};// Array with all rows, indicating which 'value' to showuint8_t line[8] = {0, 0, 0, 0, 0, 0, 0, 0};// What row we are current working withuint8_t idx = 0;// Our delay counters (in ms)int delayButton = 0;int delayRotary = ROTARY_DELAY;int delayFlash = 0;int delayCursor = CURSOR_DELAY;int cursorState = 0;// Rotary position, reset after each looplong pos = 0;// Do we update the matrix this run?uint8_t update = 1;void loop () {// Flash the row after a button pressif (delayFlash && idx != 8) {maxSingle(idx+1, 255);if (delayFlash == 1) {maxSingle(idx+1, values[line[idx+1]]);}delayFlash--;if (delayButton) delayButton--;return;}// Check for button pressif (delayButton) delayButton--;if (!digitalRead(4) && delayButton == 0) {if (idx == 8)idx = 0;elseidx++;delayButton = BUTTON_DELAY;delayFlash = FLASH_DELAY;}// Checks for rotary turning, and update// the matrix buffer// My rotary encoder had '2 turns' per detent, making// it awkward to move a single position. This is why// the check is for > 1 and < -1 to make it a full detent.if (delayRotary) delayRotary--;if (delayRotary == 0 && idx != 8) {pos = knobLeft.read();if (pos > 1) {if (line[idx] != 0)line[idx]--;elseline[idx] = 8;update = 1;} else if (pos < -1) {if (line[idx] != 8)line[idx]++;elseline[idx]= 0;update = 1;}if (update) {knobLeft.write(0);delayRotary = ROTARY_DELAY;if (pos) {cursorState = 1;delayCursor = CURSOR_DELAY;}}}// Toggle the state of the cursor after the// cursor delay (in ms) has been reachedif (delayCursor) delayCursor--;if (delayCursor == 0 && idx != 8) {delayCursor = CURSOR_DELAY;cursorState = 1 - cursorState;update = 1;}// Update the matrix only if a change has been madeif (update) {for (x = 0; x<8; x++) {if (x == idx) {if (cursorState && line[x] != 0)maxSingle(x+1, values[line[x]]);elsemaxSingle(x+1, 0);} else {if (line[x] == 0) continue;digitalWrite(trigger, HIGH);maxSingle(x+1, values[line[x]]);digitalWrite(trigger, LOW);}}update = 0;}delay(1);}