Store piezo knocked beat then output via solenoids

Im trying to make a art installation piece that basically is a small box that you can knock a beat on and it will bounce about (via solenoids "a bit like the jumping toaster in ghostbusters2") at same beat you knocked it.

I've got a piezo waiting on the solenoids from ebay and transistors to control the solenoids, but not to great at the whole programming bit.

So far I have an led blinking when the piezo is knocked

/*piezo sketch
*lights and LED when Piezo is tapped
*/

const int sensorPin = 0; // the analog pin connected to the sensor
const int ledPin = 13; // pin connected to LED
const int THRESHOLD = 100;
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
int val = analogRead(sensorPin);
if (val >= THRESHOLD)
{
digitalWrite(ledPin, HIGH);
delay(100); // to make the LED visible
}
else
digitalWrite(ledPin, LOW);
}

now I could get that to trigger the solenoid as soon as its been knocked, but I would like to store a beat of knocks then wait if their are any more for 5 or so seconds then output them to the solenoids.

Can any one help? gimme some pointers?

thanks Jon

/*piezo sketch
 *lights and LED when Piezo is tapped
  */
  
const int sensorPin = 0;  // the analog pin connected to the sensor
const int ledPin = 13;    // pin connected to LED
const int solPin = 10;    // pin connected to transistor-solenoid

const int THRESHOLD = 100;
long timing_rythm[10] = 0;   // 10 beat, could be more;
int count = 0;
int play = 0;


void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(solPin, OUTPUT);
}

void loop()
{
 if ( !play ) {
  int val = analogRead(sensorPin);
  if (val >= THRESHOLD)
  {
    digitalWrite(ledPin, HIGH);
    delay(100);  // to make the LED visible
timing_rythm[count] = millis();
    count++;
if (count == 10) count = 0;

  }
  else
    digitalWrite(ledPin, LOW);
 }
if( (millis() -  timing_rythm[count]) > 5000 ) play = 1;

 if (play) {
 for(  count =0; count < 10; count++) {
    digitalWrite(solPin, HIGH);
    delay(100);  // to make the solenoid be heard
    digitalWrite(solPin, LOW);
    delay(timing_rythm[count +1] - timing_rythm[count] - 100) 
}
play =0;
}
}

*Not tested, just idea

I tried that and I'm getting this error

sketch_aug14a:9: error: array must be initialized with a brace-enclosed initializer
sketch_aug14a.cpp: In function 'void loop()':
sketch_aug14a:44: error: expected `;' before '}' token

??

long timing_rythm[10] = {0};

or just long timing_rythm[10];  

sketch_aug14a:44: error: expected `;' before '}' token

delay(timing_rythm[count +1] - timing_rythm[count] - 100) ;
}

thats better thanks AWOL its compiled fine now, but it still only getting output at the same time the piezo is triggered, not recorded then playback???

Time to sprinkle in some debug prints.

Here's how its looking so far

/*piezo sketch
 *lights and LED when Piezo is tapped
  */
  
const int sensorPin = 0;  // the analog pin connected to the sensor
const int ledPin = 13;    // pin connected to LED
const int solPin = 10;    // pin connected to transistor-solenoid

const int THRESHOLD = 40;
long timing_rythm[10];   // 10 beat, could be more;
int count = 0;
int play = 0;


void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(solPin, OUTPUT);
}

void loop()
{
 if ( !play ) {
  int val = analogRead(sensorPin);
  if (val >= THRESHOLD)
  {
    digitalWrite(ledPin, HIGH);
    delay(100);  // to make the LED visible
timing_rythm[count] = millis();
    count++;
if (count == 10) count = 0;

  }
  else
    digitalWrite(ledPin, LOW);
 }
if( (millis() -  timing_rythm[count]) > 5000 ) play = 1;

 if (play) {
 for(  count =0; count < 10; count++) {
    digitalWrite(solPin, HIGH);
    delay(100);  // to make the solenoid be heard
    digitalWrite(solPin, LOW);
    delay(timing_rythm[count +1] - timing_rythm[count] - 100);
}
play =0;
}
}

so at the minute its triggering output as its hit, so still need it to record a succession of knocks, wait for any more and if no knocks follow for 5 seconds it then outputs the sequence.

it also seems to go to sleep or something if it hasn't been triggered for a couple of minutes so has to be reset??

thanks for everyone who has helped so far!! :slight_smile:

As AWOL advised you, insert "printing line" in the code, so you would get information what going on and correct some code pieces, if it's not working as you expected.
First, insert in the setup:

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(solPin, OUTPUT);
  Serial.begin(115200);  // <<<<<<<--------- Serial, speed 115200 you have to select this value //in Serial Monitor window. 
}

Than, insert "printing lines" :

void loop()
{
 if ( !play ) {
  int val = analogRead(sensorPin);
  if (val >= THRESHOLD)
  {
   Serial.print("\t Have analog read with value: ");
   Serial.println(val);

    digitalWrite(ledPin, HIGH);
    delay(100);  // to make the LED visible
timing_rythm[count] = millis();
    count++;
   Serial.print("Number of beat: ");
   Serial.println(count);

if (count == 10) count = 0;

  }
  else
    digitalWrite(ledPin, LOW);
 }
if( (millis() -  timing_rythm[count]) > 5000 ) play = 1;

 if (play) {
   Serial.println("Turn to play mode, 5 sec no knocking!: ");
 //  Serial.println(nbr);

 for(  count =0; count < 10; count++) {
    digitalWrite(solPin, HIGH);
    delay(100);  // to make the solenoid be heard
   Serial.print("Have you heard it? , I just play beat number: ");
   Serial.println(count);
}
    digitalWrite(solPin, LOW);
    delay(timing_rythm[count +1] - timing_rythm[count] - 100);
}
play =0;
}
}

So, if you like to check workflow of the program, insert as many printing lines, as necessary ! :slight_smile: