 # Trying to find multiple Max values of a single sine wave

Good Day .

I am fairly new to programming and have a lot learn. i am here for guidance.

i have a pressure sensor and it generates a pulse between .5 to 4.5 volts . The aptitude and the frequencies may vary. my aim is to get the max value of each crest for 5 successive crests and the values then repeat the process again an rewrite the last four values with the new ones.below is an attachment of the idea to detect the new crest i am just not sure if i am doing this right .

i have tried to use a threshold value and micros to track the crossings but i am having some trouble could any one guide in the right direction.?

this is you code thus far

``````const int analogInPin = A0;// Analog input pin

int sensorValue = 0;// value read from the pot
int Max=0;//general max value of current crest
int tH=50;//threshold value to be used for zero crossing
int T0=0;//zero crossing 1
int T1=0;//zero crossing 2
int T2=0;//zero crossing 3
int T3=0;//zero crossing 4
int T4=0;
int T5=0;
int T6=0;
int T7=0;
int MX1=0;
void setup()
{
Serial.begin(9600);// initialize serial communications at 9600 bps:
}

void loop()
{

if(sensorValue==tH)
{
T0=micros();// time of first zero crossing
Serial.print("T0=");
Serial.println(T0);
}

if ((sensorValue==tH)&&(T1<=micros()))
{
T1=micros();// time of second zero crossing
Serial.print("T1=");
Serial.println(T1);
}

if((sensorValue==tH)&&(T2<=micros()))
{
T2=micros();
Serial.print("T2=");
Serial.println(T2);
}

if((sensorValue==tH)&&(T3<=micros()))
{
T3= micros();
Serial.print("T3=");
Serial.println(T3);
}

if((sensorValue==tH)&&(T4<=micros()))
{
T4=micros();
Serial.print("T4=");
Serial.println(T4);
}

if((sensorValue==tH)&&(T5<=micros()))
{
T5=micros();
Serial.print("T5=");
Serial.println(T5);
}

if((sensorValue==tH)&&(T6<=micros()))
{
T6= micros();
Serial.print("T6=");
Serial.println(T6);
}

if((sensorValue==tH)&&(T7<=micros()))
{
T7=micros();
Serial.print("T7=");
Serial.println(T6);
}

if ((T2 < micros())&&(T3>micros()))
{
sensorValue=Max;
if(sensorValue>Max)
{
Max=sensorValue;
MX1=micros();
Serial.print("MX1=");
Serial.println(MX1);
Serial.print("Max=");
Serial.println(Max);
}
}

}
``````

Not a good coder, so don't take my word for it.

I think all the "times" need to be declared as "unsigned long" for micros().

if(sensorValue==tH)...

Are you sure the sinewave changes slow enough to catch this. Leo..

Your algorithm is not going to find the low threshold crossing points.

The value returned by micros() is continually increasing. At all times Tn will be less than micros() and the compound conditional statements are true in all cases.

This section of code for finding the max is also flawed by the fact that micros() is advancing. Furthermore, you set sensorValue=Max and then test it for being greater than Max.

`````` if ((T2 < micros())&&(T3>micros()))
{
sensorValue=Max;
if(sensorValue>Max)
{
Max=sensorValue;
MX1=micros();
Serial.print("MX1=");
Serial.println(MX1);
Serial.print("Max=");
Serial.println(Max);
}
}
``````

If you could find the thresholds, I think that max would be a time halfway in between for a sine wave.

cattledog:
Your algorithm is not going to find the low threshold crossing points.

The value returned by micros() is continually increasing. At all times Tn will be less than micros() and the compound conditional statements are true in all cases.

This section of code for finding the max is also flawed by the fact that micros() is advancing. Furthermore, you set sensorValue=Max and then test it for being greater than Max.

`````` if ((T2 < micros())&&(T3>micros()))
``````

{

if(sensorValue>Max)
{
Max=sensorValue;
MX1=micros();
Serial.print(“MX1=”);
Serial.println(MX1);
Serial.print(“Max=”);
Serial.println(Max);
}
}

``````

If you could find the thresholds, I think that max would be a time halfway in between for a sine wave.
``````

thank you for pointing pointing out that mistake

Wawa: Not a good coder, so don't take my word for it.

I think all the "times" need to be declared as "unsigned long" for micros().

if(sensorValue==tH)...

Are you sure the sinewave changes slow enough to catch this. Leo..

no i am not sure if this will work in my case the pulses may be of different sizes and magnitudes so i am unsure thats why i was trying to catch the start and end of the pulse using the threshold values i will do some research and try to find another way to do this . thank you for you input

So i have a diffrent approach to finding the max values in the pluses please let me know what you all think

``````const int analogInPin = A0;// Analog input pin

int sensorValue = 0;// value read from the pot
int Max=0;//general max value of current crest
int tH=50;//threshold value to be used for zero crossing

int i=0;

int MX0[i]=0;// max array

int MX1=0;// store max array values these variables
int MX2=0;
int MX3=0;

float T0[i]=0;// max time array

float T1=0; // store max time in these variables
float T2=0;
float T3=0;

void setup()
{
Serial.begin(9600);// initialize serial communications at 9600 bps:
}

void loop()
{

{
if(sensorValue>tH)// for values grater than threshold th=50
{
if(sensorValue>Max)
{
Max=sensorValue;// find max value
}
MX0[i]=Max;// store four concetive max values in array
T0[i]= millis();store time when max occures in array
}
}

MX1=MX0;
T1=T0;

MX2=MX0;
T2=T0;

MX3=MX0;
T3=T0;

{
``````

I think you are headed in the right direction, looking for the maximum value in a series of readings.

You can also do a google search on "Arduino find maximum value " for some ideas.

Here's a good tutorial on analogRead() which explains how to make it faster if needed. https://www.gammon.com.au/adc

cattledog: I think you are headed in the right direction, looking for the maximum value in a series of readings.

You can also do a google search on "Arduino find maximum value " for some ideas.

Here's a good tutorial on analogRead() which explains how to make it faster if needed. https://www.gammon.com.au/adc

thank you for the link i will look in to increasing the sample rate

i have a pressure sensor and it generates a pulse between .5 to 4.5 volts . The aptitude and the frequencies may vary.

Note that at any given peak (90°), the rate of change of voltage is very low, which allows more time for a sample to occur, so increasing the sampling frequency may not yield noticeable benefits.

Do you know the minimum and maximum frequency? If so, you could record your samples within this timing range (1/4 period) after the rising zero cross.

For example, if the frequency varies from 50Hz min to 60Hz max, then you could start taking readings at 4167µs after the zero cross and stop taking readings at 5000µs after the zero cross. The default analogRead speed is about 100µs, so you should get about 8 readings, of which you could easily determine the highest value. Note that you would need to correct for the timing error of the zero cross signal.

EDIT:

For 50Hz sine, how much error is there for being out by ±1 reading (±100µs)? The period is 20000µs, so we can take 200 x 100µs samples, which is 1.8 degrees per sample. For a 1V peak at 90 degrees, sine 91.8 = 0.9995, so there would be ±0.5mV error for readings from 88.2 to 91.8 degrees.

hi so i have made some progress with my code but its not exactly doing what i want it to do

what i am trying to achieve is read a analog input that is a sine wave and record the max value of the first 4 pulses ,i will ignore the max value for the first pulse and display the max value of 3 successive pulses. the start of each pulse is distinguish by a low threshold value i have set.

i do not want time to be a factor i just want to read the first pulse and select the max value when the signal goes below my threshold value i store in to an array as max and then start to read the second pulse for max value then when the second pulse goes below the threshold value i save the max and store it to the second element in the array and so on the for the other two pulses . after the four pulses i want to repeat the process.

here is the code i have so far the problem that i am having is that the code runs continuously i need it to read for max value until the lower threshold is reached . this way i can know a new pulse has started .

``````const int analogInPin = A0;// Analog input pin

int sensorValue = 0;// value read from the pot
int Max=0;//general max value of current crest
int tH=25;//threshold value to be used for zero crossingint
int tH2=100;
int i=0;
int MX0;// max array

int MX1=0;// store max array values these variables
int MX2=0;
int MX3=0;

int T0;// max time array

int T1=0; // store max time in these variables
int T2=0;
int T3=0;

void setup()
{
Serial.begin(9600);// initialize serial communications at 9600 bps:
}

void loop()
{
for(int i=0;i<4;i++)
{
Max=0;
A:
while(sensorValue<tH)
{
goto A;
}
while(sensorValue>tH)// for values grater than threshold th=50
{
if(sensorValue>Max)
{
Max=sensorValue;// find max value
goto A;
}
}

MX0[i]=Max;// store  values in array
T0[i]= millis();//store time when max occures in array
}

MX1=MX0;
T1=T0;

MX2=MX0;
T2=T0;

MX3=MX0;
T3=T0;
Serial.print("MX1=");
Serial.println(MX1);
Serial.print("T1=");
Serial.println(T1);
Serial.print("MX2=");
Serial.println(MX2);
Serial.print("T2=");
Serial.println(T2);
Serial.print("MX3=");
Serial.println(MX3);
Serial.print("T3=");
Serial.println(T3);
delay(5000);

i=0;
int MX0={0,0,0};//set max array to zero
MX1=0;//set max array values these variables
MX2=0;
MX3=0;

int T0={0,0,0,0};//set max time array to zero

T1=0; // set max time to zero
T2=0;
T3=0;

}
``````