Seeed Grove - Ultrasonic Ranger with TinyCLR

I have ultrasonic ranger sensor from Seeed (Grove - Ultrasonic Ranger - Seeed Wiki) and I have ported it’s driver to C# (TinyCLR). Here is my code:

 public class DistanceSensor
    {
        public GpioPin _pin { get; set; }
        static long MicrosDiff(long begin, long end)
        {
            return end - begin;
        }
        static long micros()
        {
            var ticks = DateTime.Now.Ticks;
            long microseconds = ticks / (TimeSpan.TicksPerMillisecond / 1000);
            return microseconds;
        }
        long pulseIn(bool state, long timeout = 1000000)
        {
            var begin = micros();

            // wait for any previous pulse to end
            while (_pin.Read() == GpioPinValue.High) if (MicrosDiff(begin, micros()) >= timeout) return 0;

            // wait for the pulse to start
            while (!(_pin.Read() == GpioPinValue.High)) if (MicrosDiff(begin, micros()) >= timeout) return 0;
            var pulseBegin = micros();

            // wait for the pulse to stop
            while (_pin.Read() == GpioPinValue.High) if (MicrosDiff(begin, micros()) >= timeout) return 0;
            var pulseEnd = micros();

            return MicrosDiff(pulseBegin, pulseEnd);
        }

        public DistanceSensor(int SignalPin)
        {
            _pin = GpioController.GetDefault().OpenPin(SignalPin);

        }


        /*The measured distance from the range 0 to 400 Centimeters*/
        public long MeasureInCentimeters()
        {
            //pinMode(_pin, OUTPUT);
            _pin.SetDriveMode(GpioPinDriveMode.Output);
            _pin.Write(GpioPinValue.Low);
            Thread.Sleep(2);
            _pin.Write(GpioPinValue.High);
            //digitalWrite(_pin, HIGH);
            Thread.Sleep(5);
            _pin.Write(GpioPinValue.Low);

            //digitalWrite(_pin, LOW);
            _pin.SetDriveMode(GpioPinDriveMode.Input);
            //pinMode(_pin, INPUT);
            long duration;
            duration = pulseIn(true);
            long RangeInCentimeters;
            RangeInCentimeters = duration / 29 / 2;
            return RangeInCentimeters;
        }
        /*The measured distance from the range 0 to 157 Inches*/
        public long MeasureInInches()
        {
            _pin.SetDriveMode(GpioPinDriveMode.Output);
            //pinMode(_pin, OUTPUT);
            _pin.Write(GpioPinValue.Low);
            //digitalWrite(_pin, LOW);
            Thread.Sleep(2);

            //delayMicroseconds(2);
            _pin.Write(GpioPinValue.High);
            //digitalWrite(_pin, HIGH);
            Thread.Sleep(5);
            //delayMicroseconds(5);
            _pin.Write(GpioPinValue.Low);
            //digitalWrite(_pin, LOW);
            _pin.SetDriveMode(GpioPinDriveMode.Input);
            //pinMode(_pin, INPUT);
            long duration;
            duration = pulseIn(true);
            long RangeInInches;
            RangeInInches = duration / 74 / 2;
            return RangeInInches;
        }
    }

it’s working, but I think I need to adjust my code to get more accurate reading. suggestion ?

Is enought just centimetres or inch to return
And with formula you can get another ones

Return to cm and inch=(cm/2.54) or
Return to inch and cm=(inch*2.54)

2 Likes

Perhaps you can be more accurate with Gpio Pulse Reader Writer instead of PulseIn.

Here is my code.

4 Likes

Thanks, but I think I got a new problem… it should be under 2 cm

Long is basicly Int64, but in your calculation you use floating point divisions. You lose a lot of precision by successive integer rounding for each division.

1 Like

Sensor seems to be for distance more than 2cm

1 Like

You won’t get down to 2cm with those sensors. The transmitter ping rings and is too long so you need to blank this period and then start listening for the reply. Most of these sensors are rate from 2cm.

1 Like