The Midi Blanket

hello,
for universety im planing a projekt were i basically want to build a midicontroller, the triggers will be conductive paint i will put on a blanket and then using capacitive sensoring

to start and build a prototype first i wanted to try and build this :

i have done every stp as said but

now im stuck because the arduino does not send out the midi signal.
in fact im not using a uno but a mega2560 because for the projekt in planing i need alot more pins

do i have to make any changes in the code beacuse of that?

maby you have a better idea how to do it i am a newbie to arduio i bought it 2 weeks ago hamming tons of turotials into my brain :cold_sweat:

// drawMIDI



int myKey[12];
int myOldKey[12];
int myNote[] = {79, 77, 76, 72, 74, 71, 69, 67, 65, 64, 62, 60};
int keyPin[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};


// Pins for MIDI keys


// This is the value required to consider the key 'touched' and trigger a MIDI signal
int touchedCutoff = 36;

// This is the value required for the first part of goMIDI
int midiInfo = 144;


// This is the section that sets up serial communications
void setup(){
  Serial.begin(19200); //if using hardward MIDI or HIDUINO, change to 31250  
  //19200 baud, requires serial to MIDI conversion on your computer
  
}


// This is the section that reads the capacitance and determines what to do, noteOn or noteOff
void loop(){
  
  

// only send MIDI messages when something changes
for (int i; i<12; i++) {
  myKey[i]=readCapacitivePin(keyPin[i]);
  
  if (myKey[i]>touchedCutoff){
    myKey[i]=127;
  }
  else{
    myKey[i]=0;
  }
  
  
  if (myKey[i] != myOldKey[i]) {
    myOldKey[i] = myKey[i];
    goMidi(midiInfo, myNote[i], myKey[i]);
  }
}
}




// The readCapacitivePin function is used to read whether the graphite strip connected to each pin is actually being pressed or not
// this part of the code is based on an open example on the Arduino playground for 'Capacitive Sensing' 

// readCapacitivePin
//  Input: Arduino pin number
//  Output: A number, from 0 to 17 expressing
//          how much capacitance is on the pin
//  When you touch the pin, or whatever you have
//  attached to it, the number will get higher

uint8_t readCapacitivePin(int pinToMeasure){
  volatile uint8_t* port;
  volatile uint8_t* ddr;
  volatile uint8_t* pin;
  
  byte bitmask;
  if ((pinToMeasure >= 0) && (pinToMeasure <= 7)){
    port = &PORTD;
    ddr = &DDRD;
    bitmask = 1 << pinToMeasure;
    pin = &PIND;
  }
  
  if ((pinToMeasure > 7) && (pinToMeasure <= 13)){
    port = &PORTB;
    ddr = &DDRB;
    bitmask = 1 << (pinToMeasure - 8 );
    pin = &PINB;
  }
  
  if ((pinToMeasure > 13) && (pinToMeasure <= 19)){
    port = &PORTC;
    ddr = &DDRC;
    bitmask = 1 << (pinToMeasure - 13);
    pin = &PINC;
  }
  
  // Discharge the pin first by setting it low and output
  *port &= ~(bitmask);
  *ddr  |= bitmask;
  delay(1);
  
  *ddr &= ~(bitmask);

  int cycles = 16000;
  for(int i = 0; i < cycles; i++){
    if (*pin & bitmask){
      cycles = i;
      break;
    }
  }
  
  *port &= ~(bitmask);
  *ddr  |= bitmask;
  
  return cycles;
}


 
 
// This is the section that translates the touches into MIDI signals
 
void goMidi(int cmd, int data1, int data2) {
  Serial.write(cmd); // set value stays the same
  Serial.write(data1);  // note number, 60 or 49 or whatever
  Serial.write(data2); // velocity, keep at 127 for ON or 0 for OFF
  delay(2);
}

moderatore update: quote tags replaced by code tags …

Post code with the # icon not the quote icon next to it.

Serial.begin(19200); //if using hardward MIDI or HIDUINO, change to 31250 
  //19200 baud, requires serial to MIDI conversion on your computer

So what have you got as a MIDI converter on your computer?

You do not get a large chunk of code and expect it to work. Especially not from an Instructiables page, the quality of most projects range from poor to crap, although there are the odd exceptions.

Start off just by sending out MIDI notes, only what that is working go for the capacitive sensors.

Capacitive sensing is not very robust either, the more sensors you have the less reliable it gets.

i guess your right.
im using max6.1 and the skript the guys put on thair Instructiables page

but i rather go with pure data and then control with qbase or ableton

maby i explain my projekt a bit further it does not have to convert midi ill just show my idea:

i want to build a hanging tensioned piece of textile with vertical printed soundwaves on it
for a simple example: on the left side thers a sinus wave and on the other a w-noise with alot of lowpass
my idea with the arduino was to create about 50-60 sounds witch start from the left with only the sinus sound and then if you touch the next sector the next sound will start and it will have a little of the w-noise until they both have the same loudness and backwars just like a xfader effekt.

i guess its not the smartest idea but since i have only 2 weeks of experiance in programming and electronics and about 2 months left for the projekt there is no time to learn more than the basics :confused:

brainstorm picture:

this is how id like it to work but on textile and alot soundscapier with very low frequenzes in a dimmed room and a hidden subwoofer so you can "feel the soud on the textile" get it?^^

OK, sounds like a good idea.
Thinking about it I am sure that the cap sense libary does not work on the Mega. This is because it relies on direct port manipulation and the mapping is diffrent on the Mega than the UNO.

It sounds like what you need is several makie makie kits and conductive threads to stich or woven into your blankets. I think these are much more reliable than the cap sense libary anyway.

I once saw something where the trailing stems or rassiems of a plant were stroked to produce twinklie sound.

i found this code

int LEDPin = 13;

int capSensePin = 2;

int touchedCutoff = 60;

void setup(){
  Serial.begin(9600);
 
  pinMode(LEDPin, OUTPUT);
  digitalWrite(LEDPin, LOW);
}

void loop(){
 
  if (readCapacitivePin(capSensePin) > touchedCutoff) {
    digitalWrite(LEDPin, HIGH);
  }
  else {
    digitalWrite(LEDPin, LOW);
  }
  
  // Every 500 ms, print the value of the capacitive sensor
  if ( (millis() % 500) == 0){
    Serial.print("Capacitive Sensor on Pin 2 reads: ");
    Serial.println(readCapacitivePin(capSensePin));
  }
}


uint8_t readCapacitivePin(int pinToMeasure){
 
  volatile uint8_t* port;
  volatile uint8_t* ddr;
  volatile uint8_t* pin;
 
  byte bitmask;
  if ((pinToMeasure >= 0) && (pinToMeasure <= 7)){
    port = &PORTD;
    ddr = &DDRD;
    bitmask = 1 << pinToMeasure;
    pin = &PIND;
  }
  if ((pinToMeasure > 7) && (pinToMeasure <= 13)){
    port = &PORTB;
    ddr = &DDRB;
    bitmask = 1 << (pinToMeasure - 8);
    pin = &PINB;
  }
  if ((pinToMeasure > 13) && (pinToMeasure <= 19)){
    port = &PORTC;
    ddr = &DDRC;
    bitmask = 1 << (pinToMeasure - 13);
    pin = &PINC;
  }

  *port &= ~(bitmask);
  *ddr  |= bitmask;
  delay(1);

  *ddr &= ~(bitmask);

  int cycles = 16000;
  for(int i = 0; i < cycles; i++){
    if (*pin & bitmask){
      cycles = i;
      break;
    }
  }

  *port &= ~(bitmask);
  *ddr  |= bitmask;
  
  return cycles;
}

the capsense works fine if i wire up to pin 19 instead of pin 2
also pin 3 works if i wire it to pin 18 but thats it… :confused:

i thought about the makey makey but it sells for 50€ and for my project i would need about 4-5 of them, thats 200€ instead of 19€ i payed for my arduino mega and since im a student thats a lot of money for me…guess its the only way

You do know that the analog input pins (A0-A5) can be used as digital pins, right?

See this bit of code:-

 port = &PORTD;
    ddr = &DDRD;

That is the direct port manipulation I told you about. It will map to different pins on a Mega and and Uno.
See:-

okay now i found this
http://www.instructables.com/id/Capacitive-Touch-Arduino-Keyboard-Piano/all/?lang=de

the code is from the capsense example sketch but i dont get what to change for the pins
i also found this list and still i dont know what to do:
www.arduino.cc/en/Hacking/PinMapping2560

maby you can help me out on what numbers i have to change… as said before im very new to arduino programming and electronics
id appreciate some help

#include <CapacitiveSensor.h>

/*
 * CapitiveSense Library Demo Sketch
 * Paul Badger 2008
 * Uses a high value resistor e.g. 10M between send pin and receive pin
 * Resistor effects sensitivity, experiment with values, 50K - 50M. Larger resistor values yield larger sensor values.
 * Receive pin is the sensor pin - try different amounts of foil/metal on this pin
 */


CapacitiveSensor   cs_4_2 = CapacitiveSensor(4,2);        // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapacitiveSensor   cs_4_6 = CapacitiveSensor(4,6);        // 10M resistor between pins 4 & 6, pin 6 is sensor pin, add a wire and or foil
CapacitiveSensor   cs_4_8 = CapacitiveSensor(4,8);        // 10M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil

void setup()                    
{
   cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);     // turn off autocalibrate on channel 1 - just as an example
   Serial.begin(9600);
}

void loop()                    
{
    long start = millis();
    long total1 =  cs_4_2.capacitiveSensor(30);
    long total2 =  cs_4_6.capacitiveSensor(30);
    long total3 =  cs_4_8.capacitiveSensor(30);

    Serial.print(millis() - start);        // check on performance in milliseconds
    Serial.print("\t");                    // tab character for debug windown spacing

    Serial.print(total1);                  // print sensor output 1
    Serial.print("\t");
    Serial.print(total2);                  // print sensor output 2
    Serial.print("\t");
    Serial.println(total3);                // print sensor output 3

    delay(10);                             // arbitrary delay to limit data to serial port 
}

but i dont get what to change for the pins

That first line calls up a libary it is that libary that you have to change. Not a beginners job.

The code inside it will look like that last code I pointed out..
The pin mapping link wil show you what pin numbers correspond to what ports.
You see to get stuff in and out of a processor you read and write to ports, these are collections of 8 bits or pins at one memory location. The Arduino system hides this from you and abstracts the port into a single bit read write function calls. That is digitalWrite and digitalRead. The price you pay for this is speed, it takes time to do this abstraction. So by using direct access it speeds things up but at the price of being different on different processors.

I would take the code before the last one and use the bits I pointed out along with the pin mapping information to make it work with the pins you want on the mega.

okay i managed to understand the mapping list and i can use any pin i want.
now i want to add multiple pins to the code e.g. 17 and 18 ( PH0 and PD3 )
i guess ill start by adding another int

int capSensePin = 0;
int capSensePin2 = 3; //<<<

now in this sector i figured that the first “if” case i use to change the register ( for my example i changed it to PORTH…)
but i dont know what the other 2 “if” codes do

  byte bitmask;
  if ((pinToMeasure >= 0) && (pinToMeasure <= 7)){
    port = &PORTH ;
    ddr = &DDRH;
    bitmask = 1 << pinToMeasure;
    pin = &PINH;
  }
  if ((pinToMeasure > 7) && (pinToMeasure <= 13)){
    port = &PORTB;
    ddr = &DDRB;
    bitmask = 1 << (pinToMeasure - 8); //<<---this port does not exsist ? i dont get it
    pin = &PINB;
  }
  if ((pinToMeasure > 13) && (pinToMeasure <= 19)){
    port = &PORTC;
    ddr = &DDRC;
    bitmask = 1 << (pinToMeasure - 13);
    pin = &PINC;

then i found a comment on how to add serveral pins but i dont know how to use it i only get tons of error messages cause im to newbie to coding … :confused:

//The sample code has a funktion, readCapacitivePin(int pinToMeasure)

// if you put in different values for that, like

int firstSensor = readCapacitivePin(17)
int secondSensor = readCapacitivePin(17)

you can read whatever Arduino pins you want, as many as you`d like.

do you have time to explain or just give a example what to change in the code to get what i want?
thanks

now in this sector i figured that the first "if" case i use to change the register ( for my example i changed it to PORTH...)
but i dont know what the other 2 "if" codes do

Because there are only 8 bits per port if you use pin numbers above 7 then they belong to another port. So what those two ifs are doing is mapping pin numbers between 8 & 15 and 16 & 23 to other ports, in the case of the code these are PORTB and PORTC. If you want to use more pins then you will have to add more if statements to handle those.
Hope that helps.

okay thx i understood that very well
i figured out i can use 68 pins to send in a signal what means 68 sounds could be controlled, thats pretty neat!
(if i manage to make the rest of the code^^)

the next step i need to know and what i actually was asking for was:
how do i add multiple pins at the same time, i mean just so i cant test it:

i want pin 17 to make the LED glow
and now i want pin 18 to make the same thing

my idea of how it could work(it gives an error :/):

(<<<<<< marks the added code)

int LEDPin = 13;

int capSensePin = 0;
int capSensePin2 =1;                            <<<<<<<<<<<<<<<<<<<<

int touchedCutoff = 60;

void setup(){
  Serial.begin(9600);
 
  pinMode(LEDPin, OUTPUT);
  digitalWrite(LEDPin, LOW);
}

void loop(){
 
  if (readCapacitivePin(capSensePin) > touchedCutoff) {
    digitalWrite(LEDPin, HIGH);
  }
  else {
    digitalWrite(LEDPin, LOW);
  }
  
  if (readCapacitivePin(capSensePin2) > touchedCutoff) {                                      <<<<<<<<<<<<<<
    digitalWrite(LEDPin, HIGH);                                                                                            <<<<<<<<<<<<<
  }                                                                                                                                                 <<<<<<<<<<<<<<
  else {                                                                                                                                        <<<<<<<<<<<<<<
    digitalWrite(LEDPin, LOW);                                                                                            <<<<<<<<<<<<<
  }                                                                                                                                                   <<<<<<<<<<<<<
  // Every 500 ms, print the value of the capacitive sensor
  if ( (millis() % 500) == 0){
    Serial.print("Capacitive Sensor on Pin 2 reads: ");
    Serial.println(readCapacitivePin(capSensePin));
  
}


uint8_t readCapacitivePin(int pinToMeasure){
 
  volatile uint8_t* port;
  volatile uint8_t* ddr;
  volatile uint8_t* pin;
 
  byte bitmask;
  if ((pinToMeasure >= 0) && (pinToMeasure <= 7)){
    port = &PORTH;
    ddr = &DDRH;
    bitmask = 1 << pinToMeasure;
    pin = &PINH;
  }
  if ((pinToMeasure > 7) && (pinToMeasure <= 13)){
    port = &PORTB;
    ddr = &DDRB;
    bitmask = 1 << (pinToMeasure - 8);
    pin = &PINB;
  }
  if ((pinToMeasure > 13) && (pinToMeasure <= 19)){
    port = &PORTC;
    ddr = &DDRC;
    bitmask = 1 << (pinToMeasure - 13);
    pin = &PINC;
  }

  *port &= ~(bitmask);
  *ddr  |= bitmask;
  delay(1);

  *ddr &= ~(bitmask);

  int cycles = 16000;
  for(int i = 0; i < cycles; i++){
    if (*pin & bitmask){
      cycles = i;
      break;
    }
  }

  *port &= ~(bitmask);
  *ddr  |= bitmask;
  
  return cycles;
}

okay :smiley: :smiley: too much effort in the post befor i just missed a bracket

i works!! i feel like i could be poppin the champain hahaha

but im allready at the next problem

now i need to use the signal not to turn on LED but to send a midi signal into the pc

still this was a grat step forward thx alot!

MIDI is easy, sending a MIDI note is just a 3 line function.
See:-
http://www.thebox.myzen.co.uk/Hardware/MIDI_Shield.html

Or lots of notes from switches:-
http://www.thebox.myzen.co.uk/Hardware/Pendulum.html

Hey again!

i managed to play some notes with my capsense pins now
im using ableton for output and i send the midi notes direkt with usb to a programm called The Hairless MIDI<->Serial Bridge

now the problem is i only managed to create a code that loops the note and it does not stop as i want as soon as you do not touch the sensor anymore.

it looks like this:

void loop(){
 
  
  if (readCapacitivePin(capSensePin) > touchedCutoff) {
    
      for (byte note=60;note<61;note++) {     
    MIDImessage(noteON, note, 100);             // here im actually telling it to play the note 2 sec as soon as the pin is touched
    delay(2000);                                //  i want it stop as soon as the touchedCutoff is below my set rate (60)
    MIDImessage(noteON, note, 0);               // and of course i dont want it to loop, i you put yout finger on it should play the
    delay(0);                                   // note once.
  }

and one other thing i couldnt find out yet. if its possible id really like the idea of playn several notes at the same time

hope you can give me some advice again i had a week with lots of sleepless nights this projekt is really stealing my energy^^
id be really proud to present you the whole thing with a nice video when its done

cheers

OK you are now needing a different sort of programming known as a state machine.
The blink without delay example in the IDE is a good start as it my page on the subject.
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
Basically you remove all delays from the system and instead use the system time given by millis() to orchestrate everything.

So you look at an input, and decide if you want to trigger a note or not. If you do you then make a note of the current time in a variable. Then at the start of the loop you check with that variable if enough time has passed, if it has you send the midi note off message.

this is just what i needed i will work on it immediately.
thanks alot! you really help me out :slight_smile: