Calculating low pulse time from a digital sensor

I’m trying to calculate the low pulse time for a digital sensor that has an output like in the attached diagram. I’ve used a voltage divider to convert the 4v high into a 3.3v signal and that seems to be working fine. And I can read the low pulse duration with my arduino just fine using this: duration = pulseIn(pin, LOW);

The imp doesn’t seem to have something equivalent and I’m looking for some direction as I’m new to coding in Squirrel. I just need to know how long the low pulses are and be able to define a total sample time so I can calculate for what percent of the sample time the pulse was low.

Any help on how to do this in Squirrel on the imp would be appreciated!

for some reason the image isn’t attaching properly, but here’s the datasheet of the sensor I’m trying to read from: http://www.sca-shinyei.com/pdf/PPD42NS.pdf

The output from the sensor can be seen on page 3.

Refer to the following to understand how imp handles IO’s: http://electricimp.com/docs/api/hardware/pin/

Would need to configure your IO pin. http://electricimp.com/docs/api/hardware/pin/configure/

Choose appropriate digital input method as imp gives plenty options. Note if you plan to put imp asleep then limited on which IO pin can be used to wake it up.

Would need to read pin status… http://electricimp.com/docs/api/hardware/pin/read/

Have timer options…
http://electricimp.com/docs/api/hardware/micros/
http://electricimp.com/docs/api/hardware/millis/

Should now be able to calc duration of your pulse.

Have a look at the sampler. I use that for my weather station, where I calculate wind speed from the time between pulses.

Thanks for the ideas. I think I’ve got the pin configured and am reading it correctly, but I’m trying to calculate the ratio of low pulse time to high pulse time for a 10-second sample using the following code and it’s not working for me correctly. I’m new to Squirrel, so I’m not sure where I’m going wrong but any help is appreciated:

function buttonPress()
{

totaltime=0;

starttime = hardware.micros();

for (endtime = 0; endtime <= 10000000;)
{
while (button.read() == 0) {
count = hardware.micros();
}
while (button.read() == 1) {
duration=hardware.micros()-count;
}

totaltime = totaltime + duration;
endtime = hardware.micros() - starttime;
}

ratio = (totaltime/endtime)*100;

concentration = 1.1math.pow(ratio,3)-3.8math.pow(ratio,2)+520*ratio+0.62;

server.log("ratio: " + ratio);
server.log("endtime: " + endtime);
server.log("totaltime: "+ totaltime);
server.log("concentration: " + concentration);
server.log(“timer:” + hardware.micros());

}

How precise do you need the measurement to be? Squirrel is interpreted, so you can’t expect it to be within microsecond precision.

Is your button pressed only once?

Consider using pin.configure(DIGITAL_IN, function)

The function you pass it will be called every time the pin state changes. You can take a reading of hardware.micros() at that point.

For example:

`    button <- hardware.pin?
    totaltime <- 0
    count <- 0;
    starttime <- hardware.micros();

    button.configure(DIGITAL_IN_PULLUP,function(){
        local micros = hardware.micros()
        if (button.read()==1)    
            // button is released, calculate duration and add to total
            totaltime+= micros-count;
        else
            // button is pressed, hold onto time for later calculation
            count = micros;
    }

    // run test for 10 seconds
    imp.wakeup(10,function(){ 
        local endtime = hardware.micros()
        /* your final code goes here */ 
    });
`

NOTE: this code assumes that button is high when test starts.

Thanks for the idea, @coverdriven. My real problem is the timers, though, as I need to run this function continuously to collect 10 second samples rather than when the pin state changes. My code sees the pulses, but the way I have it configured with the 10-second for loop and then the low pulse timer within the loop aren’t working properly as I’m getting negative numbers sometimes when I look at the totaltime variable in my log. So something is wrong with my code rather than the pin configuration, I think.

also, the fact that the function is called buttonPress is really a misnomer. It’s just called that because I started with some sample code for looking at a buttonPress. It should be called something like lowpulsetimer since that’s what I’m trying to do.

You can use the sampler over a 10 second period, at (eg) 500Hz (so, 5,000 samples in total), then threshold the samples and count the number that are below a threshold.

This will give you the number of 2ms long periods that the output is low (datasheet says min period is 10ms, so this should be fairly accurate).

eg:

`tenseconds <- blob(105002);

function calculate(buffer, length) {
if (length) {
// Only do this when we get the buffer; we will have a zero
// buffer after we stop
hardware.sampler.stop();
local lows = 0, samples = length/2;
while(samples) {
if (buffer.readn(‘w’) < 32768) lows++;
samples–;
}
server.log(“Low percentage = “+(lows/(length/2.0))*100+”%”);
}
}

hardware.sampler.configure(hardware.pin1, 500, [tenseconds], calculate, 0);
hardware.sampler.start();
`