I have a grove ultrasonic sensor with which pulse and echo share the same pin. In doc, it seems pulse and echo can’t share the same pin.
What can be my options ?
Those are rare and so we do not plan to support for now but we should look into it in the future. Try in managed it might work.
I try this, but no way :
using System;
using System.Diagnostics;
using System.Threading;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.Signals;
using GHIElectronics.TinyCLR.Pins;
namespace testPulseFeedbackSamePin
{
static class Program
{
private static PulseFeedback _pf;
static void Main()
{
Setup();
while (true)
{
Loop();
Thread.Sleep(20);
}
// ReSharper disable once FunctionNeverReturns
}
private static void Loop()
{
var time = _pf.Trigger();
var distance = time.TotalMilliseconds * 1000.0 * 0.018;
Debug.WriteLine(distance.ToString());
Thread.Sleep(500);
}
private static void Setup()
{
var ctl = GpioController.GetDefault();
var _pulse = ctl.OpenPin(SC20100.GpioPin.PA2);
_pf = new PulseFeedback(_pulse,_pulse, PulseFeedbackMode.DurationUntilEcho)
{
DisableInterrupts = false,
EchoValue = GpioPinValue.High,
PulseValue = GpioPinValue.High,
Timeout = TimeSpan.FromSeconds(1),
PulseLength = TimeSpan.FromTicks(100)
};
}
}
}
I mean try without pulse feedback. How does the sensor work?
It’s a grove Ultrasonic ranger module. It’s like an hc-sr04 but echo and pulse are on same pin (SIG).
I need to send a high level on SIG. Change Output in Input and just after wait for a raising edge on SIG.
But time is important, I don’t think managed level can keep it accurate.
Wait for rising or falling edge? If falling then you can treat it like capacitive sensing.
I do have the one that use only one pin in c#. We tested on TinyCLR SC13xxx. Hopefully that help.
public class Ultrasonic
{
GpioPin pulsePin;
const int timeout = 1 * 1000 * 1000;
public Ultrasonic(GpioPin pulsePin)
{
this.pulsePin = pulsePin;
}
long PulseLength()
{
var begin = Micro();
// wait for any previous pulse to end
while (this.pulsePin.Read() == GpioPinValue.High)
{
if (MicrosDiff(begin, Micro()) >= timeout)
{
return 0;
}
}
// wait for the pulse to start
while (!(this.pulsePin.Read() == GpioPinValue.High))
{
if (MicrosDiff(begin, Micro()) >= timeout)
{
return 0;
}
}
var pulseBegin = Micro();
// wait for the pulse to stop
while (this.pulsePin.Read() == GpioPinValue.High)
{
if (MicrosDiff(begin, Micro()) >= timeout)
{
return 0;
}
}
var pulseEnd = Micro();
return MicrosDiff(pulseBegin, pulseEnd); ;
}
long Duration()
{
this.pulsePin.SetDriveMode(GpioPinDriveMode.Output);
this.pulsePin.Write(GpioPinValue.Low);
DelayMicroSecond(2);
this.pulsePin.Write(GpioPinValue.High);
DelayMicroSecond(5);
this.pulsePin.Write(GpioPinValue.Low);
this.pulsePin.SetDriveMode(GpioPinDriveMode.Input);
long duration;
duration = PulseLength();
return duration;
}
public long MeasureInCentimeters()
{
long RangeInCentimeters;
RangeInCentimeters = Duration() / 29 / 2;
return RangeInCentimeters;
}
/*The measured distance from the range 0 to 4000 Millimeters*/
public long MeasureInMillimeters()
{
long RangeInMillimeters;
RangeInMillimeters = Duration() * (10 / 2) / 29;
return RangeInMillimeters;
}
/*The measured distance from the range 0 to 157 Inches*/
public long MeasureInInches()
{
long RangeInInches;
RangeInInches = Duration() / 74 / 2;
return RangeInInches;
}
static long MicrosDiff(long begin, long end)
{
return end - begin;
}
static long Micro()
{
return DateTime.Now.Ticks / 10;
}
static void DelayMicroSecond(int microsecond)
{
var begin = Micro();
while (Micro() - begin < microsecond) ;
}
}
I’ll give it a try, as soon as I finish my clock project !
Thanks for this code.
It’s working very well !!!
Thanks again.