SHARE
TWEET

arduinomeFirmware3_2

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