CHƯƠNG 4. THI CÔNG HỆ THỐNG
4.3. Lập trình hệ thống
4.3.2. Phần mềm lập trình visual studio 2017
Ngay sau khi cài đặt xong Windows 10 IoT lên Raspberry Pi 3, có ba cách điều khiển Raspberry Pi 3 với những hạn chế khác nhau:
Cách 1: Điều khiển trực tiếp: Dùng chuột, bàn phím gắn vào Raspberry Pi điều khiển trực tiếp. Trong một số trường hợp cách này có nhiều giới hạn và bất tiện do phải gắn màn hình, chuột, bàn phím vào RPI.
Cách 2: Điều khiển qua giao diện web: Ngay sau khi cài đặt xong, có thể truy cập vào Raspberry Pi 2 qua trình duyệt web theo dạng <Địa chỉ IP của RPI>:8080
VD: 192.168.1.5:8080
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 45
Màn hình sau xuất hiện yêu cầu User name và Password:
Hình 4.16. Giao diện đăng nhập Windows 10 IoT Core trên web
User name là Administrator, password mặc định của Administrator là p@ssw0rd (Lưu ý ký tự @ và số 0 - chứ không phải chữ o). Sau khi Ok sẽ vào màn hình sau:
Hình 4.17. Giao diện quản lí Windows 10 IoT Core trên web
Lưu ý: trong hình này Raspberry Pi 2 đã được đổi tên (Device name). Tên mặc định sau khi cài xong là minwinpc.
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 46
Với giao diện web này ta có thể thực hiện một số thao tác như cài đặt phần mềm vào Raspberry Pi 2. Tuy nhiên nhiều thao tác khác như cài đặt driver, quản lý người dùng,... không thực hiện được.
Cách 3: Điều khiển qua PowerShell:
Điều khiển Raspberry Pi 2 (Windows 10 IoT) qua PowerShell là phương pháp tốt nhất (nhưng hơi khó dùng do phải thuộc các câu lệnh).
Giả sử Raspberry Pi 2 có địa chỉ IP là 192.168.1.5. Chạy PowerShell với quyền administrator. Đánh các lệnh sau:
net start WinRM
Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.1.5
Màn hình có dạng như sau
Hình 4.18. Giao diện kết nối Win 10 IoT Core qua PowerShell
Nhấn phím Y để đồng ý.Tiếp tục chạy lệnh (giả sử máy tính bàn chạy windows 10 có địa chỉ IP là 192.168.1.2):
Enter-PSSession–ComputerName192.168.1.2-Credential 192.168.1.5\Administrator
Hộp thoại nhắc nhập password sẽ xuất hiện:
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 47 setcomputername TênMới
net user administrator PasswordMới
Hình 4.19. Giao diện đăng nhập Win 10 IoT Core trên PowerShell
Nhập password là p@ssw0rd
Sau một lúc (khoảng 1 phút),sẽ đăng nhập vào RPI, khi đó màn hình PowerShell có dấu nhắc dạng như sau:
Lúc này chúng ta có thể thao tác với Raspberry Pi qua các lệnh Powershell.
Hình 4.20. Giao diện điều khiển Win10 IoT Core qua PowerShell
Ngay sau khi đăng nhập xong, nên đổi tên máy và password của
Administrator:
Để tắt RPI chạy Windows 10 IoT dùng lệnh: shutdown /r /t 0
Một vài lưu ý:
Windows 10 IoT cho RPI dùng driver khác với Windows thường (do RPI dùngchip ARM),Tại một thời điểm chi có một ứng dụng foreground trên Windows 10 IoT. Tức là chỉ thấy 1 ứng dụng trên màn hình nối trực tiếp với RPI. Để thay đổi ứng dụng foreground cần dùng lệnh trong Powershell hoặc qua giao diện web.
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 48
Phiên bản Windows 10 cho IoT với Windows 10 trên PC và Mobile
Bảng 4.2.Bảng so sánh một vài thuộc tính của hệ điều hành Windows 10 trên ba nền tảng PC, Mobile và thiết bị IoT
Tính năng Windows 10 Pro Windows 10 Windows 10 IoT
Mobile Core
Giao diện Có Có Không
Phân phối OEM OEM ?
Bán lẻ Bản quyền
Cấu trúc IA-32 IA-32
x86-64 ARMv7 ARM
Phiên bản N Có Không Không
Bộ nhớ vật lý tối 4 GB trên 32-bit ? ?
đa (RAM)
512 GB trên 64-bit
Cortana Có Có Không
Desktop Ảo Có Không
Cài đặt PC Mobile Thiết bị IoT
Chi phí Miễn phí khi nâng cấp từ Windows 7, 8 Miễn phí và 8.1 trong vòng 1 năm. Bản mua thì có
chi phí cao.
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 49 Để xây dựng ứng dụng Universal ta dùng Visual Studio 2017 chạy trên PC cài Windows 10. Một lưu ý khi chạy debug, build hay deploy một ứng dụng universal có kết nối với thiết bị raspberry thật ta cần có bước cài đặt, tùy chỉnh ban đầu. Cụ thể ta chọn Solution Platforms là ARM, Emulator là Remote
Machine: và đảm bảo đang kết nối
với đúng thiết bị bằng cách so sánh chuỗi IP kết nối trong properties của project và IP của thiết bị.
Hình 4.21. Giao diện Properties của Project
Để xem thiết bị đã được kết nối với máy tính chưa, hay kiểm tra IP trên Raspberry ta dùng Windows IoT Core Watcher
Hình 4.22. Giao diện Windows IoT Core Watcher
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 50
CHƯƠNG 5. KẾT QUẢ_NHẬN XÉT_ĐÁNH GIÁ
Nhiệm vụ chính của luận văn là xây dựng mô hình nhận dạng giọng nói sủ dụng thuật toán nhận dạng bằng văn bảng của microsoft nhận dạng tiếng nói thông qua kít Raspberry pi 3 điều khiển mô hình hệ thống thông qua xe robot .
Nhóm đã nghiên cứu và thực hiện đề tài trong 15 tuần và đã đạt được kết quả tốt là sản phẩm đã hoàn thành, chạy tốt và sản phẩm khá đẹp
5.1. KẾT QUẢ
Kết quả nhóm đạt được là khá tốt
Hiểu về hệ điều hành Win 10 IoT core trên Raspberry Pi.
Giao tiếp được với module L298N để điều khiển động cơ.
Giao tiếp được cảm biến siêu âm SRF04 để đo khoảng cách xe robot.
Kết nối được micro không dây thông qua USB Sound Card
Xe hoạt động khá ổn định. Xe có thể chạy tới, lui, xoay trái ,xoay phải và đang chạy có thể nói dừng thì xe dừng nhưng khi phát hiện vật cản trong vòng 30 cm xe sẽ dừng nhờ vào cảm biến siêu âm SRF04. động cơ chạy rất tốt và bộ vi xử lý điều khiển và xử lý tín hiệu khá ổn định.
Hình 5.1. Kết quả mô phỏng
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 51
Những hình ảnh kết quả đề tài
Hình 5.2. Sản phẩm hoàn thiện chụp từ trên xuống
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 52 Hình 5.3. Sản phẩm hoàn thiện chụp từ dưới lên
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 53 Hình 5.4. Sản phẩm hoàn thiện chụp từ phía trước
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 54 5.2. NHẬN XÉT VÀ ĐÁNH GIÁ
Sản phẩm đã hoàn thiện và hoạt động tốt nhưng trong quá trình điều khiển còn một số nhiễu làm ảnh hưởng đến tín hiệu và tín hiệu xử lý còn chậm
Sản phẩm hoàn thành 100%
Mô hình xe đẹp
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 55
CHƯƠNG 6. KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
6.1.KẾT LUẬN
Nắm rõ được giao tiếp Raspberry pi 3 với SRF04 giúp cho xe phát hiện được vật cản
Nắm rõ được giao tiếp Raspberry pi 3 với L298 giúp cho hệ thống xe có thể điều khiển được động cơ chạy thuận hay chạy nghịch
Xử lý được tín hiệu giọng nói giúp chúng ta điều khiển hệ thống thông qua giọng nói của người điều khiển
Nhúng chương trình ARM vào Raspberry pi 3
Hiểu được hệ điều hành win 10 Iot core , Hệ điều hành win 10 Iot core được tích hợp nhiều ứng dụng. Trong đó ứng dung xử lý âm thanh dự trên mã nguồn mở đã giúp cho nhóm thực hiện được đề tài điều khiển xe bằng giọng nói.
Nhóm đã hoàn thành đề tài khoảng 95% với muchj đích đã đề ra.
Sản phẩm của nhóm chạy khá ổn định va mô hình xe khá đẹp mắt . 6.2 NHỮNG HẠN CHẾ CỦA ĐỀ TÀI
Tín hiệu điều khiển bằng tiếng anh
Còn nhiễu tín hiệu nhiều
Đây la những vần đề nhóm chưa làm được 6.3.HƯỚNG PHÁT TRIỂN
6.3.1. Hướng khắc phục cách hạn chế của đề tài.
Tín hiệu điều khiển được bằng tiếng việt
Sử dụng những thiết bị thu và nhận âm thanh tốt hơn để lọc nhiễu tiếng ồn tốt nhất.
6.3.2. Hướng phát triển trong tương lai.
Nhóm sẽ phát triển thành hệ thống xe lăn điều khiển bằng giọng nói.
Phát triển hệ thống người robot làm việc được điều khiển bằng giọng nói
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 56
TÀI LIỆU THAM KHẢO
[1] Đoàn Văn Ban, phân tích và thiết kế hướng đối tượng, NXB Khoa học và Kỹ thuật.1999
[2] Cộng đồng Microsoft,Trang web www.support.microsoft.com
[3] Nguyễn Việt Hùng, Nguyễn Ngô Lâm, Nguyễn Văn Phúc, Giáo trình Kỹ thuật truyền số liệu, Trường ĐH Sư Phạm Kỹ Thuật, 9.2011.
[4] Ivar Jacobson Object – Oriented Software Engineering, Addison-Wesley Publishing Company, 1992
[5]. Cộng đồng Raspberry Việt Nam, Trang web www. Raspberry.com.vn
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 57
PHỤ LỤC : CODE CHƯƠNG TRÌNH ĐIỀU KHIỂN XE ROBOT BẰNG GIỌNG NÓI.
Code chương trình chính.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Media.SpeechRecognition;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
namespace SpeechControlledRobot__RPi2_
{
public sealed partial class MainPage : Page {
private SpeechRecognizer MyRecognizer;
private bool AvoidObstacle = true;
public MainPage() {
this.InitializeComponent();
MotorDriver.InitializePins(MotorDriver.AvailableGpioPin.GpioPin_5, MotorDriver.AvailableGpioPin.GpioPin_6,
MotorDriver.AvailableGpioPin.GpioPin_13, MotorDriver.AvailableGpioPin.GpioPin_26);
InitializeSpeechRecognizer();
Sensor.UltrasonicDistanceSensor Front_DistanceSensor = new
Sensor.UltrasonicDistanceSensor(Sensor.UltrasonicDistanceSensor.AvailableGpioP in.GpioPin_12, Sensor.UltrasonicDistanceSensor.AvailableGpioPin.GpioPin_16);
Sensor.ObstacleDetection Front_ObstacleDetection = new Sensor.ObstacleDetection(Front_DistanceSensor);
Front_ObstacleDetection.ObstacleDetected +=
Front_ObstacleDetection_ObstacleDetected;
}
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 58 private void
Front_ObstacleDetection_ObstacleDetected(Sensor.ObstacleDetection.DetectionSta te arg1, double arg2)
{
if (AvoidObstacle == true) {
if (arg1 == Sensor.ObstacleDetection.DetectionState.Detected &&
MotorDriver.CurrentState == MotorDriver.State.MovingForward) {
MotorDriver.Stop();
Debug.WriteLine("Robot stopped! (Obstacle Detected)");
} }
if (AvoidObstacle == true) {
if (arg1 ==
Sensor.ObstacleDetection.DetectionState.Detected && MotorDriver.CurrentState
== MotorDriver.State.MovingReverse) {
MotorDriver.Stop();
Debug.WriteLine("Robot stopped! (Obstacle Detected)");
} }
} /// <summary>
/// Initializes MyRecognizer and Loads Grammar from File 'Grammar\MyGrammar.xaml'
/// </summary>
private async void InitializeSpeechRecognizer() {
MyRecognizer = new SpeechRecognizer();
MyRecognizer.StateChanged += MyRecognizer_StateChanged;
MyRecognizer.ContinuousRecognitionSession.ResultGenerated +=
MyRecognizer_ResultGenerated;
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 59 StorageFile GrammarContentFile = await
Package.Current.InstalledLocation.GetFileAsync(@"Grammar\MyGrammar.xml");
SpeechRecognitionGrammarFileConstraint GrammarConstraint = new SpeechRecognitionGrammarFileConstraint(GrammarContentFile);
MyRecognizer.Constraints.Add(GrammarConstraint);
SpeechRecognitionCompilationResult CompilationResult = await MyRecognizer.CompileConstraintsAsync();
Debug.WriteLine("Status: " + CompilationResult.Status.ToString());
if (CompilationResult.Status == SpeechRecognitionResultStatus.Success) {
await MyRecognizer.ContinuousRecognitionSession.StartAsync();
} }
/// <summary>
/// Fires when MyRecognizer successfully parses a speech /// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void
MyRecognizer_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
Debug.WriteLine(args.Result.Text);
switch (args.Result.Text) {
case "move forward":
MotorDriver.MoveForward();
break;
case "move reverse":
MotorDriver.MoveReverse();
break;
case "turn right":
MotorDriver.TurnRight();
break;
case "turn left":
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 60 MotorDriver.TurnLeft();
break;
case "stop":
MotorDriver.Stop();
break;
case "engage obstacle detection":
AvoidObstacle = true;
break;
case "disengage obstacle detection":
AvoidObstacle = false;
break;
default:
break;
} }
/// <summary>
/// Fires when MyRecognizer's state changed /// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void MyRecognizer_StateChanged(SpeechRecognizer sender, SpeechRecognizerStateChangedEventArgs args)
{
Debug.WriteLine(args.State);
} } }
Code chương trình con:Drive_động cơ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Gpio;
namespace SpeechControlledRobot__RPi2_
{
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 61 /// <summary>
/// Provides abstraction layer to drive robot /// </summary>
public static class MotorDriver {
private static GpioPin MotorLeft_A, MotorLeft_B;
private static GpioPin MotorRight_A, MotorRight_B;
private static State _CurrentState;
/// <summary>
/// Available Gpio Pins. Refer:
/// </summary>
public enum AvailableGpioPin : int {
/// <summary>
/// Raspberry Pi 2 - Header Pin Number : 29 /// </summary>
GpioPin_5 = 5, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 31 /// </summary>
GpioPin_6 = 6, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 32 /// </summary>
GpioPin_12 = 12, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 33 /// </summary>
GpioPin_13 = 13, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 36 /// </summary>
GpioPin_16 = 16, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 12 /// </summary>
GpioPin_18 = 18, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 15
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 62 /// </summary>
GpioPin_22 = 22, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 16 /// </summary>
GpioPin_23 = 23, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 18 /// </summary>
GpioPin_24 = 24, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 22 /// </summary>
GpioPin_25 = 25, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 37 /// </summary>
GpioPin_26 = 26, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 13 /// </summary>
GpioPin_27 = 27 }
/// <summary>
/// Available driving states /// </summary>
public enum State : byte {
MovingForward, MovingReverse, RotatingRight, RotatingLeft, TurningRight, TurningLeft, Stopped }
public static State CurrentState {
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 63 get
{
return _CurrentState;
} }
/// <summary>
/// Initializes four pins for motor driver /// </summary>
/// <param name="Pin_MotorLeft_A">Left motor's Pin A.</param>
/// <param name="Pin_MotorLeft_B">Left motor's Pin B.</param>
/// <param name="Pin_MotorRight_A">Right motor's Pin A.</param>
/// <param name="Pin_MotorRight_B">Right motor's Pin B.</param>
public static void InitializePins(AvailableGpioPin Pin_MotorLeft_A, AvailableGpioPin Pin_MotorLeft_B, AvailableGpioPin Pin_MotorRight_A, AvailableGpioPin Pin_MotorRight_B)
{
GpioController MyGpioConroller = GpioController.GetDefault();
if (MotorLeft_A != null) {
MotorLeft_A = null;
MotorLeft_B = null;
MotorRight_A = null;
MotorRight_B = null;
}
MotorLeft_A = MyGpioConroller.OpenPin((int)Pin_MotorLeft_A);
MotorLeft_B = MyGpioConroller.OpenPin((int)Pin_MotorLeft_B);
MotorRight_A = MyGpioConroller.OpenPin((int)Pin_MotorRight_A);
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 64 MotorRight_B = MyGpioConroller.OpenPin((int)Pin_MotorRight_B);
MotorLeft_A.SetDriveMode(GpioPinDriveMode.Output);
MotorLeft_B.SetDriveMode(GpioPinDriveMode.Output);
MotorRight_A.SetDriveMode(GpioPinDriveMode.Output);
MotorRight_B.SetDriveMode(GpioPinDriveMode.Output);
_CurrentState = State.Stopped;
}
public static void MoveForward() {
if (MotorLeft_A == null) return;
MotorLeft_A.Write(GpioPinValue.Low);
MotorLeft_B.Write(GpioPinValue.High);
MotorRight_A.Write(GpioPinValue.Low);
MotorRight_B.Write(GpioPinValue.High);
_CurrentState = State.MovingForward;
}
public static void MoveReverse() {
if (MotorLeft_A == null) return;
MotorLeft_A.Write(GpioPinValue.High);
MotorLeft_B.Write(GpioPinValue.Low);
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 65
MotorRight_A.Write(GpioPinValue.High);
MotorRight_B.Write(GpioPinValue.Low);
_CurrentState = State.MovingReverse;
}
public static void TurnRight() {
// Return if pins are not initialized if (MotorLeft_A == null)
return;
// Left Motor
MotorLeft_A.Write(GpioPinValue.High);
MotorLeft_B.Write(GpioPinValue.Low);
// Right Motor
MotorRight_A.Write(GpioPinValue.Low);
MotorRight_B.Write(GpioPinValue.High);
// Set current state
_CurrentState = State.RotatingRight;
}
public static void TurnLeft() {
if (MotorLeft_A == null) return;
MotorLeft_A.Write(GpioPinValue.Low);
MotorLeft_B.Write(GpioPinValue.High);
MotorRight_A.Write(GpioPinValue.High);
MotorRight_B.Write(GpioPinValue.Low);
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 66
_CurrentState = State.RotatingLeft;
}
public static void Stop() {
if (MotorLeft_A == null) return;
MotorLeft_A.Write(GpioPinValue.Low);
MotorLeft_B.Write(GpioPinValue.Low);
MotorRight_A.Write(GpioPinValue.Low);
MotorRight_B.Write(GpioPinValue.Low)
_CurrentState = State.Stopped;
} } }
Code chương trình con:cảm biến siêu âm SRF04 using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Gpio;
namespace SpeechControlledRobot__RPi2_.Sensor {
public class UltrasonicDistanceSensor {
private GpioPin Pin_Trig, Pin_Echo;
private Stopwatch _StopWatch;
private double? _Distance;
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 67
/// <summary>
/// Available Gpio Pins. Refer: https://ms-iot.github.io/content/en- US/win10/samples/PinMappingsRPi2.htm
/// </summary>
public enum AvailableGpioPin : int {
/// <summary>
/// Raspberry Pi 2 - Header Pin Number : 29 /// </summary>
GpioPin_5 = 5, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 31 /// </summary>
GpioPin_6 = 6, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 32 /// </summary>
GpioPin_12 = 12, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 33 /// </summary>
GpioPin_13 = 13, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 36 /// </summary>
GpioPin_16 = 16, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 12 /// </summary>
GpioPin_18 = 18, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 15 /// </summary>
GpioPin_22 = 22, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 16 /// </summary>
GpioPin_23 = 23,
BỘ MÔN ĐIỆN TỬ CÔNG NGHIỆP – Y SINH 68 /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 18 /// </summary>
GpioPin_24 = 24, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 22 /// </summary>
GpioPin_25 = 25, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 37 /// </summary>
GpioPin_26 = 26, /// <summary>
/// Raspberry Pi 2 - Header Pin Number : 13 /// </summary>
GpioPin_27 = 27 }
public UltrasonicDistanceSensor(AvailableGpioPin TrigPin, AvailableGpioPin EchoPin)
{
_StopWatch = new Stopwatch();
var gpio = GpioController.GetDefault();
Pin_Trig = gpio.OpenPin((int)TrigPin);
Pin_Trig.SetDriveMode(GpioPinDriveMode.Output);
Pin_Trig.Write(GpioPinValue.Low);
Pin_Echo = gpio.OpenPin((int)EchoPin);
Pin_Echo.SetDriveMode(GpioPinDriveMode.Input);
}
public double GetDistance() {
var mre = new ManualResetEventSlim(false);