Hi all, figured this was PROBABLY the right place for this, but it could probably also fall under Programming Questions.
Basically I am trying to create some sound-reactive LEDs in the form of an LED equalizer, or that is the aim of the final project.
At the moment, I am just experimenting with using a shift register to turn on the correct number of lights determined by a number passed over serial to the arduino.
Here is the code I have so far:
int data = 2;
int clock = 3;
int latch = 4;
int v;
int lights = 0;
void setup(){
Serial.begin(9600);
pinMode(latch, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(data, OUTPUT);
}
void loop(){
v = getSerial();
lights = calculate(v);
light(lights);
lights = 0;
}
//processes serial input
int getSerial(){
if (Serial.available()) {
//convert char to int
v = int(Serial.read()-'0');
}
return v;
}
//works out the value to be passed to light()
int calculate(int v){
lights = (pow(2,v)-1);
return(lights);
}
//turns on the required number of LEDs (supposedly)
void light(int lights){
digitalWrite(latch, LOW);
shiftOut(data, clock, MSBFIRST, lights);
digitalWrite(latch, HIGH);
delay(10);
}
Now my problem arises when it comes to understanding how the binary is processed.
I have 8 LEDs in a row. If the "volume" is three, I need to turn 3 LEDs on. Because I am using a shift register, and because binary uses the formula 2^x, or in my case 2^v, 2^3 would be 8, which would turn on 4 LEDs, but seeing as I only need 3, I have to take 1 away.
However, this does not work as expected. For one LED, it works perfectly, but for more than one, the value passed to light() is 1 too small. If I change the line
lights = (pow(2,v)-1);
to
lights = (pow(2,v));
then it works fine EXCEPT for the case where the "volume" is 1, as obviously, the arduino works out 2^1, which is ovbiously 2, so it turns on the second LED.
I am guessing here, but does the issue arise when converting the char from the serial input to an int? Or is this not the problem?
If any more detail is needed, I will be happy to provide.
Thanks,
Sam