Go Down

Topic: Controlling 5 leds with 5 Piezo sensors (Read 659 times) previous topic - next topic

rhukkk

Hello there,
I'm trying to control 5 leds (pin(13,12,8,7,4)) with 5 piezos (A0,A1,A2,A3,A4). something like piezoA0 switch pinled1, piezo A1 switch pinled2 etc etc.
I've written down a simple program to switch 1 led on/off with 1 piezo.

Code: [Select]

int ledPin =13;
int piezoPin = 0;
int val = 0;
int ledStatus = LOW;
int threshold = 1;

void setup(){
  pinMode(ledPin, OUTPUT); 
  Serial.begin(9600); 
}

void loop() {
  val = analogRead(piezoPin); 
    if(val>= threshold){
        ledStatus = !ledStatus;
        digitalWrite(ledPin, ledStatus);
        Serial.println(val);
        delay(180);
      }
  delay(10);
}


and than i tryed with fail to array the piezo and the leds. like in the example below. I'm sure i'm doing wrong since here i can control 5 leds with 1 piezo only and this is not what i need:

Code: [Select]

const int analogPin = A0;
const int ledCount = 5;

int ledPins[] = {4,7,8,12,13};


int ledStatus = LOW;

void setup() {
 
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
    pinMode(ledPins[thisLed], OUTPUT);
  }
}

void loop() {
 
 
 
  int ledLevel = 1;
  int sensorReading = analogRead(analogPin);
  //map(sensorReading, 0, 1023, 0, ledCount);

 
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
   
    if (sensorReading > ledLevel) {
      ledStatus = !ledStatus;
      digitalWrite(ledPins[thisLed], ledStatus);
      Serial.println(ledPins[thisLed]);
      delay(10);
    }
   
  }
 
}


can someone help me?

Thank u!

knut_ny

Code: [Select]
const byte ledCount = 5;
byte ledPins[] = {4, 7, 8, 12, 13};
int sensorReading;
int ledLevel = 1; // why 1 for analog value ??

void setup()
{
  for (int thisLed = 0; thisLed < ledCount; thisLed++) pinMode(ledPins[thisLed], OUTPUT);
}

void loop()
{
  for (int thisLed = 0; thisLed < ledCount; thisLed++)
  {
    sensorReading = analogRead(thisLed); // runs: 0,1,2,3,4,5
    if (sensorReading > ledLevel)
    {
      digitalWrite(ledPins[thisLed], !digitalRead(ledPins[thisLed])); // toggle led N
      // Serial.println(ledPins[thisLed]); // why this ?? Take a look at the LED
      // if you NEED it: Serial.println(digitalRead(ledPins[thisLed]);
      delay(10); // why this here ??
    }
  }
}
Ny

Grumpy_Mike

Odd that https://forum.arduino.cc/index.php?topic=476394.0 makes the same mistake in coding the pin setup. Do you know each other, perhaps in the same class and have only programmed in Python?

rhukkk

No i 've never meet him :)
well, i'm not the best in programming. i'm trying to improve myself.
By the way the sketch is not working properly. the led lights up intermittently and when i press the piezo it stops. but i would like it to light on and off with no intermittence. this is cos of delay(10). if i remove it from the sketch it seems to work but not properly. the led is so fast to turn on and off that it seems to be on actually. so happen that when i press the piezo the led just select the state in that moment.
i don't know if i explane good myself but this is the problem (im sorry for my english im italian).

Best,
F

rhukkk

Now i understand ur code but i would like the led to switch on when the piezo is hitted and keep that state until i hit the piezo again.
Thank u guys!

Grumpy_Mike

So post your corrected code so far and we will look at it. Your current code has changed too much, and we need to know if you have corrected he code and not introduce any more errors.

rhukkk

Ok Mike, thank u!
This is what i have.
Code: [Select]

const byte ledCount = 4;
byte ledPins[] = {4, 7, 8, 12, 13};
int sensorReading;
int ledLevel = 1;

void setup()
{
  for (int thisLed = 0; thisLed < ledCount; thisLed++) pinMode(ledPins[thisLed], OUTPUT);
}

void loop()
{
  for (int thisLed = 0; thisLed < ledCount; thisLed++)
  {
    sensorReading = analogRead(thisLed);
    if (sensorReading > ledLevel)
    {
      digitalWrite(ledPins[thisLed], !digitalRead(ledPins[thisLed]));
      delay(10);
      Serial.println(sensorReading);
    }
   
  }
}

Grumpy_Mike

OK first of all you have no Serial.begin call so you will never see anything. Set the baud rate to the highest value possible and adjust the serial monitor to match.

Next this line
Code: [Select]
digitalWrite(ledPins[thisLed], !digitalRead(ledPins[thisLed]));
Simply constantly inverts ( toggles ) the state of the LED while the analogue reading is above 1. There are two things wrong with this:-
1) A value of 1 is way too low. Try printing out the values you read from the sensor. I bet you will find a value of 100 is more like the point.
2) You don't want to toggle the state of the LED you want to turn it on. Only when the sensor reading drop below the LED level do you want to turn off the LED next time the LED level is exceeded.

So you need a booliean variable ( one for each sensor / LED so make an array of them ) to tell you if to turn the LED on or off in that wrong line you have.

The delay is doing nothing for you remove it.

rhukkk

Ok Mike,

Yes i forgot adding Serial.begin(9600); but i'm still confused about array. could u please help me with it?
This is what i have:
Code: [Select]

const byte ledCount = 4;
byte ledPins[] = {4, 7, 8, 12, 13};
int sensorReading;
int ledLevel = 70;

void setup()
{
  for (int thisLed = 0; thisLed < ledCount; thisLed++) pinMode(ledPins[thisLed], OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  for (int thisLed = 0; thisLed < ledCount; thisLed++)
  {
    sensorReading = analogRead(thisLed);
    if (sensorReading > ledLevel)
    {
      digitalWrite(ledPins[thisLed], !digitalRead(ledPins[thisLed]));
      delay(10);
      Serial.println(sensorReading);
    }
   
  }
}


Thank u in advance!


Grumpy_Mike

So when you followed the advice of:-
Try printing out the values you read from the sensor. I bet you will find a value of 100 is more like the point.

What did you get?

Quote
but i'm still confused about array. could u please help me with it?
What is confusing about "array"? If you can say what you don't understand I could explain that bit.

rhukkk

Hi there Mike,
Actually the piezos are attached to 5 wine bottles so i need lower values cos i'm not going to touch the piezo directly and the values i get are pretty low when i play with the bottle.
btw i was trying to use no array and this is what i've done.

Code: [Select]

int piezo1 = 0, piezo2 = 1, piezo3 = 2, piezo4 = 3, piezo5 = 4;
int led1 = 4, led2 = 7, led3 = 8, led4 = 12, led5 =13;
int threshold = 70;

void setup(){
  pinMode(piezo1, INPUT);
  pinMode(piezo2, INPUT);
  pinMode(piezo3, INPUT);
  pinMode(piezo4, INPUT);
  pinMode(piezo5, INPUT);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  Serial.begin(9600);
}

void loop(){

  if(analogRead(piezo1)>=threshold){
    digitalWrite(led1, 1);
  }else{
    digitalWrite(led1, 0);
  }
  if(analogRead(piezo2)>=threshold){
    digitalWrite(led2, 1);
  }else{
    digitalWrite(led2, 0);
  }
  if(analogRead(piezo3)>=threshold){
    digitalWrite(led3, 1);
  }else{
    digitalWrite(led3, 0);
  }
  if(analogRead(piezo4)>=threshold){
    digitalWrite(led4, 1);
  }else{
    digitalWrite(led4, 0);
  }
  if(analogRead(piezo5)>=threshold){
    digitalWrite(led5, 1);
  }else{
    digitalWrite(led5, 0);
  }
  
}


Grumpy_Mike

You don't need to set the piezo bits as inputs, when you use them as analogue reads that will set them to be analogue inputs.
This is your code converted to use arrays:-
Code: [Select]
int led [] = {4, 7, 8,12,13};
int threshold = 70;

void setup(){
  for(int i=0; i<5;i++){
  pinMode(led[i], OUTPUT);
  }
  Serial.begin(9600);
}

void loop(){
  for(int sensor = 0; sensor<5; sensor++){
  if(analogRead(sensor)>=threshold){
    digitalWrite(led[sensor], 1);
  }else{
    digitalWrite(led[sensor], 0);
  } 
 }
}

rhukkk

Thank u Mike,
Now i understand :D
Btw i would like the led to keep light on when i press the piezo and switch off when i press it again. i tried something like this but is not working very well

Code: [Select]

int led [] = {4, 7, 8,12,13};
int threshold = 20;
int ledStatus = LOW;

void setup(){
  for(int i=0; i<5;i++){
  pinMode(led[i], OUTPUT);
  }
  Serial.begin(9600);
}

void loop(){
  for(int sensor = 0; sensor<5; sensor++){
  if(analogRead(sensor)>=threshold){
    delay(25);
    ledStatus = !ledStatus;
    digitalWrite(led[sensor], ledStatus);
   
  }
 }
 
}

Grumpy_Mike

Like I said in reply #7

You don't want to toggle the state of the LED you want to turn it on. Only when the sensor reading drop below the LED level do you want to turn off the LED next time the LED level is exceeded.

So you need a booliean variable ( one for each sensor / LED so make an array of them ) to tell you if to turn the LED on or off in that wrong line you have.

rhukkk

#14
May 17, 2017, 10:39 pm Last Edit: May 17, 2017, 10:44 pm by rhukkk
Hey there Mike,
Ok, something like this?

Code: [Select]

int led [] = {2, 4, 7, 8, 12, 13};
int threshold = 40;
boolean ledStatus;

void setup(){
  for(int i=0; i<6;i++){
  pinMode(led[i], OUTPUT);
  }
  Serial.begin(9600);
}

void loop(){
  for(int sensor = 0; sensor<6; sensor++){
  if(analogRead(sensor)>=threshold){
    switch (ledStatus){
      case 0:
        digitalWrite(led[sensor], HIGH);
        ledStatus = 1;
      break;
      case 1:
        digitalWrite(led[sensor], LOW);
        ledStatus = 0;
      break;   
      }
    }
  }
}

Go Up