Wednesday, February 24, 2010

new code for the 16x4x3




an improved code,written by olaf. the main virtue of this one against the old one is that the multiplexing section is now "outputing" a string of input+i.d, so you could easily tag your inputs. there is however some decoding to be done on the max/msp side as shown on the foto below.
the 595 part is still credited to sebastian tomczak aka little scale.




// 16x4x3 www.openskinnerbox.blogspot.com , 2010

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
byte data1;
byte data2;
byte data3;
// ----------------------------- MUXES -------------------------------
const byte APin = 2; // Pins for 4051-Control
const byte BPin = 3; // ...
const byte CPin = 4; // ...
byte row = 0; // store bin code
byte r0 = 0; // Input selection value...
byte r1 = 0;
byte r2 = 0;
byte count = 0; // just a count
// -------------------------------------------------------------------
const byte numControls = 40; // Amount of Knobs
const byte ctrlOffset = 1; // start scanning at this Controller (min 1 !!!)
const byte hysteresis = 10; // Hysteresis (0 = off)
byte analogInputPin; // Pin for analog Input
int value; // read analog Input to here
int oldValue [numControls]; // Value read last time
int lowerLimit[numControls]; // Hysteresis window
int upperLimit[numControls]; // ...
const byte startbyte = 254; // data block indicators...
const byte stopbyte = 255; // ...
byte lobyte = 0; // 5 bit...
byte hibyte = 0; // and the other 5 bit of the value
// ===================================================================
void setup()
{
  for (count=0; count// clear Hysteresis-Windows
  {
    lowerLimit[count] = 0;
    upperLimit[count] = lowerLimit[count] + hysteresis;
  }
// -------------SETUP ARDUINO-----------------
  pinMode(APin, OUTPUT); // Set 4051-Control Pins as Outputs...
  pinMode(BPin, OUTPUT);
  pinMode(CPin, OUTPUT);
  digitalWrite(APin, LOW); // set the 4051 to Input 0...
  digitalWrite(BPin, LOW);
  digitalWrite(CPin, LOW);
  
  pinMode(latchPin, OUTPUT); // 595
  Serial.begin(57600);
// -------------------------------------------
}

// =====================================================================================
// ===================================== M A I N =======================================
// =====================================================================================
void loop()
{
  for (count=(ctrlOffset-1); count<(numControls+ctrlOffset-1); count++)
  {
    switch (count+1)
    {
//     case 29: break;        // following inputs are not connected, so don´t check them!
//      case 31: break;
//      case 40: break;
//      case 41: break;
      case 42: break;
      case 43: break;
      case 44: break;
      case 45: break;
      case 46: break;
      case 47: break;
      default:
      {
// -------------------- set the MUXES ---------------------
        row = count & 7;        // wrap count between 0 and 7
        r0 = row & 1;
        r1 = (row >> 1) & 1; 
        r2 = (row >> 2) & 1; 
        digitalWrite(APin, r0); // set 4051 Input...
        digitalWrite(BPin, r1);
        digitalWrite(CPin, r2);
// ---------------------------------------------------------

        analogInputPin = count >> 3;       // div. count by 8

        value = analogRead(analogInputPin);

        if ((value<=upperLimit[count]) && (value>=lowerLimit[count])) // no change...
        { }                                                              // ... no operation.
        else
        {                                               // Otherwise set new Hysteresis-window...
          if (value>upperLimit[count])
          {
            upperLimit[count] = value;
            lowerLimit[count] = upperLimit[count] - hysteresis;
          }
          else
          {
            lowerLimit[count] = value;
            upperLimit[count] = lowerLimit[count] + hysteresis;
          }

          lobyte = value >> 5;                          // ... split value...
          hibyte = value & 31;

          Serial.print(startbyte); // ... and send out a packet!
          Serial.print(count);
          Serial.print(lobyte);
          Serial.print(hibyte);
          Serial.print(stopbyte);


          delayMicroseconds(10000);
        }
      }
    }
  }

if(Serial.available() > 2) {
data1 = Serial.read();
data2 = Serial.read();
data3 = Serial.read();
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, data1);
shiftOut(dataPin, clockPin, data2);
shiftOut(dataPin, clockPin, data3);
digitalWrite(latchPin, 1);
}
}
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
if ( myDataOut & (1<pinState= 1;
}
else {
pinState= 0;
}
digitalWrite(myDataPin, pinState);
digitalWrite(myClockPin, 1);
digitalWrite(myDataPin, 0);
}
digitalWrite(myClockPin, 0);
}