Analog sync detection Project

Hi all,
1st time here and kind of newbe with Arduino... however I want to realise this project; here are my needs:
I want to be able to detect/calculate the time between 2 analog inputs that reach a trigger level.
In other words, I have 2 analog signals 0 - 5V. Both should reacts the same way stable at about 1V then spike up to 4V and stable at 3V. The problem is if there are not perfectly synchronised (spike on both with less than 1s gap) then it can leads to big problems. So I want to use the arduino to monitor these 2 analog signals and reacts when the time between the 2 spikes is too long.
Can anybody help me with the code please?
That would be very appreciated!

(deleted)

Would a [u]differential amplifier[/u] help? It's an analog circuit and you'll only get an output when there's a difference between the two signals.

You can apply the signals directly to digital input pins. Then measure the time of the first pin going HIGH, then the second pin, and get the difference.

@Spycatcher: I haven't write anything so far... I was hopping to get some help with the entire code :slight_smile:
@ DVDdoug: I rather prefer to use the arduino than pure electronics because I want to be able to upgrade my project (e.g. display the time between the 2 spikes, communication with the equipment that is behind, stop the process...). Ok maybe I should give more details about that: So at work we have production equipment with several devices for process. One of these devices is a gas flow controller and I found out few weeks ago that it was not working well. The equipment did not catch this failure. That's the reason why I want to develop this analog sync detection device. What we expect from this equipment is when its open the gases, we should have these 2 spikes (gas flow signals) then stable at about 3V. When the process is finished, the equipment stops the gases flow and both signals drop to about 1V.

My thought was indeed to use 2 analog inputs with 2 variables for the trigger values (that way I can separate the 2 signals) and start to count from when 1 of the 2 analog input goes over the trigger.

My thought was indeed to use 2 analog inputs with 2 variables for the trigger values (that way I can separate the 2 signals) and start to count from when 1 of the 2 analog input goes over the trigger.

OK start coding that idea. Then post what you have.
This is a help forum, it is not a code writing forum. If you want to pay some one to write it for you then post in the Gigs & Collaboration section of the forum.

Yeah I understand and you're right!
I will start something then I'll come back when I'm ready.
Thanks

This sounds like a job that would be best done with the AnalogComparator in the Atmega chip. It can trigger an interrupt when the difference between two pins reaches a certain level.

Unfortunately there are no "Arduino" functions to make its use easy - perhaps because there are lots of detail differences between the Atmel devices.

If you read the relevant Atmel datasheet it should be straightforward.

...R

Ok here I am again :slight_smile:
I wrote a code (with some help from google :slight_smile: ) but it seems not doing the job and I don't understand why.
I have connected 2 pots to simulate my analog signals on A0 and A1
Here is my code:

const byte HeInValue = A0;
const int InnerThreshold = 818; // 4V Trigger

const byte HeOutValue = A1;
const int OuterThreshold = 818; // 4V Trigger

void setup()
{
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}

void loop()
{
boolean HeInTrigger;
boolean HeOutTrigger;
unsigned long Delta;
unsigned long Start;

//
// Wait for one of the two events to occur.
//

do
{
analogRead( HeInValue );
HeInTrigger = (analogRead( HeInValue ) >= InnerThreshold);
analogRead( HeOutValue );
HeOutTrigger = (analogRead( HeOutValue ) >= OuterThreshold);
}
while ( HeInTrigger || HeOutTrigger );

//
// One or both of the events occurred.
//

if (HeInTrigger && HeOutTrigger)
{
Delta = 0;
}
else

//
// One fired. Wait for the other
//

{
Start = micros(); // Start counter

if (HeInTrigger)
{
analogRead(HeOutValue);
do
{
HeOutTrigger = (analogRead( HeOutValue ) >= OuterThreshold);
}
while (HeOutTrigger == 0);
}
else
{
analogRead(HeInValue);
do
{
HeInTrigger = (analogRead( HeInValue ) >= InnerThreshold);
}
while ( HeInTrigger == 0);
}

Delta = micros() - Start;
}

Serial.println(Delta);

}

The problem is:

  • A0 low (below trigger value), if A1 goes above trigger I got the delta time
  • A0 high (above trigger value), I never get the delta time

@ Robin2: Thanks for the advice but I already started with the arduino so I would like to use it anyway.

Please read this:-
How to use this forum
Because your post is breaking the rules about posting code. ( use the </> icon )

What is this?:

 while (HeOutTrigger == 0);

Do not put a semicolon at the end here because the program just sweeps past the statement or it gets stuck forever here.

analogRead( HeInValue );

This does nothing, it returns a value which you then ignore.

Every time round the loop then these variables get created again and do not retain their value from the previous loop.

void loop()
{
  boolean HeInTrigger;
  boolean HeOutTrigger;
  unsigned long Delta;
  unsigned long Start;
analogRead( HeInValue );
HeInTrigger = (analogRead( HeInValue ) >= InnerThreshold);
analogRead( HeOutValue );
HeOutTrigger = (analogRead( HeOutValue ) >= OuterThreshold);

I think this code reads (for example) the value of the HeinValue pin twice and discards the first reading and I believe that is what is recommended when you need to change channels. It is just a different way of doing it.

HOWEVER - I wonder if the compiler would discard the first line of code thinking that it is not doing anything useful

Personally I would write it as

adcVal = analogRead( HeInValue );
    adcVal = analogRead( HeInValue );
    HeInTrigger = adcVal >= InnerThreshold);
    adc2Val = analogRead( HeOutValue );
    adc2Val = analogRead( HeOutValue );
    HeOutTrigger = adc2Val >= OuterThreshold);

as that would allow to include, for example, Serial.println(adcVal); if I need that for debugging.

...R

RafVerzet:
@ Robin2: Thanks for the advice but I already started with the arduino so I would like to use it anyway.

I was not suggesting that you use anything other than an Arduino. You can use the analog comparator perfectly well with an Arduino.

...R

I believe that is what is recommended when you need to change channels.

It is only recommended when the input impedance of the analogue signal is significantly higher that 10K, which I don't think is the case here.

Thank you for all you inputs and sorry that I did not follow the rules about posting codes.
I took into account you remarks and also found errors in my code. So I've done some modifications and I think it is more simple now. The only thing is I cannot test it right now. It will be for tomorrow...
Please guys tell me what you think about it.

const byte HeInValue = A0;
const int InnerThreshold = 818; // 4V Trigger

const byte HeOutValue = A1;
const int OuterThreshold = 818; // 4V Trigger


void setup() 
{
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}



void loop() 
{ 
  boolean HeInTrigger;
  boolean HeOutTrigger;
  unsigned long Delta;
  unsigned long Start;
 
  //
  // Wait for one of the two events to occur. 
  //
  
  do
  {
    HeInTrigger = (analogRead( HeInValue ) >= InnerThreshold);
    HeOutTrigger = (analogRead( HeOutValue ) >= OuterThreshold);
  }  
  while ( ! HeInTrigger && ! HeOutTrigger ); // HeInTrigger AND HeOutTrigger = 0
  
  //
  // One or both of the events occurred.
  //
  
  {
      if (HeInTrigger)
      {
       do
       {
         Start = micros();
         HeOutTrigger = (analogRead( HeOutValue ) >= OuterThreshold);
       }
       while ( HeOutTrigger == 0);
      }
      else
      {
       do
        {
          Start = micros();
          HeInTrigger = (analogRead( HeInValue ) >= InnerThreshold);
        }
       while ( HeInTrigger == 0);
      }

  Delta = micros() - Start;
  }

Serial.println(Delta);

}

@Grumpy; every loop should give a new delta value right? So in that case I believe it is good to have these variables get kind of reseted.
The inputs are indeed low impedance. I have remove the unnecessary analogRead.
If I remove the semicolon fron while (HeOutTrigger == 0); then I get an error

You get an error when you remove the semicolon because something else is wrong. Probbly unmatched braces.

When using a while loop there must be something in the loop that changes the condition you are testing otherwise you can get stuck in the loop. If you don't get stuck then the statement is not doing what you think.

Ok so I could test my code again but I still have some issues: 1 I figured out that the

Start.micros();

wasn't at the right place because I got all the time 112us so I changed its position and it seems better now.
Here is my code:

const byte HeInValue = A0;
const int InnerThreshold = 818; // 4V Trigger

const byte HeOutValue = A1;
const int OuterThreshold = 818; // 4V Trigger

void setup() 
{
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

void loop() 
{ 
  boolean HeInTrigger;
  boolean HeOutTrigger;
  unsigned long Delta;
  unsigned long Start;
 
  // Wait for one of the two events to occur.  
  do
  {
    HeInTrigger = (analogRead( HeInValue ) >= InnerThreshold);
    HeOutTrigger = (analogRead( HeOutValue ) >= OuterThreshold);
  }  
  while ( ! HeInTrigger && ! HeOutTrigger ); // HeInTrigger AND HeOutTrigger = 0
  
  // One or both of the events occurred.
  Start = micros();
  {
      if (HeInTrigger)
      {
       do
       {
         HeOutTrigger = (analogRead( HeOutValue ) >= OuterThreshold);
       }
       while ( HeOutTrigger == 0);
      }
      else
      {
       do
        {
          HeInTrigger = (analogRead( HeInValue ) >= InnerThreshold);
        }
       while ( HeInTrigger == 0);
      }

  Delta = micros() - Start;
  }

Serial.println(Delta);

}

The problem I have now is that the delta time seems to be not correct (too long). So I believe there are still some errors in my code... Any help would be very appreciated.
Thanks guys

Every analog read call takes about 100uS does that explain why it is too long?

Grumpy_Mike:
It is only recommended when the input impedance of the analogue signal is significantly higher that 10K, which I don't think is the case here.

Do you have a reference to that advice ? I can't find where I read about it and I can't see anything about it in the Datasheet (but I may have missed it).

...R

Do you have a reference to that advice ?

Section 23.6.1 of the ATmega328 data sheet:-

The ADC is optimized for analog signals with an output impedance of approximately 10 kΩ or less.
If such a source is used, the sampling time will be negligible. If a source with higher impedance is used, the sampling time will depend on how long time the source needs to charge the S/H capacitor, with can vary widely. The user is recommended to only use low impedance sources with slowly varying signals, since this minimizes the required charge transfer to the S/H capacitor.

Only 100us delay would be great. No here I'm talking about a few seconds. I really don't get it...