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);
}
I loved it! Will build one as soon as possible, will you ever upload the m4l patch ? and also can you recommend a place to buy the buttons with leds?
ReplyDeletethank you very very much for inspiring
sure! uploading the patch would be no problem... where are you located? were in berlin... i actually bought the buttons at conrad, but you might find them cheaper somewhere else...
ReplyDeleteCan I ask where you got those buttons and possibly a model number? I'd love those for a sequencer project I'm working on.
ReplyDeletesure,
ReplyDeletei got them at conrad,
http://www.conrad.de/ce/de/product/701149/DRUCKTASTER-LED-SCHWARZROT/SHOP_AREA_17384&promotionareaSearchDetail=005
they are actually very nice, and have soft touch... i would look for them somewhere else tho, im sure you can get them cheaper..
hello!
ReplyDeleteyour sequencer is looking great and i'm considering building one :) you're very kind to share the arduino code and the schematics, but i'm wondering if you'd mind also sharing the max patch and a bill of materials.
cheers
ill prepare a post with detailed shopping list and post the patch sometimes soon,
ReplyDelete:) thanks for that.
ReplyDelete