the function call just partly work

Now I am working on a Peizo sensor project. I need to drive the sensor vibration via PWM SineWave.
When I make my program only generate sine wave, the Peizo sensor can generate vibration. However When I add some conditions, like press judges (PressStatus), the Peizo sensor only produce some weak vibrations or just voice even I press the sensor. I think my highlighted code have something wrong, but I really don't know what I can I do.
my code is:

#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 8000/2 // 8 ksps

int outputPin = 6; // (PCINT22/OC0A/AIN0)PD6, Arduino Digital Pin 6
volatile uint16_t sample;
const int sinewave_length=256;


int led =13;
const int N=100;
float voltageValue[N];
float voltage[N];
boolean PressStatus;//Pressing flag;

const unsigned char sinewave_data[] PROGMEM = {
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};



void startPlayback()
{
  pinMode(outputPin, OUTPUT);
  // Set Timer 0 Fast PWM Mode (Section 14.7.3)
  // WGM = 0b011 = 3 (Table 14-8)
  // TOP = 0xFF, update OCR0A register at BOTTOM
  TCCR0A |= _BV(WGM01) | _BV(WGM00);
  TCCR0B &= ~_BV(WGM02);
  // Do non-inverting PWM on pin OC0A, arduino digital pin 6
  // COM0A = 0b10, clear OC0A pin on compare match,
  // set 0C0A pin at BOTTOM (Table 14-3)
  TCCR0A = (TCCR0A | _BV(COM0A1)) & ~_BV(COM0A0);
  // COM0B = 0b00, OC0B disconnected (Table 14-6)
  TCCR0A &= ~(_BV(COM0B1) | _BV(COM0B0));
  // No prescaler, CS = 0b001 (Table 14-9)
  TCCR0B = (TCCR0B & ~(_BV(CS02) | _BV(CS01))) | _BV(CS00);
  // Set initial pulse width to the first sample.
  OCR0A = pgm_read_byte(&sinewave_data[0]);
  // Set up Timer 1 to send a sample every interrupt.
  cli(); // disable interrupts
  // Set CTC mode (Section 15.9.2 Clear Timer on Compare Match)
  // WGM = 0b0100, TOP = OCR1A, Update 0CR1A Immediate (Table 15-4)
  // Have to set OCR1A *after*, otherwise it gets reset to 0!
  TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
  TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
  // No prescaler, CS = 0b001 (Table 15-5)
  TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  // Set the compare register (OCR1A).
  // OCR1A is a 16-bit register, so we have to do this with
  // interrupts disabled to be safe.
  OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
  // Enable interrupt when TCNT1 == OCR1A (p.136)
  TIMSK1 |= _BV(OCIE1A);
  sample = 0;
  sei(); // enable interrupts
}
void setup()
{
  startPlayback();
  //initialize serial communication at 4800bit per second;
  Serial.begin(4800);
  pinMode (led,OUTPUT);


}

void loop()
{
    int i;
  for(i=0;i<N;i++){
    //read the input on analog pin A0;
    voltageValue[i] = analogRead(A0);
    voltage[i] = voltageValue[i] * (5.0 / 1023.0);
    if (i>0&&voltage[i]-voltage[i-1]>=0.2){
      PressStatus=1;
      digitalWrite(led,HIGH);
    }

    else {
      PressStatus=0;
      digitalWrite(led,LOW);
    }
  }

}

// This is called at SAMPLE_RATE kHz to load the next sample.
[b]ISR(TIMER1_COMPA_vect) {
  if (sample < sinewave_length&&PressStatus=1) {
    OCR0A = pgm_read_byte(&sinewave_data[sample]);
     }
  else {
     sample = -1;
  }
  ++sample;
}[/b]

This is wrong:

  if (sample < sinewave_length&&PressStatus=1) {

It would be best to parenthesize the two separate conditions but the real problem is that '=' is assignment, not comparison.
Use this:

  if ((sample < sinewave_length) && (PressStatus == 1)) {

Pete

It would be best to parenthesize the two separate conditions

And, as Pete showed, some judicious use of white space makes the code so much easier to read.

I am sorry, I copy wrong code, actually my code is "==" instead of "=", but it still not work completely.

If you've copied and posted the wrong code, why not post the actual code?

I don't really see the point of the for loop.
If you're only interested in the differences between adjacent samples, why store 100 of them?

Hi AWOL,
See you again:)
My original code is as the following:

#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 8000/2 //control the fre of  the output signal =16M/SAMPLE_RATE/256

int outputPin = 6; // (PCINT22/OC0A/AIN0)PD6, Arduino Digital Pin 6
volatile uint16_t sample;
const int sinewave_length=256;


int led =13;
const int N=100;
float voltageValue[N];
float voltage[N];
boolean PressStatus;//Pressing flag;

const unsigned char sinewave_data[] PROGMEM = {
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};



void startPlayback()
{
  pinMode(outputPin, OUTPUT);
  // Set Timer 0 Fast PWM Mode (Section 14.7.3)
  // WGM = 0b011 = 3 (Table 14-8)
  // TOP = 0xFF, update OCR0A register at BOTTOM
  TCCR0A |= _BV(WGM01) | _BV(WGM00);
  TCCR0B &= ~_BV(WGM02);
  // Do non-inverting PWM on pin OC0A, arduino digital pin 6
  // COM0A = 0b10, clear OC0A pin on compare match,
  // set 0C0A pin at BOTTOM (Table 14-3)
  TCCR0A = (TCCR0A | _BV(COM0A1)) & ~_BV(COM0A0);
  // COM0B = 0b00, OC0B disconnected (Table 14-6)
  TCCR0A &= ~(_BV(COM0B1) | _BV(COM0B0));
  // No prescaler, CS = 0b001 (Table 14-9)
  TCCR0B = (TCCR0B & ~(_BV(CS02) | _BV(CS01))) | _BV(CS00);
  // Set initial pulse width to the first sample.
  OCR0A = pgm_read_byte(&sinewave_data[0]);
  // Set up Timer 1 to send a sample every interrupt.
  cli(); // disable interrupts
  // Set CTC mode (Section 15.9.2 Clear Timer on Compare Match)
  // WGM = 0b0100, TOP = OCR1A, Update 0CR1A Immediate (Table 15-4)
  // Have to set OCR1A *after*, otherwise it gets reset to 0!
  TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
  TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
  // No prescaler, CS = 0b001 (Table 15-5)
  TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  // Set the compare register (OCR1A).
  // OCR1A is a 16-bit register, so we have to do this with
  // interrupts disabled to be safe.
  OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
  // Enable interrupt when TCNT1 == OCR1A (p.136)
  TIMSK1 |= _BV(OCIE1A);
  sample = 0;
  sei(); // enable interrupts
}
void setup()
{
  startPlayback();
  //initialize serial communication at 4800bit per second;
  Serial.begin(4800);
  pinMode (led,OUTPUT);


}

void loop()
{
  int i;
  for(i=0;i<N;i++){
    //read the input on analog pin A0;
    voltageValue[i] = analogRead(A0);
    voltage[i] = voltageValue[i] * (5.0 / 1023.0);
    if (i>0&&voltage[i]-voltage[i-1]>=0.2){
      PressStatus=1;
      digitalWrite(led,HIGH);
    }

    else {
      PressStatus=0;
      digitalWrite(led,LOW);
    }
  }

}

// This is called at SAMPLE_RATE kHz to load the next sample.
ISR(TIMER1_COMPA_vect) {
  if ((sample < sinewave_length)&&(PressStatus==1)) {
    OCR0A = pgm_read_byte(&sinewave_data[sample]);
  }
  else {
    sample = -1;
  }
  ++sample;
}

Actually I am only interested in the sequent 10 or 20 data. I only initialize the number of data as 100.

BTW, you are a expert in arduino. can you give me your email?

Big thks

Actually I am only interested in the sequent 10 or 20 data.

No, your code is interested only in adjacent samples, so you need only a single sample buffer and the most recent sample.

you are a expert in arduino. can you give me your email?

No I'm not. No.

Hi AOWL,
I will make some modification in the future step by step and use other continous data later. What's your suggestion?
I just make modification as the following?

const int N=10;
float voltageValue[N];

I test my coding with oscilloscope, there is only one wave instead of holding for the press duration when I press the sensor.
What is the reason why my code only partly work? is related with the definition for the variable?

Big thks

No one can help me out?

No one can help me out?

I can't. I can't even understand your problem. Perhaps you need to try again.

Function calls don't "just partly work". The work. That they do not do what you want does not mean that they don't work.

You need to describe what function call you are talking about, describe what it actually does, describe what you expected it to do, and explain how those two differ AND how you KNOW that they differ.

Hi Pauls,
Now I am working on a Peizo sensor project.
When no any force is applied on the sensor's surface, the arduino will read the voltage of the sensor via Pin A0. When I press the sensor's surface, the code should judge the action as a "Press" and the flag "PressStatus" should be high.At the same time I need to drive the sensor vibration via PWM SineWave.

When I make my program only generate sine wave, the Peizo sensor can generate vibration (the vibration is what I want). However When I add some conditions, like press judges (PressStatus) in my modified code, the Peizo sensor only produce some weak vibrations or just voice When I press the sensor. Obviously I can find the flag "PressStatus" is high when I press the sensor. That means my "judge press" code should be right. But
I have tested my coding with oscilloscope, there is only one wave instead of holding for the press duration when I press the sensor.
What can I do next?
Emergency...

Thks a lot

When no any force is applied on the sensor's surface, the arduino will read the voltage of the sensor via Pin A0.

How does the Arduino know whether or not there is any force on the sensor, without reading it? What does the Arduino do if there is force on the sensor's surface?

Why do you save the analogRead() values in an array, when only the current reading and the previous reading are ever used?

You assign a value to PressStatus, in loop(). You check that value in the interrupt service routine, but you have not declared that PressStatus is volatile. So, the compiler is likely optimizing code out of existence.

I'll admit that I don't understand all that stuff in startPlayback(), but I suspect that you ISR is not doing what you think it does (because PressStatus is not volatile).

By the way, the only two values that are meaningful to assign to a boolean are true and false. Not 0 and 1.

How does the Arduino know whether or not there is any force on the sensor, without reading it? What does the Arduino do if there is force on the sensor's surface?

If a press is applied on the sensor, there will be a voltage jump. Of course I get the voltage by reading the value with Pin A0. My code is used to judge a press:
if (i>0&&voltage[i]-voltage[i-1]>=0.2)

Why do you save the analogRead() values in an array, when only the current reading and the previous reading are ever used?

Maybe I will use the sequent 10 data for the project in the future . If I just use the adjacent two data, what is your suggestion.

You assign a value to PressStatus, in loop(). You check that value in the interrupt service routine, but you have not declared that PressStatus is volatile. So, the compiler is likely optimizing code out of existence.

Yes, that is what I am thinking

I'll admit that I don't understand all that stuff in startPlayback(), but I suspect that you ISR is not doing what you think it does (because PressStatus is not volatile).
Yes, ISR is an Interrupt Service Routine for handling the periodic interrupt.

By the way, the only two values that are meaningful to assign to a boolean are true and false. Not 0 and 1.
I am sorry I forget to change.

BTW, How to use "quote" :slight_smile:

blizzard_ke:
If a press is applied on the sensor, there will be a voltage jump.

I'm willing to be told I'm wrong, but I think the piezo sensor measures pressure changes and not absolute pressures. If you apply a step change to the pressure you should see a voltage spike but I don't think a constant non-zero pressure will produce a constant non-zero voltage.

Hi PeterH,
Recently i am annoyed by the algorithm which how to judge a real press. Could you pls tell me more details or what your suggestion?

Thanks

If you apply a step change to the pressure you should see a voltage spike but I don't think a constant non-zero pressure will produce a constant non-zero voltage.

I suspect that is why the code is comparing subsequent reads, rather than comparing one value to an absolute threshold.

Hi Pauls,
You are right. A constant non-zero pressure may not produce a constant non-zero voltage. So I use a deduction of two adjacent data instead of a threshold as a touchstone. What's your suggestion? Do you have any idea about judge an action is a touch, hit or naturally releasing? or what is your algorithm?

PaulS:
You assign a value to PressStatus, in loop(). You check that value in the interrupt service routine, but you have not declared that PressStatus is volatile. So, the compiler is likely optimizing code out of existence.

I'll admit that I don't understand all that stuff in startPlayback(), but I suspect that you ISR is not doing what you think it does (because PressStatus is not volatile).

Hi Pauls,
I have change my code, changed the PressStatus as volatile. do you think the code is OK?

#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 8000/2 //control the frequency of  the output signal =16M/SAMPLE_RATE/256

int outputPin = 6; // (PCINT22/OC0A/AIN0)PD6, Arduino Digital Pin 6
volatile uint16_t sample;
const int sinewave_length=256;


int led =13;
float voltageValue[10];
float voltage[10];
volatile int PressStatus;//Pressing flag;

const unsigned char sinewave_data[] PROGMEM = {
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};



void startPlayback()
{
  pinMode(outputPin, OUTPUT);
 
 
  // Set Timer 0 Fast PWM Mode 
  // WGM = 0b011 = 3 (Table 14-8)
  // TOP = 0xFF, update OCR0A register at BOTTOM
  TCCR0A |= _BV(WGM01) | _BV(WGM00);
  TCCR0B &= ~_BV(WGM02);
  // Do non-inverting PWM on pin OC0A, arduino digital pin 6
  // COM0A = 0b10, clear OC0A pin on compare match,
  // set 0C0A pin at BOTTOM (Table 14-3)
  TCCR0A = (TCCR0A | _BV(COM0A1)) & ~_BV(COM0A0);
  // COM0B = 0b00, OC0B disconnected (Table 14-6)
  TCCR0A &= ~(_BV(COM0B1) | _BV(COM0B0));
  // No prescaler, CS = 0b001 (Table 14-9)
  TCCR0B = (TCCR0B & ~(_BV(CS02) | _BV(CS01))) | _BV(CS00);
  // Set initial pulse width to the first sample.
  OCR0A = pgm_read_byte(&sinewave_data[0]);
  // Set up Timer 1 to send a sample every interrupt.
  cli(); // disable interrupts
  // Set CTC mode (Section 15.9.2 Clear Timer on Compare Match)
  // WGM = 0b0100, TOP = OCR1A, Update 0CR1A Immediate (Table 15-4)
  // Have to set OCR1A *after*, otherwise it gets reset to 0!
  TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
  TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
  // No prescaler, CS = 0b001 (Table 15-5)
  TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  // Set the compare register (OCR1A).
  // OCR1A is a 16-bit register, so we have to do this with
  // interrupts disabled to be safe.
  OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
  // Enable interrupt when TCNT1 == OCR1A (p.136)
  TIMSK1 |= _BV(OCIE1A);
  sample = 0;
  sei(); // enable interrupts
}
void setup()
{
  startPlayback();
  //initialize serial communication at 4800bit per second;
  Serial.begin(4800);
  pinMode (led,OUTPUT);


}

void loop()
{
  int i;
  for(i=0;i<10;i++){

    voltageValue[i] = analogRead(A0);
    voltage[i] = voltageValue[i] * (5.0 / 1023.0);
    if (i>0&&voltage[i]-voltage[i-1]>=0.2){
      PressStatus=1;
      digitalWrite(led,HIGH);
    }
    
    else {
      PressStatus=0;
      digitalWrite(led,LOW);
    }
  }

}

// This is called at SAMPLE_RATE kHz to load the next sample.
ISR(TIMER1_COMPA_vect) {
  if ((sample < sinewave_length)&&(PressStatus==1)) {
    OCR0A = pgm_read_byte(&sinewave_data[sample]);
  }
  else {
    sample = -1;
  }
  ++sample;
}

Hi,
I have posted my questions for several times. Until now my question doesn't solve:
I am working on a peizo sensor project. for a Peizo sensor, it will generate a voltage when a force is applied on its surface.
The arduino Pin A0 samples the voltage across the sensor. I hope the arduino Pin 6 will generate a sinewave to drive the sensor to vibrate when I press the sensor. I use a relay to control the circuit.
Now the question is :
1.when I make my code generate sinewave, it can drive the sensor to vibration.
2.When I make my code only judge the press, it seems to work (the flag "PressStatus" can set high when I press the sensor).
3.when I set a threshold: I wanna call the sinewave generation function (ISR) when I press the sensor. But the code cannot trigger the threshold and the sinewave doesn't drive the sensor.

The question have annoyed my for a long time. Pls guys help me out. Thank you so much. My code has something wrong?
my code is:

#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 8000/0.64 //control the frequency of  the output signal =16M/SAMPLE_RATE/256

int outputPin = 6; // (PCINT22/OC0A/AIN0)PD6, Arduino Digital Pin 6
volatile uint16_t sample;
const int sinewave_length=256;


int led =13;
const int N=5;
float voltageValue[N];
float voltage[N];
volatile int PressStatus;//Pressing flag;

const unsigned char sinewave_data[] PROGMEM = {
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};



void startPlayback()
{
  pinMode(outputPin, OUTPUT);


  // Set Timer 0 Fast PWM Mode 
  // WGM = 0b011 = 3 (Table 14-8)
  // TOP = 0xFF, update OCR0A register at BOTTOM
  TCCR0A |= _BV(WGM01) | _BV(WGM00);
  TCCR0B &= ~_BV(WGM02);
  // Do non-inverting PWM on pin OC0A, arduino digital pin 6
  // COM0A = 0b10, clear OC0A pin on compare match,
  // set 0C0A pin at BOTTOM (Table 14-3)
  TCCR0A = (TCCR0A | _BV(COM0A1)) & ~_BV(COM0A0);
  // COM0B = 0b00, OC0B disconnected (Table 14-6)
  TCCR0A &= ~(_BV(COM0B1) | _BV(COM0B0));
  // No prescaler, CS = 0b001 (Table 14-9)
  TCCR0B = (TCCR0B & ~(_BV(CS02) | _BV(CS01))) | _BV(CS00);
  // Set initial pulse width to the first sample.
  OCR0A = pgm_read_byte(&sinewave_data[0]);
  // Set up Timer 1 to send a sample every interrupt.
  cli(); // disable interrupts
  // Set CTC mode (Section 15.9.2 Clear Timer on Compare Match)
  // WGM = 0b0100, TOP = OCR1A, Update 0CR1A Immediate (Table 15-4)
  // Have to set OCR1A *after*, otherwise it gets reset to 0!
  TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
  TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
  // No prescaler, CS = 0b001 (Table 15-5)
  TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  // Set the compare register (OCR1A).
  // OCR1A is a 16-bit register, so we have to do this with
  // interrupts disabled to be safe.
  OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
  // Enable interrupt when TCNT1 == OCR1A (p.136)
  TIMSK1 |= _BV(OCIE1A);
  sample = 0;
  sei(); // enable interrupts
}
void setup()
{
  startPlayback();
  //initialize serial communication at 4800bit per second;
  Serial.begin(4800);
  pinMode (led,OUTPUT);


}


void loop()
{
  int i;
for (i=0;i<N;i++) {
    voltageValue[i] = analogRead(A0);
    voltage[i] = voltageValue[i] * (5.0 / 1023.0);
    if (i>0&&voltage[i]-voltage[i-1]>=0.05){
      PressStatus=1;
      digitalWrite(led,HIGH);
    Serial.println(voltage[i]);   
    }

    else {
      PressStatus=0;
      digitalWrite(led,LOW);
       Serial.println(voltage[i]);
    }
   
  

}
}

// This is called at SAMPLE_RATE kHz to load the next sample.
ISR(TIMER1_COMPA_vect) {
if (PressStatus==1){
    if (sample >= sinewave_length) {
      sample = -1;
    }
    else 
    {
      OCR0A = pgm_read_byte(&sinewave_data[sample]);
    }
    ++sample;
  }

}