Advertisement
Guest User

Untitled

a guest
Jan 19th, 2020
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.08 KB | None | 0 0
  1. /*
  2.  * "ArduinomeFirmware" - Arduino Based Monome Clone by Owen Vallis & Jordan Hochenbaum 06/16/2008
  3.  * Revised 06/26/2008
  4.  * Revised 07/20/2008 by Ben Southall
  5.  * Revised 03/21/2009 Ben Southall
  6.  * Revised 01/21/2012 Jordan Hochenbaum v3.3 rev.a
  7.  * --------------------------------------------------------------------------
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  * --------------------------------------------------------------------------
  18.  *
  19.  * This code is largely a direct translation of the 40h protocol designed by Brian Crabtree
  20.  * & Joe Lake, and coded by Joe Lake.  We would like to express our utmost thanks for making
  21.  * the monome & its inner-workings available and open source.  We would also like to extend
  22.  * our thanks to all those who have helped us get this far in successfully making an arduino-
  23.  * based monome clone, including but not limited to Brad Hill for his awesome arduino shield,
  24.  * and Melka for showing how to pack and unpack the serial data.
  25.  *
  26.  * Additional comment and attribution 7/20/2008 :
  27.  * The changes on 7/20/2008 were inspired by, and at least in some part, directly
  28.  * copied from the 'Octinct' code written by Jonathan M Guberman (upwardnotnorthward.com).  
  29.  * In particular, the use of timer 2 to drive an interrupt routine to read the serial port was
  30.  * picked up from the Octinct project, and also, setting the baud rate to 57600 seemed to be
  31.  * critical for getting everything to work reliably.  My thanks to Jonathan for sharing his
  32.  * software, and for figuring out how to keep that serial buffer in check.
  33.  *
  34.  * Changes 03/21/2009
  35.  *
  36.  * Added ADC support for arduino ADCs 0 - 3.  Thanks to Josh Lory for the first cut of the code for
  37.  * this.  Added handling of the ADC enable/disable serial messages, and changed Josh's checkADC code
  38.  * to loop through the 4 ADCs rather than read each one individually.  Also, cleaned up a number of
  39.  * unused variables, and moved all PORT/pin definitions to the top of the file; this should make it
  40.  * easier for people not using the unsped shield to change the hardware connections.
  41.  *
  42.  * Please DO NOT email monome with technical questions and/or help regarding this code or clone.  
  43.  * They are in NO WAY responsible or affiliated with this project other than they were our inspiration
  44.  * and we used many of their methods and pulled from their code.
  45.  *
  46.  * Additionally, while we are availble and willing to help as much as possible, we too CANNOT be held
  47.  * responsible for anything you do with this code.  Please feel free to report any bugs, suggestions
  48.  * or improvements to us as they are all welcome.  Again, we cannot be held responsible for any damages
  49.  * or harm caused by the use or misuse of this code or our instructions.  Thank you for understanding.
  50.  *
  51.  *
  52.  *
  53.  *
  54.  * Changes 01/21/2012 & 3.3a
  55.  * Arduino 1.0+ compatability (uses .ino extension and no longer specifies BYTE type in Serial.write)
  56.  * --------------------------------------------------------------------------
  57.  *
  58.  * Links:
  59.  * http://www.flipmu.com - Our website - Click "Work/Arduinome" on the Navigation Menu on the top.
  60.  * www.monome.org - the "original" monome and our inspiration
  61.  * www.flickr.com/photos/unsped/2283428540/in/photostream/
  62.  * http://play-collective.net/blog/archives/category/arduinomonomergb
  63.  *
  64.  */
  65.  
  66. // PIN and PORT assignments
  67. // If you're using hardware other than the unsped shield, you'll want to go through this portion of the code,
  68. // and change the pin numbers and atmega 168 PORTs that you're using.  We're using pin/PORT assignments here,
  69. // NOT the pin number scheme from the arduino board outputs (e.g. arduino digital pin 8 = PORTB pin 1)
  70. // However, in the comments below, I do give the equivalents between arduino digital pin numbers and the
  71. // atmega168's PORT/bit numbering.
  72.  
  73. // IMPORTANT - you'll need to make sure that you set the data following two direction register variables to match your
  74. // pin assignments.
  75. byte PORTD_Data_Direction = 0xFE; // 11111110
  76. byte PORTB_Data_Direction = 0xFD; // 11111101
  77.  
  78.  
  79. // Connections to the 164 shift register
  80. //  dataPin = 3 = PORTD, bit 3
  81. // clockPin = 2 = PORTD, bit 2
  82. #define DATA_PORT_164 (PORTD)
  83. byte dataPin = 3;
  84. byte dataPinMaskHigh = 1 << dataPin;
  85. byte dataPinMaskLow = ~dataPinMaskHigh;
  86.  
  87. #define CLOCK_PORT_164 (PORTD)
  88. byte ClockPin = 2;
  89. byte clockPinMaskHigh = 1 << ClockPin;
  90. byte clockPinMaskLow = ~clockPinMaskHigh;
  91. // end connections to the 164 shift register
  92.  
  93. // Connections to the 165 shift register
  94. //  inloadPin = arduino digital pin 8 = PORTB, bit 0
  95. // indataPin = arduino digital pin 9 = PORTB, bit 1
  96. // inclockPin = arduino digital pin 7 = PORTD, bit 7
  97. #define LOAD_PORT_165 (PORTB)
  98. byte inloadPin = 0;
  99. byte inloadPinMaskHigh = 1 << inloadPin;
  100. byte inloadPinMaskLow = ~inloadPinMaskHigh;
  101.  
  102. #define INPUT_DATA_PORT_165 (PINB)
  103. byte indataPin = 1;
  104. byte indataPinMask = 1 << indataPin;
  105.  
  106. #define CLOCK_PORT_165 (PORTD)
  107. byte inclockPin = 7;
  108. byte inclockPinMaskHigh = 1 << inclockPin;
  109. byte inclockPinMaskLow = ~inclockPinMaskHigh;
  110. // end connections to the 165 shift register
  111.  
  112. // Connections to the Max7219 (drives LEDS)
  113. // dataIn = arduino pin 4 = PORTD, bit 4
  114. // load = arduino pin 5 = PORTD bit 5
  115. // clock = arduino pin 6 = PORTD, bit 6
  116. #define LED_DATA_PORT (PORTD)
  117. byte MaxDataPin = 4;
  118. byte DataMaskHigh = 1 << MaxDataPin;
  119. byte DataMaskLow = ~DataMaskHigh;
  120.  
  121. #define LED_CLOCK_PORT (PORTD)
  122. byte MaxClockPin = 6;
  123. byte ClockMaskHigh = 1<<MaxClockPin;
  124. byte ClockMaskLow = ~ClockMaskHigh;
  125.  
  126. #define LED_LOAD_PORT (PORTD)
  127. byte MaxLoadPin = 5;
  128. byte LoadMaskHigh = 1 << MaxLoadPin;
  129. byte LoadMaskLow = ~LoadMaskHigh;
  130. // end connections to the 165 shift register
  131.  
  132.  
  133.  
  134.  
  135. // END pin and PORT assignments
  136.  
  137. // ----------------------------
  138.  
  139. // Global variables
  140.  
  141. byte byte0, byte1;                      // storage for incoming serial data
  142.  
  143. byte WaitingForAddress = 1;             // 1 when we expect the next serial byte to be an address value, 0 otherwise
  144.  
  145. byte address =  0x00;                   // garbage byte to hold address of function
  146. byte state = 0x00;                      // garbage byte to hold state value
  147. byte x = 0x00;                          // garbage byte to hold x position
  148. byte y = 0x00;                          // garbage byte to hold y position
  149. byte z = 0x00;                          // garbage byte to iterate over buttons
  150.  
  151. // The following variables are used to store flags that indicate whether we have received a given message,
  152. // the value of the data in that message.  e.g. IntensityChange = 0 == no intensity change message received,
  153. // IntensityChange = 1 == an intensity change message has been received, and it's value will be in IntensityVal
  154. // The code that eventually acts upon the incoming message will reset the 'Change' variable to 0 once the
  155. // message has been handled.
  156.  
  157. byte IntensityChange = 0;              
  158. byte IntensityVal = 0;                  
  159.  
  160. byte DisplayTestChange = 0;            
  161. byte DisplayTestVal = 0;                
  162.  
  163. byte ShutdownModeChange = 0;            
  164. byte ShutdownModeVal= 0;
  165.  
  166. // These variables are used to handle the ADC messages, and store which ports are currently enabled,
  167. // and which are not.
  168. byte ADCnum;
  169. byte ADCstate;
  170. byte ADCEnableState[4];
  171.  
  172. byte ledmem[8];                         // memory for LED states - 64 bits.
  173.  
  174. int b = 0;                              // temporary variable used in transmission of button presses/releases
  175. int i = 0;                              // temporary variable for looping etc.
  176. int id = 0;                             // temporary storage for incoming message ID
  177. byte firstRun = 1;                      // 1 when we have yet to receive an LED command, 0 after that.
  178.                                         // used to ensure that our led state memory is properly initialized when we receive the first LED message
  179.  
  180. int kButtonUpDefaultDebounceCount   = 12;  // Used in button debouncing
  181.  
  182. int kButtonNewEvent   = 1;              // Used to store whether the state of a button has changed or not.
  183.  
  184. byte t = 0;                            // temporary variable used in button processing
  185.  
  186. /* BUTTON ARRAY VARIABLES
  187.  
  188.  For 1/0 button states, use 8 bytes (64 bits)
  189.  For button debounce counter, use 8x8 array
  190.  
  191.  */
  192. byte button_current[8];
  193. byte button_last[8];
  194. byte button_state[8];
  195. byte button_debounce_count[8][8];
  196. byte button_event[8];
  197. /* END OF BUTTON ARRAY VARIABLES */
  198.  
  199. /* MAX 7219 INSTRUCTION ADDRESSES */
  200.  
  201. byte max7219_reg_noop        = 0x00;    // define max7219 registers (read the tech doc for explaination)
  202. byte max7219_reg_digit0      = 0x01;
  203. byte max7219_reg_digit1      = 0x02;
  204. byte max7219_reg_digit2      = 0x03;
  205. byte max7219_reg_digit3      = 0x04;
  206. byte max7219_reg_digit4      = 0x05;
  207. byte max7219_reg_digit5      = 0x06;
  208. byte max7219_reg_digit6      = 0x07;
  209. byte max7219_reg_digit7      = 0x08;
  210. byte max7219_reg_decodeMode  = 0x09;
  211. byte max7219_reg_intensity   = 0x0a;
  212. byte max7219_reg_scanLimit   = 0x0b;
  213. byte max7219_reg_shutdown    = 0x0c;
  214. byte max7219_reg_displayTest = 0x0f;
  215.  
  216. /* END OF MAX 7219 INSTRUCTION ADDRESSES */
  217.  
  218. // putByte - helper function that sends a single byte to the MAX chip
  219. void putByte(byte data)
  220. {
  221.   byte i = 8;
  222.   byte mask;
  223.  
  224.   while(i > 0)
  225.   {
  226.     mask = 0x01 << (i - 1);      // get bitmask
  227.  
  228.  
  229.     if (data & mask)  // check and send value of this bit
  230.     {            
  231.       LED_DATA_PORT |= DataMaskHigh;
  232.     }
  233.     else
  234.     {                    
  235.       LED_DATA_PORT &= DataMaskLow;  
  236.     }
  237.  
  238.     // Pulse the MAX clock
  239.     LED_CLOCK_PORT &= ClockMaskLow; //    digitalWrite( clock, LOW);   // "tick" prepeare for bit input
  240.     LED_CLOCK_PORT |= ClockMaskHigh;//    digitalWrite(clock, HIGH);   // "tock" input bit
  241.  
  242.     --i;                         // move to lesser bit
  243.   }
  244. }
  245.  
  246.  
  247. //maxSingle is the "easy"  function to use for a single max7219
  248. //dig is the row call, and seg is the column call dig and seg refer to pin names from tech doc
  249.  
  250. void maxSingle( byte dig, byte seg) {    
  251.  
  252.   LED_LOAD_PORT &= LoadMaskLow;  //  digitalWrite(load, LOW);            // begin    
  253.  
  254.   putByte(dig);                       // specify register
  255.   putByte(seg);                       //((data & 0x01) * 256) + data >> 1); // put data  
  256.  
  257.   LED_LOAD_PORT |= LoadMaskHigh; //  digitalWrite(load,HIGH);
  258.  
  259. }
  260.  
  261.  
  262. // buttonInit - helper function that zeros the button states
  263. void buttonInit(void){
  264.   byte i;
  265.   for (i = 0; i < 8; i++) {
  266.     button_current[i] = 0x00;
  267.     button_last[i] = 0x00;
  268.     button_state[i] = 0x00;
  269.     button_event[i] = 0x00;
  270.   }
  271. }
  272.  
  273.  
  274. // buttonCheck - checks the state of a given button.
  275. void buttonCheck(byte row, byte index)
  276. {
  277.   if (((button_current[row] ^ button_last[row]) & (1 << index)) &&   // if the current physical button state is different from the
  278.   ((button_current[row] ^ button_state[row]) & (1 << index))) {  // last physical button state AND the current debounced state
  279.  
  280.     if (button_current[row] & (1 << index)) {                      // if the current physical button state is depressed
  281.       button_event[row] = kButtonNewEvent << index;              // queue up a new button event immediately
  282.       button_state[row] |= (1 << index);                         // and set the debounced state to down.
  283.     }
  284.     else{
  285.       button_debounce_count[row][index] = kButtonUpDefaultDebounceCount;
  286.     }  // otherwise the button was previously depressed and now
  287.     // has been released so we set our debounce counter.
  288.   }
  289.   else if (((button_current[row] ^ button_last[row]) & (1 << index)) == 0 &&  // if the current physical button state is the same as
  290.   (button_current[row] ^ button_state[row]) & (1 << index)) {        // the last physical button state but the current physical
  291.     // button state is different from the current debounce
  292.     // state...
  293.  
  294.     if (button_debounce_count[row][index] > 0 && --button_debounce_count[row][index] == 0) {  // if the the debounce counter has
  295.       // been decremented to 0 (meaning the
  296.       // the button has been up for
  297.       // kButtonUpDefaultDebounceCount
  298.       // iterations///
  299.  
  300.       button_event[row] = kButtonNewEvent << index;    // queue up a button state change event
  301.  
  302.       if (button_current[row] & (1 << index)){          // and toggle the buttons debounce state.
  303.         button_state[row] |= (1 << index);
  304.       }
  305.       else{
  306.         button_state[row] &= ~(1 << index);
  307.       }
  308.     }
  309.   }
  310. }
  311.  
  312.  
  313. void buttonpress ()
  314. {
  315.  
  316.   DATA_PORT_164 &= dataPinMaskLow;
  317.   //164
  318.   for(i = 0; i < 8; i++)
  319.   {
  320.     CLOCK_PORT_164 |= clockPinMaskHigh;
  321.     CLOCK_PORT_164 &= clockPinMaskLow;  
  322.     DATA_PORT_164 |= dataPinMaskHigh;  
  323.  
  324.  
  325.     // SlowDown is put in here to waste a little time while we wait for the state of the output
  326.     // pins to settle.  Without this time wasting loop, a single button press would show up as
  327.     // two presses (the button and its neighbour)
  328.     volatile int SlowDown = 0;
  329.  
  330.     while (SlowDown < 15)
  331.     {
  332.       SlowDown++;
  333.     }
  334.  
  335.     button_last [i] = button_current [i];
  336.  
  337.     //165
  338.     LOAD_PORT_165 &= inloadPinMaskLow; // digitalWrite(inloadPin, LOW);
  339.     LOAD_PORT_165 |= inloadPinMaskHigh;// digitalWrite(inloadPin, HIGH);
  340.  
  341.     for(id = 0; id < 8; id++) {
  342.  
  343.       t = (INPUT_DATA_PORT_165 & indataPinMask) >> 1;//t = digitalRead(indataPin);
  344.       t = (t == 0);
  345.       if(t){
  346.         button_current [i] |= (1 << id);
  347.       }
  348.       else{
  349.           button_current [i] &= ~(1 << id);
  350.       }
  351.  
  352.       buttonCheck(i, id);
  353.  
  354.       if (button_event[i] & (1 << id)) {
  355.         button_event[i] &= ~(1 << id);
  356.         if(button_state[i] & (1 << id)){
  357.           b = 1;
  358.         }
  359.         else{
  360.           b = 0;
  361.         }
  362.         Serial.write((0 << 4) | (b & 15));
  363.         Serial.write((id << 4) | (i & 15));
  364.  
  365.       }
  366.       CLOCK_PORT_165 |= inclockPinMaskHigh;
  367.       CLOCK_PORT_165 &= inclockPinMaskLow;  
  368.     }
  369.   }
  370.  
  371. }
  372.  
  373. ISR(TIMER2_OVF_vect) {
  374.   // first up: enable interrupts to keep the serial
  375.   // class responsive
  376.   sei();
  377.  
  378.   do
  379.   {
  380.     if (Serial.available())
  381.     {
  382.       if (WaitingForAddress == 1)
  383.       {
  384.         byte0 = Serial.read();
  385.  
  386.         address = byte0 >> 4;
  387.         WaitingForAddress = 0;
  388.       } // end if (WaitingForAddress == 1);
  389.  
  390.       if (Serial.available())
  391.       {
  392.         WaitingForAddress = 1;
  393.         byte1 = Serial.read();
  394.  
  395.         switch(address)
  396.         {
  397.         case 2:
  398.           state = byte0 & 15;
  399.           x = byte1 >> 4;
  400.           y = byte1 & 15;
  401.  
  402.           if (state == 0){
  403.             ledmem[y] &= ~( 1 << x);
  404.           }
  405.           else {
  406.             ledmem[y] |=  ( 1 << x);
  407.           }
  408.           break;
  409.         case 3:
  410.           IntensityChange = 1;
  411.           IntensityVal = byte1 & 15;          
  412.           break;
  413.         case 4:
  414.           DisplayTestChange = 1;
  415.           DisplayTestVal = byte1 & 15;
  416.           break;
  417.         case 5:
  418.           state = byte1 & 0x0F;
  419.           ADCEnableState[(byte1 >> 4)&0x03] = state;
  420.           break;
  421.         case 6:
  422.           ShutdownModeChange = 1;
  423.           ShutdownModeVal= byte1 & 15;
  424.           break;
  425.         case 7:
  426.           if (firstRun == 1) {
  427.             for (x = 0; x < 8; x++) {
  428.               ledmem[x] = 0;
  429.             }
  430.  
  431.             firstRun = 0;
  432.           }
  433.  
  434.           x = ((byte0 & 15) & 0x7); // mask this value so we don't write to an invalid address.
  435.           y = byte1;
  436.  
  437.           ledmem[x] = y;
  438.           break;
  439.         case 8:
  440.           if (firstRun == 1)
  441.           {
  442.             for (x = 0; x < 8; x++)
  443.             {
  444.               ledmem[x] = 0;
  445.             }
  446.  
  447.             firstRun = 0;
  448.           }
  449.  
  450.           x = ((byte0 & 15) & 0x7);
  451.           y = byte1;
  452.  
  453.           for (z = 0; z < 8; z++)
  454.           {
  455.             if (y & (1 << z))
  456.             {
  457.               ledmem[z] |= 1 << x;
  458.             }
  459.             else
  460.             {
  461.               ledmem[z] &= ~(1 << x);
  462.             }
  463.           }
  464.           break;
  465.         } // end switch(address)
  466.       } // end if (Serial.available()
  467.     } // end if (Serial.available();
  468.   } // end do
  469.   while (Serial.available() > 16);
  470. }
  471.  
  472. void whoosh(void)
  473. {
  474.   // reactivate overflow interrupt for
  475.   // timer 1 - it's needed by delay(...)
  476.   TIMSK0 |= (1 << TOIE0);
  477.  
  478.   for (int j = 0; j < 9; j++)
  479.   {
  480.     for (int i = 0; i < 8; i++)
  481.     {
  482.       maxSingle(i+1,1<<j);
  483.     }
  484.     delay(125);
  485.   }
  486.   // and switch the interrupt off.
  487.   TIMSK0 &= ~(1 << TOIE0);
  488. }
  489.  
  490. void setup () {
  491.  
  492.   DDRD = PORTD_Data_Direction;
  493.   DDRB = PORTB_Data_Direction;
  494.  
  495.   Serial.begin(57600);
  496.  
  497.   buttonInit();  
  498.  
  499.   //initiation of the max 7219
  500.   maxSingle(max7219_reg_scanLimit, 0x07);      
  501.   maxSingle(max7219_reg_intensity,0x0F);
  502.   maxSingle(max7219_reg_shutdown, 0x01);           // not in shutdown mode
  503.   maxSingle(max7219_reg_displayTest, 0x00);        // empty registers, turn all LEDs off h
  504.  
  505.   for (i=1; i<=8; i++){
  506.     maxSingle(i,0);
  507.     ledmem[i-1]=0;
  508.   }
  509.  
  510.   // Set up 8-bit counter 2, output compare switched off,
  511.   // normal waveform generation (whatever that might mean)
  512.   TCCR2A = 0;
  513.   // set counter to be clocked at 16Mhz/8 = 2Mhz
  514.   TCCR2B = 1<<CS21;
  515.  
  516.   // set the interrupt mask so that we get an interrupt
  517.   // on timer 2 overflow, i.e. after 256 clock cycles.
  518.   // The timer 2 interrupt routine will execute every
  519.   // 128 uS.
  520.   TIMSK2 = 1<<TOIE2;
  521.  
  522.   // NOTE: In my efforts to try to get this
  523.   // code to work reliably at 115200 baud
  524.   // I went about disabling unused timers that
  525.   // are set up by the Arduino framework.
  526.   // The framework sets up both timer 2 and
  527.   // timer 1.  We use timer 2 to drive the
  528.   // serial reading interrupt, so we can only
  529.   // disable timer1 and its interrupt.
  530.  
  531.   // REALLY IMPORTANT NOTE - IF YOU WANT TO USE
  532.   // ANALOGWRITE
  533.  
  534.   // Disabling timer 1 will switch off the timer
  535.   // used for PWM, which underlies analogWrite.
  536.   // If you want to use analogWrite, remove
  537.   // the lines below.
  538.  
  539.   // DISABLE PWM COUNTER
  540.   TIMSK0 &= ~(1 << TOIE0);
  541.  
  542.   TCCR1B &= ~(1 << CS12);
  543.   TCCR1B &= ~(1 << CS11);
  544.   TCCR1B &= ~(1 << CS10);  
  545.   // END DISABLE PWM COUNTER
  546.  
  547.   // Also, disable the interrupts on timer 0
  548.   // REALLY IMPORTANT NOTE IF YOU WANT TO USE
  549.   // DELAY
  550.   // remove this line, and also look at
  551.   // 'whoosh', which enables and then disables
  552.   // the intterupt on timer 0.  You'll want
  553.   // to get rid of those lines too.
  554.   TIMSK0 &= ~(1 << TOIE0);
  555.  
  556.   // pretty pattern to assure me that the firmware's
  557.   // uploaded properly.
  558.   whoosh();
  559.  
  560.   // make sure to turn off the lights.
  561.   for (int i = 0; i < 8; i++)
  562.   {
  563.     maxSingle(i+1,0);
  564.   }
  565. }  
  566.  
  567. void sendADC(int port, int value) {
  568.   Serial.write((1 << 4) | ((port << 2) & 0x0C) | ((value >> 8) & 0x03));
  569.   Serial.write(value & 0xFF);
  570. }
  571.  
  572. int current[4];
  573. int previous[4];
  574. int tolerance = 7;
  575.  
  576. void checkADCs() {
  577.  
  578.   for (int adcCounter = 0; adcCounter < 4; adcCounter++)
  579.   {
  580.  
  581.     if (ADCEnableState[adcCounter] != 0)
  582.     {
  583.       current[adcCounter] = analogRead(adcCounter);
  584.  
  585.       if (abs(previous[adcCounter]-current[adcCounter]) > tolerance)
  586.       {
  587.         previous[adcCounter] = current[adcCounter];
  588.         sendADC(adcCounter,current[adcCounter]);
  589.       }
  590.  
  591.     }
  592.  
  593.   }
  594. }
  595.  
  596. void loop () {
  597.  
  598.   // send the LED states to the LED matrix.
  599.   for (int i = 0; i < 8; i++)
  600.   {
  601.     maxSingle(i+1,ledmem[i]);    
  602.   }
  603.  
  604.   if (IntensityChange == 1)
  605.   {
  606.     IntensityChange = 0;
  607.     maxSingle(max7219_reg_intensity, IntensityVal & 15);
  608.   }
  609.  
  610.   if (DisplayTestChange == 1)
  611.   {
  612.     DisplayTestChange = 0;
  613.     maxSingle(max7219_reg_displayTest, DisplayTestVal & 15);
  614.   }
  615.  
  616.   if (ShutdownModeChange == 1)
  617.   {
  618.     ShutdownModeChange = 0;
  619.     maxSingle(max7219_reg_shutdown, ShutdownModeVal & 15);
  620.   }
  621.  
  622.   // check for button presses
  623.   buttonpress();
  624.  
  625.   // check the state of the ADCs
  626.   checkADCs();  
  627. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement