Alternative of pulseIn() function

Hello!

I have some troubles to determinate pulse length from a signal.
I have made several attempts to resolve pulse length but length was incorrect (simply calculation time between two low pulses).
For now i have best result with pulseIn() method but kills main loop() after first trigger.
The main problem is hardware that already exist and cannot change pin (Current version is using Serial2).
Is there some other way to count delicately HIGH time?

Code:

void serialEvent2() {

    if (Serial2.available()) {
        uint16_t width = pulseIn(LPG_INPUT, HIGH, LPG_TIMEOUT);

#ifdef LPG_TIME_SENS
        Serial.println(width);
        return;
#endif
        if (width == 0) {
            if (lpg_dataBuffer) {
                lpg_dataOffset = 0;
                lpg_recData = lpg_dataBuffer;
                lpg_dataBuffer = '\0';
                lpg_isReceive = true;
            } else {
                lpg_isReceive = false;
            }
            return;
        }

        if (width > LPG_BYTE_HIGH_MIN && width < LPG_BYTE_HIGH_MAX) {
            lpg_dataBuffer |= 1 << lpg_dataOffset;
            lpg_dataOffset++;
        } else {
            lpg_dataBuffer |= 0 << lpg_dataOffset;
            lpg_dataOffset++;
        }
    }
}

From: Original file

You need to post your complete program.

Also tell us what is producing the pulse that you want to measure. If you can post a link to the datasheet for the device that will be a great help.

You can detect pulses with an interrupt - see attachInterrupt() - Arduino Reference - but I am reluctant to go into more detail without knowing more about what needs to be done.

...R

Link was below the "code"

Original test program

Signal generator for program

Are you looking for a dedicated timing function or something that will run along with other tasks? Read reply #1. How short is the shortest pulse you expect to time? How long is the longest pulse you expect to time? At what frequency do you expect the pulses to arrive? Read reply #1. What resolution do you expect of the timing? How often do you want to time these pulses? Do you want to record them? Report them? Display them? Perform calculations on the results? And you might want to read reply #1.

There are many methods of timing signals, each with it's own benefits, but all with a cost. You need to prioritize you requirements. From one-shot timing measured in clock pulses to moving averages. As they say in auto repair - Good. Fast. Cheap. Pick two.

I think you can use a interrupt CHANGE connected to the PINOUT. In the ISR a flag goes up and millis go signed into a variable. In loop controll the flag, if it is on you pass the content of the exmillis variable into an other, calcolate the impulse duration and the flag goes down.
The i.d. is the difference between the twoo exmillis variable.

Can it be a solution?
Everyways I don't understand:
What is this for? If you generate a pulse witch Arduino you know the timing lf the pulse
How can it works? If a specific function, made specifically for this topic is not what you want how can a new solution works better?

fireAngel:
Link was below the "code"

Please explain what you are trying to do. What is an LpgSignal? For me "LPG" means Liquid Petroleum Gas.

You seem to have a pair of programs that you got from Github. I can see that one of them just creates test pulses for the other one. But I presume when the tests work you intend to use the code for some other purpose - what is that purpose?

...R

You can attach a change interrupt to any pin on the 328p, including Rx/Tx. For critical timing however, you can't use millis and/or micros.

DKWatson:
...Read reply #1...Read reply #1...read reply #1...

Karma++

DKWatson:
You can attach a change interrupt to any pin on the 328p, including Rx/Tx. For critical timing however, you can’t use millis and/or micros.

I try several types of this variant, but cannot find any to work over pin D17 on mega2560.

Robin2:
Please explain what you are trying to do. What is an LpgSignal? For me “LPG” means Liquid Petroleum Gas.

You seem to have a pair of programs that you got from Github. I can see that one of them just creates test pulses for the other one. But I presume when the tests work you intend to use the code for some other purpose - what is that purpose?

…R

I’m trying to capture signal between LPG ECU and Switch control unit. In current version I’m using pure Serial (Serial2) to read the signal (works fine), but its hard to setup (baud rate & etc) and half of data is missing.

In this GitHub repo
“LpgSignal” simulates exact signal from ECU to switch (dump from logic analyzers)
“LpgSerial” Needs to capture exact same signal over pin 17 (constant pin / hardware exist). Signal capturing needs to happens without disturbing loop() method.

The attempts i made to read it: “Change interrupt to any pin [over D17 don’t work]”, “Reading states High/Low [calc. time is unstable]”, “pulseIn() in serialEvent2() [pulseIn kills the loop after serialEvent2 is triggered ]”

fireAngel:
In this GitHub repo
"LpgSignal" simulates exact signal from ECU to switch (dump from logic analyzers)

The problem I have is that the GitHub link does not describe the signal it is emulating so I can't visualize it and therefore I can't start to envisage a solution.

Can't you post a link to the datasheet for the LPG ECU?

Or, at least, post a diagram of the pulses with timings marked on them? And also please identify what part of the signal you want to measure. For example is it between successive RISING edges?

...R

fireAngel:
I try several types of this variant, but cannot find any to work over pin D17 on mega2560.

I'm trying to capture signal between LPG ECU and Switch control unit. In current version I'm using pure Serial (Serial2) to read the signal (works fine), but its hard to setup (baud rate & etc) and half of data is missing.

In this GitHub repo
"LpgSignal" simulates exact signal from ECU to switch (dump from logic analyzers)
"LpgSerial" Needs to capture exact same signal over pin 17 (constant pin / hardware exist). Signal capturing needs to happens without disturbing loop() method.

The attempts i made to read it: "Change interrupt to any pin [over D17 don't work]", "Reading states High/Low [calc. time is unstable]", "pulseIn() in serialEvent2() [pulseIn kills the loop after serialEvent2 is triggered ]"

Sorry, should have realised that we were talking about mega2560. As you have found, not every pin on the mega2560 has an interrupt attached to it. There are only 19, D0, D10-15, D50-53 and A8-15. Some diagrams depict PCINT8 being attached to pin D6 as well as D0. There is no PCINT associated with pin15 aka PH3 aka D6 on the mega2560.

Robin2:
The problem I have is that the GitHub link does not describe the signal it is emulating so I can’t visualize it and therefore I can’t start to envisage a solution.

Can’t you post a link to the datasheet for the LPG ECU?

Or, at least, post a diagram of the pulses with timings marked on them? And also please identify what part of the signal you want to measure. For example is it between successive RISING edges?

…R

No datasheet or any other data … refused from manufacturer.

Attachments are screenshots of timing.
But keep in mind this timing needs to be variable (in order fit maximum number of LPG ECU types)
All digital switch units i check have almost same signals (different HIGH state time for 0/1 in 2/6ms range )

Images from Reply #11 so we don't have to download them. See this Simple Image Guide

...R

Based on those images (which are very hard to read) can you explain what you want to measure.

Also, what is the timescale for the images?

...R

Robin2:
Based on those images (which are very hard to read) can you explain what you want to measure.

Also, what is the timescale for the images?

...R

If you download attachment you will read the timing...

i want to capture all 4ms HIGH state as bit 1
and all 2ms HIGH state as bit 0
(it is not it obvious ??)

also this is example copy from Github file in microseconds range (using pulseIn())

        0
        0
        3982 // 1
        1993 // 0
        1993
        1993
        1994
        3978 // 1
        1993
        1993
        3978 // 1
        1994
        1993
        1995
        3979 // 1
        3978 // 1
        0
        0
        0

fireAngel:
If you download attachment you will read the timing...

I have been hoping that you would help me to help you by providing the information without me having to search for it.

i want to capture all 4ms HIGH state as bit 1
and all 2ms HIGH state as bit 0

Back in Reply #1 I suggested that you study the attachInterrupt() function. Have you done so?

As far as I can see all you need is a CHANGE interrupt and save the value of micros() when each interrupt occurs. Then by subtracting the previous value from the present one you can determine the duration.

...R

Reply #10

Interrupt supported pins
ATmega2560- 10 - 15, 18 - 21, A8 - A15, SS, SCK, MOSI, MISO

Missing pin 17 ... :confused:

GIVE UP!
Changing the pin …

What about the long pulses (about 15mS long) ?
Don’t you want to read these to determine the start of a series of what appears to be 14 bits?

In general i don't want those bigger pulses... they are something like buffering zone.
Basically long pulses are genning sorter when 14 bits stack have more "1" ( they are 1ms bigger )
LPG ECU Toggle one to "1" position other to "0" when something is changed