Go Down

### Topic: Urgent Help! Multiple Sensor Inputs and Multiple LED outputs (Read 2122 times)previous topic - next topic

#### drummerboi

##### Aug 12, 2012, 12:46 pm
Hey Guys

I'm doing a Year 12 D&T Major work this year. I made a drum kit and have put LED strips and sensors inside each drum. The idea is that each drum lights up in accordance to how hard I hit it. The entire circuit is built all I need to do is program my Arduino ATmega1280 to control it all.

So far I have a code that, when the sensor is triggered, the lights flash on in one drum. But that is all I can do. I can't seem to make a code that will control all four drums. All the drums will have the same function and so it is probably an easy fix but I'm only a novice at Arduino code. Any help would be greatly appreciated.

The single drum code I have is:

//This code assumes the largest value you will get from a sensor is 55, anything larger is assumed as 55
int val, brightness=2; //=Sensor Pin--Needed integers for sensor and brightness
const int threshold=0, highestval=150; //Constant integer for the threshold of the drum input sensors.

void setup()
{
pinMode(3,OUTPUT); //LED Pin
analogWrite(3,2); //LED Pin, Sensor Pin
}

void loop()
{
if (val>threshold)
{
brightness = val * (255/highestval); //Multiply sensor input number by scaling factor

if(brightness >255) //Check the values is not greater than maximum analog amount
{
brightness = 255; //set to analog maximum amount
}
}

if(brightness>1) //Check number in brightness
{
analogWrite(3,brightness); // LED Pin--If the sensor reads something, turn on LED
brightness = brightness - 5;
}

else
{
analogWrite(3,0); // LED Pin, 0--if nothing is happening, turn LED off
}

delay(10);
}

Let me know what you think

Thanks

#### AWOL

#1
##### Aug 12, 2012, 01:15 pmLast Edit: Aug 12, 2012, 01:19 pm by AWOL Reason: 1
Where's the code for the four?
Maybe you weren't using PWM-capable pins.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

#### drummerboi

#2
##### Aug 12, 2012, 01:19 pm
Thats what I need help with. I don't know how to turn this single drum code into a code that will control all four.

#### AWOL

#3
##### Aug 12, 2012, 01:20 pmLast Edit: Aug 12, 2012, 01:22 pm by AWOL Reason: 1
Quote
I can't seem to make a code that will control all four drums.
But presumably you've tried.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

#### drummerboi

#4
##### Aug 12, 2012, 01:58 pm
Well I wanted to save myself some embarrassment, so please don't judge me for this. This code is my attempt at controlling two drums. I wanted to start with two and then once I had that figured out, I would use the same principle in adding two more drums to the code. This is what I came up with:

//This code assumes the largest value you will get from a sensor is 55, anything larger is assumed as 55
int val, brightness=3; //=Sensor Pin--Needed integers for sensor and brightness
const int threshold=0, highestval=150; //Constant integer for the threshold of the drum input sensors.

void setup()
{
pinMode(4,OUTPUT); //LED Pin
analogWrite(4,3); //LED Pin, Sensor Pin
pinMode(3,OUTPUT);
analogWrite(3,0);
}

void loop()
{
if (val>threshold)
if (val>threshold)
{
brightness = val * (255/highestval); //Multiply sensor input number by scaling factor

if(brightness >255) //Check the values is not greater than maximum analog amount
{
brightness = 255; //set to analog maximum amount
}
brightness = val * (255/highestval); //Multiply sensor input number by scaling factor

if(brightness >255) //Check the values is not greater than maximum analog amount
{
brightness = 255; //set to analog maximum amount
}
}

if(brightness>1) //Check number in brightness
{
analogWrite(4,brightness); // LED Pin--If the sensor reads something, turn on LED
brightness = brightness - 5;
analogWrite(3,brightness); // LED Pin--If the sensor reads something, turn on LED
brightness = brightness - 5;
}

else
{
analogWrite(4,0); // LED Pin, 0--if nothing is happening, turn LED off
analogWrite(3,0); // LED Pin, 0--if nothing is happening, turn LED off
}

delay(10);
}

As you can see I really just added in another output and input to the setup and duplicated the loop. I would not be surprised if you told me I was going about it in the completely wrong way.

#### AWOL

#5
##### Aug 12, 2012, 02:04 pm
You're repeating your calculation, but not writing out the values calculated.
Using the auto format feature of the IDE will help you visualise  the structure of your code better.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

#### PaulS

#6
##### Aug 12, 2012, 02:17 pm
Code: [Select]
`  pinMode(4,OUTPUT); //LED Pin`
Which Arduino are you using? On the 328-based boards, pin 4 is not a PWM pin.

Code: [Select]
`    brightness = val * (255/highestval); //Multiply sensor input number by scaling factor`
255/150 = 1. Why bother computing 1 each time?

The output from the analogRead pin is between 0 and 1023. You are multiplying this value by 1, and then constraining the value to 0 to 255. For analog output values of 255 to 1023, there will be no change in brightness.

Of course, whether this matters, or not, depends on the kind of sensor you are using. You haven't told us that.

The biggest problem, as AWOL points out, is nesting code for one sensor inside the block for another sensor. Always use curly braces after and if, else if, else, while, for, etc. statement. They make it easier to see when you are doing something wrong like this.

#### GoForSmoke

#7
##### Aug 12, 2012, 03:26 pm

Code: [Select]
`    brightness = val * (255/highestval); //Multiply sensor input number by scaling factor`
255/150 = 1. Why bother computing 1 each time?

The compiler will keep it from computing 1 each time. What he needs to do for his math is to remove the ().

Quote
The biggest problem, as AWOL points out, is nesting code for one sensor inside the block for another sensor. Always use curly braces after and if, else if, else, while, for, etc. statement. They make it easier to see when you are doing something wrong like this.

+1 (as in I agree totally)

Another problem is switching analog pins for nearly back-to-back reads. It takes a good bit of digging for newbies to find out that when you do that, you need to analog read twice and ignore the first result. That's done to clear the single on-chip ADC since otherwise you won't get good reads.

You can use digital pins for analog by reading how long each pin is held HIGH by the circuit.

2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### scottyjr

#8
##### Aug 12, 2012, 03:42 pm
Code: [Select]
`void loop(){  val = analogRead(3); //Sensor Pin--Read in from sensor  if (val>threshold)  val = analogRead(0); //Sensor Pin--Read in from sensor  if (val>threshold)`

Shouldn't the values read from the sensors have different names such as val3, val0? - Scotty

#### PaulS

#9
##### Aug 12, 2012, 03:53 pm
Quote
What he needs to do for his math is to remove the ().

Like so?
Code: [Select]
`brightness = val * 255 / highestval;`
So, suppose val is 100. 100 * 255 is 25,500. That works. Suppose val gets to be 150. 150 * 225 is 38,250. Oops. That will overflow an int. The, divide that overflowed value by 150. That won't undo the overflow.

No, the key is to change 255/highestval to 255.0/highestval, so that the result is a float. When multiplying an int by a float, the result is a float, which will be in the range of values that can be truncated to fit in an int, for the specified value of highestval.

Changing that val may cause problems, depending on whether the value is increased or decreased.

Quote
It takes a good bit of digging for newbies to find out that when you do that, you need to analog read twice and ignore the first result.

Whether that needs to be done, or not, depends on the rate of change of the sensor being read, and the impedance of that sensor, Since there has been nothing said about the sensor, blanket statements like this are inappropriate.

#### GoForSmoke

#10
##### Aug 12, 2012, 05:20 pm
He could use longs to do the calculation and be a lot faster.

Blanket or not, reading twice and ignoring the first is going to work, but it is so slow -- not even 5 good reads in a whole millisecond!

He could also time how long a digital pin is held high by his circuit to get analog reading. With a good circuit he could get decent reads much faster than through the ADC even with fast read. Think how many sensors he could use then!

2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### PaulS

#11
##### Aug 12, 2012, 05:40 pm
Quote
He could use longs to do the calculation and be a lot faster.

True. Although float multiplication is faster that float division, which only needs to be done once.

Quote
Blanket or not, reading twice and ignoring the first is going to work, but it is so slow -- not even 5 good reads in a whole millisecond!

True. But, I'd still prefer to know exactly what kind of sensor is being read before offering advice on the "best" way to read it.

Quote
He could also time how long a digital pin is held high by his circuit to get analog reading.

Hmmm. Wouldn't that depend on the type of sensor? I can't see how that would work with an accelerometer, for instance. Or a flex sensor. Well, maybe with a flex sensor I could, as long as the sensor dropped back to 0 when the drum was not being hit.

#### GoForSmoke

#12
##### Aug 12, 2012, 07:55 pm
It would depend more on the circuit having RC behavior, which should work with any analog sensor I can think of. It works with all the ones I've tried. The 'hard part' for me is tuning the circuit to get reads in less than 50 micros, but that's why I've got lots of different resistors and caps  XD. For lights in drums, <10 to 20 micros is probably resolution enough!

I've had good luck using piezo disks for tap/touch sensors. I can recommend running the leads through diodes with the one on each lead pointing away connecting to an NPN transistor and the diodes pointing towards the lead connecting straight to ground. That lets the the flex of the tap go to one pin and the flex back to another pin. The diodes make the threshold but even a soft touch can be detected depending on how you feed the collectors, it's very tunable.

I don't think I claimed that the double read is best, just what you can find in the docs. Probably the best thing to do is run tests and if the results are crap then double-read will fix.

But how fast or often does he need to read? Nobody can see the difference. In fact....
If the code sets up each sensor in an array so one index selects which to operate then code to read only one sensor in loop() with the index changing each time through would still be overkill. To go there from what he has working now should be pretty simple.

2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up

Please enter a valid email to subscribe