Super Kid
Published © MIT

Rover (connected to Azure)

The Rover project used Azure

IntermediateFull instructions provided30 minutes3,154
Rover (connected to Azure)

Things used in this project

Hardware components

Raspberry Pi 2 Model B
Raspberry Pi 2 Model B
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
L298N Motor Controller
×1
Robot Kit
×1
DC-DC Step up Converter
×1

Software apps and online services

Microsoft Azure
Microsoft Azure
Windows 10 IoT Core
Microsoft Windows 10 IoT Core
Visual Studio 2015
Microsoft Visual Studio 2015

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

rover20-20wiring20diagram_hhvzjpE7MC.jpg

Code

MainPage.xaml

HTML
<Page
    x:Class="Rover_Azure.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBox  HorizontalAlignment="Left" Height="305" Margin="10,275,-1550,0" TextWrapping="Wrap" FontSize="30" VerticalAlignment="Top" x:Name="ABC" Width="1900"/>
        <TextBox x:Name="Log" HorizontalAlignment="Left" Height="260" Margin="10,10,-1550,0" TextWrapping="Wrap" Text="" FontSize="30" VerticalAlignment="Top" Width="1900"/>
    </Grid>
</Page>

MainPage.xaml.cs

C#
using System;
using Windows.UI.Xaml.Controls;
using Microsoft.Azure.Devices.Client;
using System.ComponentModel;
using Windows.UI.Core;
using System.Threading.Tasks;
using System.Text;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
// Microsoft Azure: https://azure.microsoft.com/en-us/
/// <note>
/// You have to have the Azure IoT Hub to run this app.
/// </note>

namespace Rover_Azure
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private BackgroundWorker _worker;
        private CoreDispatcher _dispatcher;

        private bool _finish;
        private TwoMotorsDriver driver = new TwoMotorsDriver(new Motor(27, 22), new Motor(5, 6));
        private UltrasonicDistanceSensor ultrasonicDistanceSensor = new UltrasonicDistanceSensor(23, 24);

        public MainPage()
        {
            InitializeComponent();


            Loaded += MainPage_Loaded;

            Unloaded += MainPage_Unloaded;
        }

        private void MainPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            _dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;

            _worker = new BackgroundWorker();
            _worker.DoWork += DoWork;
            _worker.RunWorkerAsync();
        }

        private void MainPage_Unloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            _finish = true;
        }

        private async void DoWork(object sender, DoWorkEventArgs e)
        {
            await WriteLog("Moving forward");

            while (!_finish)
            {

                driver.MoveForward();

                await Task.Delay(25);

                var distance = await ultrasonicDistanceSensor.GetDistanceInCmAsync(1000);

                await WriteLog1($"Distance: {distance} cm ");

                if (distance > 35)
                {
                    continue;
                }
                await WriteLog($"Obstacle found at {distance} cm or less. Turning right");

                await driver.TurnRightAsync();

                await WriteLog("Moving forward");
            }
        }

        private async Task WriteLog(string text)
        {
            await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                string logtowrite;
                logtowrite = text;
                Log.Text = "";
                Log.Text = logtowrite;
                SendDataToAzure(logtowrite);
            });
        }

        private async Task WriteLog1(string text)
        {
            await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                string logtowrite;
                logtowrite = text;
                ABC.Text = "";
                ABC.Text = logtowrite;
                SendDataToAzure(logtowrite);
            });
        }
        private async void SendDataToAzure(string textToSend)
        {
            // TODO: Replace 'YOUR_IOT_DEVICE_CONNECTION_STRING' with your IoT Device connection string. To get the IoT Device connection string, ...
            // ... go to Device Explorer and then Management.
            DeviceClient deviceClient = DeviceClient.CreateFromConnectionString("YOUR_IOT_DEVICE_CONNECTION_STRING", TransportType.Http1);
            var msg = new Message(Encoding.UTF8.GetBytes(textToSend));
            await deviceClient.SendEventAsync(msg);
        }
    }
}

Motor.cs

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Gpio;

namespace Rover_Azure
{
    public class Motor
    {
        private readonly GpioPin _leftMotor;
        private readonly GpioPin _rightMotor;
        public Motor(int Pin1, int Pin2)
        {
            var gpio = GpioController.GetDefault();
            _leftMotor = gpio.OpenPin(Pin1);
            _rightMotor = gpio.OpenPin(Pin2);
            _leftMotor.SetDriveMode(GpioPinDriveMode.Output);
            _rightMotor.SetDriveMode(GpioPinDriveMode.Output);
        }
        public void MoveForward()
        {
            _leftMotor.Write(GpioPinValue.High);
            _rightMotor.Write(GpioPinValue.Low);
        }

        public void MoveBackward()
        {
            _leftMotor.Write(GpioPinValue.Low);
            _rightMotor.Write(GpioPinValue.High);
        }

        public void Stop()
        {
            _leftMotor.Write(GpioPinValue.Low);
            _rightMotor.Write(GpioPinValue.Low);
        }
    }
}

TwoMotorsDriver.cs

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rover_Azure
{
    public class TwoMotorsDriver
    {
        private readonly Motor _leftMotor;
        private readonly Motor _rightMotor;
        public TwoMotorsDriver(Motor left, Motor right)
        {
            _leftMotor = left;
            _rightMotor = right;
        }
        public void Stop()
        {
            _leftMotor.Stop();
            _rightMotor.Stop();
        }

        public void MoveForward()
        {
            _leftMotor.MoveForward();
            _rightMotor.MoveForward();
        }

        public void MoveBackward()
        {
            _leftMotor.MoveBackward();
            _rightMotor.MoveBackward();
        }

        public async Task TurnRightAsync()
        {
            _leftMotor.MoveBackward();
            _rightMotor.MoveForward();

            await Task.Delay(TimeSpan.FromMilliseconds(250));

            _leftMotor.Stop();
            _rightMotor.Stop();
        }

        public async Task TurnLeftAsync()
        {
            _leftMotor.MoveForward();
            _rightMotor.MoveBackward();

            await Task.Delay(TimeSpan.FromMilliseconds(250));

            _leftMotor.Stop();
            _rightMotor.Stop();
        }
    }
}

UltrasonicDistanceSensor.cs

C#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Gpio;

namespace Rover_Azure
{
    public class UltrasonicDistanceSensor
    {
        private readonly GpioPin triggerpin;
        private readonly GpioPin echopin;
        private Stopwatch stopwatch;
        private double? distance;
        public UltrasonicDistanceSensor(int trigger, int echo)
        {
            var gpio = GpioController.GetDefault();
            triggerpin = gpio.OpenPin(trigger);
            echopin = gpio.OpenPin(echo);
            triggerpin.SetDriveMode(GpioPinDriveMode.Output);
            echopin.SetDriveMode(GpioPinDriveMode.Input);
            echopin.ValueChanged += Echopin_ValueChanged;
        }

        private void Echopin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args)
        {
            distance = stopwatch.ElapsedMilliseconds * 34.3 / 2.0;
        }
        public async Task<double> GetDistanceInCmAsync(int timeoutInMilliseconds)
        {
            distance = null;
            try
            {
                stopwatch.Reset();
                triggerpin.Write(GpioPinValue.High);
                await Task.Delay(TimeSpan.FromMilliseconds(10));
                triggerpin.Write(GpioPinValue.Low);
                stopwatch.Start();
                for(var i = 0; i < timeoutInMilliseconds/100; i++)
                {
                    if (distance.HasValue)
                        return distance.Value;
                    await Task.Delay(TimeSpan.FromMilliseconds(100));
                }
            }
            finally
            {
                stopwatch.Stop();
            }
            return double.MaxValue;
        }
    }
}

Azure Device Explorer

Credits

Super Kid

Super Kid

1 project • 26 followers
I am building the project with IoT with Windows (Windows On Devices). Also I have a tag: Break your heart for the beginner.

Comments