Need help to modify "Knock" code to light LED

First I have ever worked with Arduino. I have completed the "KnocK" tutorial and things work as expected. For my first project, I need to modify the knock code, so an LED on pin 10 strobes for 3 seconds, then shuts off,. Tried my hand at it, but did not get the results I am looking for.

Any assistance would be appreciated:

I am using an Arduino mini 328 and a piezo vibration sensor-small horizontal

http://www.arduino.cc/en/tutorial/knock

Tried my hand at it, but did not get the results I am looking for.

Well post the code you tried, and explain what results you did get…

OK…My goal this round was to get the Knock and Blink code to work together. However, it is the strobe effect that I am looking to achieve:

The following code produces a single blink of the LED whenever the piezo is triggered:

/* Knock Sensor
This sketch reads a piezo element to detect a knocking sound.
It reads an analog pin and compares the result to a set threshold.
If the result is greater than the threshold, it writes
“knock” to the serial port, and toggles the LED on pin 13.
The circuit:

    • connection of the piezo attached to analog in 0
    • connection of the piezo attached to ground
  • 1-megohm resistor attached from analog in 0 to ground

created 25 Mar 2007
by David Cuartielles http://www.0j0.org
modified 30 Aug 2011
by Tom Igoe
This example code is in the public domain.

*/

// these constants won’t change:
const int ledPin = 10; // led connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 10; // threshold value to decide when the detected sound is a knock or not

// these variables will change:
int sensorReading = 0; // variable to store the value read from the sensor pin
int ledState = LOW; // variable used to store the last LED status, to toggle the light

void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
Serial.begin(9600); // use the serial port
}

void loop() {
// read the sensor and store it in the variable sensorReading:
sensorReading = analogRead(knockSensor);
// if the sensor reading is greater than the threshold:
if (sensorReading >= threshold) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
// update the LED pin itself:
digitalWrite(ledPin, ledState);
// send the string “Knock!” back to the computer, followed by newline
Serial.println(“Knock!”);
}
delay(100); // delay to avoid overloading the serial port buffer
}

I got it to work with this hack. Open to a cleaner solution :slight_smile:

/* Knock Sensor
This sketch reads a piezo element to detect a knocking sound.
It reads an analog pin and compares the result to a set threshold.
If the result is greater than the threshold, it writes
“knock” to the serial port, and toggles the LED on pin 13.
The circuit:

    • connection of the piezo attached to analog in 0
    • connection of the piezo attached to ground
  • 1-megohm resistor attached from analog in 0 to ground

created 25 Mar 2007
by David Cuartielles http://www.0j0.org
modified 30 Aug 2011
by Tom Igoe
This example code is in the public domain.

*/

// these constants won’t change:
const int ledPin = 10; // led connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 5; // threshold value to decide when the detected sound is a knock or not

// these variables will change:
int sensorReading = 1; // variable to store the value read from the sensor pin
int ledState = HIGH; // variable used to store the last LED status, to toggle the light

void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
Serial.begin(9600); // use the serial port
}

void loop() {
// read the sensor and store it in the variable sensorReading:
sensorReading = analogRead(knockSensor);
// if the sensor reading is greater than the threshold:
if (sensorReading >= threshold) {
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}

Open to a cleaner solution

Like maybe a for loop? 7 lines of code to replace that mess of code.

:slight_smile:

This is the first I have heard of Arduino. Would love to replace my mess if you can provide an example. Will see what I can learn

Here is my stab at using the For loop. There is probably a better way to get the strobe effect I am looking for, but this works. Currently, the loop only runs for very brief interval, as I trigger the piezo switch. I need it to loop for 3-4 seconds, instead. How can I adjust my loop for the desired effect?

const int ledPin = 10; // led connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 5; // threshold value to decide when the detected sound is a knock or not

// these variables will change:
int sensorReading = 1; // variable to store the value read from the sensor pin
int ledState = HIGH; // variable used to store the last LED status, to toggle the light
int timer = 20;

void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
Serial.begin(9600); // use the serial port
}

void loop() {
// read the sensor and store it in the variable sensorReading:
sensorReading = analogRead(knockSensor);
// if the sensor reading is greater than the threshold:
if (sensorReading >= threshold)
for (int thisPin = 10; thisPin < 12; thisPin++) {
// turn the pin on:
digitalWrite(thisPin, HIGH);
delay(timer);
// turn the pin off:
digitalWrite(thisPin, LOW);

}
}

Hi… glad you got some progress.

This might help with the next step: have a look at millis and do…while. The idea would be to log the time in millis just after the knock test, then start the “do…while”. At the end of each pass thru the “do”, it checks to see if 3 seconds has elapsed: if not, it goes back to the top of the “do”, and if time’s up it exits at the bottom.

Psuedo code like this

unsigned long startTime = millis()
do{
...... blink the lights here
} while (millis()-  startTime < 3000)

Thank you… I made some progress with the following: (LED stays on for 3 seconds, but does not strobe, as before.)

const int ledPin = 10; // led connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 5; // threshold value to decide when the detected sound is a knock or not

// these variables will change:
int sensorReading = 1; // variable to store the value read from the sensor pin
int ledState = HIGH; // variable used to store the last LED status, to toggle the light
int timer = 20;

void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
Serial.begin(9600); // use the serial port
}

void loop() {
// read the sensor and store it in the variable sensorReading:
sensorReading = analogRead(knockSensor);
// if the sensor reading is greater than the threshold:
if (sensorReading >= threshold)
for (int thisPin = 10; thisPin < 12; thisPin++) {
// turn the pin on:
unsigned long startTime = millis();
do{
digitalWrite(thisPin, HIGH);
delay(timer);
// turn the pin off:
digitalWrite(thisPin, LOW);
} while (millis()- startTime < 3000);

}
}

try this

const int ledPin = 10;      // led connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 5;  // threshold value to decide when the detected sound is a knock or not


// these variables will change:
int sensorReading = 1;      // variable to store the value read from the sensor pin
int ledState = HIGH;         // variable used to store the last LED status, to toggle the light
int timer = 20;

void setup() {
 pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
 Serial.begin(9600);       // use the serial port
}

void loop() {
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor);
    // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold)
   unsigned long startTime = millis();
do{
    digitalWrite(ledPin , !digitalRead(ledPin ));   
    delay(timer);                 
 } while (millis()-  startTime < 3000);
}

I get the following error:

" 'startTime' was not declared in this scope"

 if (sensorReading >= threshold) 
{
   unsigned long startTime = millis();
   do{
     digitalWrite(ledPin , !digitalRead(ledPin ));   
     delay(timer);                 
  } while (millis()-  startTime < 3000);
}
}

Yes... That worked!

Thank you for the replies!