digital pins

I am using the arduino as a simple input device for max/msp and would like to program the digital pins 2 - 6 to simply send nothing until a button is pushed.

The analog pins 0 - 5 are working fine.

Could someone steer me in the right direction?

This is what I've uploaded so far:

  • Arduino2Max
  • Send pin values from Arduino to MAX/MSP
  • Arduino2Max.pde

  • This version: .4, October 2007

  • Copyleft: use as you like
  • by Daniel Jolliffe
  • Based on a sketch and patch by Thomas Ouellet Fredericks tof.danslchamp.org

*/

int x = 0; // a place to hold pin values
int ledpin = 13;

void setup()
{
Serial.begin(115200); // 115200 is the default Arduino Bluetooth speed
digitalWrite(13,HIGH); ///startup blink
delay(600);
digitalWrite(13,LOW);
pinMode(13,INPUT);
}

void loop()
{

if (Serial.available() > 0){ // Check serial buffer for characters

if (Serial.read() == 'r') { // If an 'r' is received then read the pins

for (int pin= 0; pin<=5; pin++){ // Read and send analog pins 0-5
x = analogRead(pin);
sendValue (x);
}

for (int pin= 2; pin<=13; pin++){ // Read and send digital pins 2-13
x = digitalRead(pin);
sendValue (x);
}

Serial.println(); // Send a carriage returnt to mark end of pin data.
delay (5); // add a delay to prevent crashing/overloading of the serial port

}

}
}

void sendValue (int x){ // function to send the pin value followed by a "space".
Serial.print(x);
Serial.print(32, BYTE);
}

Not sure I understood your intent, but if I did, you could try the following.

Replace :

for (int pin= 2; pin<=13; pin++){     // Read and send digital pins 2-13
   x = digitalRead(pin);
   sendValue (x);
   }

with:

for (int pin= 2; pin<=6; pin++){     // Read and send digital pins 2-6 if button is pressed
   if (digitalRead(buttonPin) = HIGH) {x = digitalRead(pin);}
     else {x=LOW;} // or whatever value you want to send when button is not pressed
   sendValue (x);
   }

for (int pin= 7; pin<=13; pin++){     // Read and send digital pins 7-13
   x = digitalRead(pin);
   sendValue (x);
   }

Note that I didn't try this on an Arduino, so YMMV.

I was trying to make it send a default value for pins 2-6 if the button is not pressed (the button pin reads LOW) and send the corresponding pin value if the button is pressed (the button pin reads HIGH).

Note that you may want to debounce the button input and put the button test outside the loop for pins 2-6 rather than inside, if you don't want the possibility of some pins reading default and others their measured values within the same frame. Was that your intent?

Lastly, you will need to define which pin is the button pin somewhere at the beginning of the sketch, with:

int buttonPin =13; // or whatever value you want

If you use the code above, the value of the buttonPin will get sent along with the others. Even if it is between 2 and 6, it will send LOW when it is low since that is the default, and HIGH when it is high.

:slight_smile:

Mathleu,

It's close, but when I compile the code with your additions, I get an error message highlighting this line of code:

if (digitalRead(pin) = HIGH)

This is what I have for code.

int x = 0; // a place to hold pin values
int ledpin = 13;

void setup()
{
Serial.begin(115200); // 115200 is the default Arduino Bluetooth speed
digitalWrite(13,HIGH); ///startup blink
delay(600);
digitalWrite(13,LOW);
pinMode(13,INPUT);
}

void loop()
{

if (Serial.available() > 0){ // Check serial buffer for characters

if (Serial.read() == 'r') { // If an 'r' is received then read the pins

for (int pin= 0; pin<=5; pin++){ // Read and send analog pins 0-5
x = analogRead(pin);
sendValue (x);
}

for (int pin= 2; pin<=6; pin++){ // Read and send digital pins 2-6 if button is pressed
if (digitalRead(pin) = HIGH)
{x = digitalRead(pin);}
else {x=LOW;} // or whatever value you want to send when button is not pressed
sendValue (x);
}

for (int pin= 7; pin<=13; pin++){ // Read and send digital pins 7-13
x = digitalRead(pin);
sendValue (x);
}

Serial.println(); // Send a carriage returnt to mark end of pin data.
delay (5); // add a delay to prevent crashing/overloading of the serial port

}
}
}

void sendValue (int x){ // function to send the pin value followed by a "space".
Serial.print(x);
Serial.print(32, BYTE);
}

It's all starting to make more sense to me but I just need a little more help. Thanks.

anne

Matt was in a rush, he meant:
if (digitalRead(pin) == HIGH) // two equal signs

Doh! :stuck_out_tongue:

Thanks Mem, that's what you get for not trying the code sample for at least compiling in the IDE before posting it :slight_smile:

Other thing, tho, Anne, why did you change buttonPin to pin in the if test?

The way you have it set up, the software runs the test on each pin before measuring that pin, which is kinda redundant and doesn't help with the button.

You need to pick a pin to dedicated to the button, any pin will do, connect that button to it, and then make the if test read THAT pin to decide whether to send the default value or not.

Matt,

The code loads fine but I still get a chatter from the digital pin when I'm not pushing the button. It is as if the Arduino is constantly polling. Perhaps adding debounce would solve this?

What is strange is that the analog ports are fine. Once I attach a pot to them, there is no chatter at all.

anne

I changed it because I got:

error: 'buttonPin' was not declared in this scop

but actually I should have put (2Pin) or something like that.

anne

Anne, our posts crossed in the aether. :slight_smile:

I'm beginning to suspect we don't have the same intent for our code.

Do you want a single button that turns detection on and off for all pins between 2 and 6, or did you a button per input pin between 2 and 6 to turn each pin on and off separately?

If the former, try defining a button pin and replacing pin by button pin in the if test as suggest above.

If the latter, I think you need a hardware solution, not a software solution, wiring up a button per pin that either grounds that pin or connects it to the signal it is supposed to measure, depending on button position

To define buttonPin and avoid the error, after this part:

int x = 0;                              // a place to hold pin values
int ledpin = 13;

add this:

int buttonPin = 2; // or which ever pin you like

Off to lunch, good luck and talk to you in a bit. :wink:

Matt,

If we both took our lunch breaks at the same time then we must be on the same continent.

I suspected that we needed to clarify the intent of the hardware/software and your second assumption was what I'm after:

"did you want a button per input pin between 2 and 6 to turn each pin on and off separately?

"If the latter, I think you need a hardware solution, not a software solution, wiring up a button per pin that either grounds that pin or connects it to the signal it is supposed to measure, depending on button position"

My problem seems to be that the button doesn't have a ground so that when it is not engaged it sends high and low with about 25% high and 75% low. I haven't seen buttons with a third prong but maybe I need to simply research that.

Right now I'm filtering the chatter out in max but for future purposes I'd like to get a handle on this.

anne

Yes, I'm in the South of France, visiting family. Makes lunch a rather enjoyable proposition.

:wink:

ok, keep the original code and let's find the right hardware solution for your needs.

The reason the pin returns high and low semi-randomly is that it is left to float around, not connected to anything specific. So you need some way for the pin to always be connected to ground when its button is off, and connected to an input when it is not.

There are several types of buttons and switches, but I'm assuming that you have a button that connects its two contacts when you press it, and disconnects them when you don't, since you have this floating behavior.

There is a classic solution called a pull-down resistor that may help, depending on the circuit you are getting your signal from:

Basically, the idea is that if the button is not pressed, your input pin is connected to ground thru a resistor, so without a source of volts, the pin is pulled down to ground and reads LOW, while if the button is pressed, a signal from the other side of the button will be read at your input pin.

This last is only true if the source of your signal can provide enough current to flow thru the pull-down resistor. If this were not the case, your signal source being enable to generate enough current would see its voltage drop and if it falls below the minimum to be read as HIGH, you'd never be able to see the signal at your input pin.

Hum... I hope that makes some sense?

In the case of a 5V arduino, that current is 5V divided by 10,000 ohms or 0.5mA... not very much at all for most signal sources.

Give it a try on one pin and see if it helps at all.

Matt,

Your proposed solution makes sense. I'll need a day to run across town to buy the resistor. I suspected the problem was something like that.

I'll get back to you in a few days with hopefully a positive report.

In the meantime, enjoy southern France. The weather in Europe is unusually good right now.

anne

Thanks, it is, indeed gorgeous. Was in London for work yesterday and it was, uh, not so nice.

::slight_smile:

I'll need a day to run across town to buy the resistor.

anne, no nead to buy anything, the Arduino has built in resistors for this purpose that you can turn on by doing a digital write to the input pin
int buttonPin = 2; // or which ever pin you like
pinMode(buttonPin, INPUT); // set pin to input
digitalWrite(buttonPin, HIGH); // turn on pullup resistors

You can read more about this here: http://arduino.cc/en/Tutorial/DigitalPins

Was in London for work yesterday and it was, uh, not so nice.

Matt, you picked the wrong day, it was a beautiful morning in London today

Matt, you picked the wrong day, it was a beautiful morning in London today

Figures... :-? ah well, was in windowless meeting rooms most of the day anyway.

... Arduino has built in resistors for this purpose ...

I always forget those :-[

Anne, use the internal pull-ups instead of the external pull-down as mem suggests but of course the pin will read HIGH rather than LOW when the button is not pressed.

But now the button only reads high whether or not it's being pushed. :-?

What is the signal source you connected at the other end of the button?

You see, with the pull-up activated, that pin will read high unless something else pulls it down. So you need a signal and its source needs to be able to sink enough current to create a voltage drop of 5 volts across the pull-up resistor.

For example, if you connect the other side of that button to ground, you should be able to toggle that pin HIGH or LOW by pressing the button.

Right. I understand that, but without 3 prongs on the button, how do I also send a message to max/msp? Or do I need to program another pin to send a message to another pin? This seems like alot of hardware for a simple message. :-/

Matt and Mem,

OK. Got it. Done. Happy. Full of wisdom. Many thanks. ::slight_smile:

Hum... I think we've been too quick to think we understood each other again. Lemme try to explain how I envision your setup, and tell me if I'm wrong and why, please.

  1. I think you have an Arduino that is reading the values of its pins and sending these to a PC where they will be processed by max/msp.

  2. I think you want, for each of pins 2 thru 6, to have a button which enables or disables the reading for that pin.

  3. I think you have various signal sources, be they sensors or devices, you are connecting to your Arduino's pins to provide the values being measured and sent to the PC.

Now, say you have a signal that oscillates between high and low every 2 seconds. You connect it to pin 4, and max/msp see that pin as HIGH because you have not pressed its button. You press the button and now max/msp sees that pin go high/low every 2 seconds.

There is no need for a third prong on the button in this scenario. The pin is held high if the button disconnects it from the signal source, and is driven by the signal source when the button connects it (the pin) to it (the signal source).

Is that what we are trying to do? If so, can you give us some examples of signal sources you are interested in connecting to your Arduino?