Bhairav Pardiwala
Published

GPIO control using MQTT

Control your raspberry pi 2 from any internet capable network with minimal server setup

IntermediateShowcase (no instructions)7,663
GPIO control using MQTT

Things used in this project

Hardware components

Breadboard (generic)
Breadboard (generic)
×1
LED (generic)
LED (generic)
×1
Raspberry Pi 2 Model B
Raspberry Pi 2 Model B
×1
Jumper wires (generic)
Jumper wires (generic)
×1
ethernet cable
×1
Windows phone 8.,1
×1
Resistor
×1

Software apps and online services

Visual Studio 2015
Microsoft Visual Studio 2015
Windows 10 IoT Core
Microsoft Windows 10 IoT Core
MQTT library
Newtonsoft.Json
visual studio 2013

Story

Read more

Schematics

WP_20151031_12_48_55_Pro__highres.jpg

WP_20151031_12_49_29_Pro__highres.jpg

WP_20151031_12_49_36_Pro__highres.jpg

Code

Device Init code

C#
This code is to be kept in device initialization
MqttClient cl;
        string sendTopic =  "<devname>" ;
        string[] reciveTopic = { "<devname>" };
        //this is to demonstrate diffrent reposnes sent to diffrent requests
        string diffResponse1="resp1", diffResponse2="resp2"; 
        
        Boolean run = true;
        String instanceid = "";
         
        Windows.Devices.Gpio.GpioController ioControll = Windows.Devices.Gpio.GpioController.GetDefault();
        Windows.Devices.Gpio.GpioPin pin;

Page init code

C#
Page init code when constructor is called
//you can use cloud amqp for free MQTT hosting service 
            cl = new MqttClient("<free cloud client server >", 1883, false, MqttSslProtocols.None);
            cl.Connect("<devname>", "<username>:<username>", "<password>", true, 100);
            byte[] qosLevels = { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE };
            cl.Subscribe(reciveTopic, qosLevels);
            cl.MqttMsgPublishReceived += Cl_MqttMsgPublishReceived;
            instanceid = Guid.NewGuid().ToString();
             pin = ioControll.OpenPin(5);
            pin.SetDriveMode(Windows.Devices.Gpio.GpioPinDriveMode.Output);

Timer publishing logic

C#
This publishes messages on an interval .This is so that you can schedule a timer to revive device updates on a fixed delay basis .This is optional
Task.Run(async () =>
            {
                try
                {

                    while (true)
                    {
                        if (run)
                        {
                            CommunicationMessage commMsg = new CommunicationMessage();
                            String resp = diffResponse1;
                            commMsg.id = instanceid;
                            commMsg.msg = resp;
                            publishMessage(sendTopic, SerializeIt(commMsg));
                        }
                        await Task.Delay(TimeSpan.FromMinutes(15));
                    }

                }
                catch (Exception)
                {

                   // throw;
                }

            });

Logic to listen and respond on device

C#
This code enables the windows 10 iot device to listen and respond to messages
 private async Task LedOn()
        {
            try
            {
                if (ioControll != null)
                {
                    pin.Write(Windows.Devices.Gpio.GpioPinValue.High);
                }
            }
            catch (Exception)
            {
            }
        }
        private async Task LedOff()
        {
            try
            {
                if (ioControll != null)
                {
                        pin.Write(Windows.Devices.Gpio.GpioPinValue.Low);
                }
            }
            catch (Exception)
            {

            }
        }

        private void Cl_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            if(e.Message!=null && !String.IsNullOrWhiteSpace(Encoding.UTF8.GetString(e.Message)))
            {
                CommunicationMessage mrcv= deserializeIt(e.Message);
                if(mrcv.id!=instanceid)
                {
                    if (mrcv.msg.Equals("ledon"))
                    {
                        CommunicationMessage commMsg = new CommunicationMessage();
                        commMsg.id = instanceid;
                        commMsg.msg = diffResponse1;
                        publishMessage(sendTopic, SerializeIt(commMsg));
                        LedOn();
                    }
                    else if (mrcv.msg.Equals("ledoff"))
                    {
                        CommunicationMessage commMsg = new CommunicationMessage();
                        commMsg.id = instanceid;
                        commMsg.msg = diffResponse2;
                        publishMessage(sendTopic, SerializeIt(commMsg));
                        LedOff();
                    }
                    else if (mrcv.msg.Equals("stop"))
                    {
                        run = false;
                        LedOff();
                    }
                    else
                    {
                        run = true;
                    }
                }
                

            }
        }

       
        public void publishMessage(String topic, byte[] message)
        {
            try
            {
                cl.Publish(topic,message);
            }
            catch (Exception)
            {


            }
        }
        public byte[] SerializeIt(Object obj)
        {
            MemoryStream ms = new MemoryStream();
            JsonSerializer serializer = new JsonSerializer();
            BsonWriter writer = new BsonWriter(ms);
            serializer.Serialize(writer, obj);
            return ms.ToArray();
        }

       

        public CommunicationMessage deserializeIt(byte[] b)
        {
            MemoryStream ms = new MemoryStream(b);
            JsonSerializer serializer = new JsonSerializer();
            BsonReader reader = new BsonReader(ms);
            CommunicationMessage rcv = serializer.Deserialize<CommunicationMessage>(reader);
            return rcv;
        }

Windows 8.1 phone logic

C#
Visual studio 2013 code .I had a Lumia 930 device with windows 8.1 hence i had to code 2 separate projects but using power of universal apps .Both projects could be same in future
 public sealed partial class MainPage : Page
    {
        MqttClient cl;
        string[] sendTopic = { "<devname>" };
        string reciveTopic =  "<devname>" ;
        string diffResponse1 = "resp1", diffResponse2 = "resp2";
       
        String instanceid = "";
      
        public MainPage()
        {
            this.InitializeComponent();

            this.NavigationCacheMode = NavigationCacheMode.Required;
            try
            {
              //Server could be cloudAmqp
                cl = new MqttClient("<mqtt server>", <portnumber>, false, MqttSslProtocols.None);
                cl.Connect("<phone queue name>", "<username>:<username>", "<password>", true, 100);
                byte[] qosLevels = { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE };
                cl.Subscribe(sendTopic, qosLevels);
                cl.MqttMsgPublishReceived += Cl_MqttMsgPublishReceived;
                instanceid = Guid.NewGuid().ToString(); //this is so that we identiify and not respond to our own echo
            }
            catch (Exception)
            {
            }
        }

        private async void Cl_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            // throw new NotImplementedException();
           await  Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,  () => {
                try
                {
                    if (e.Message != null && !String.IsNullOrWhiteSpace(Encoding.UTF8.GetString(e.Message, 0, e.Message.Count())))
                    {
                       CommunicationMessage recvMsg = deserializeIt(e.Message);
                       if(recvMsg.id!=instanceid)
                       {
                           String text = recvMsg.msg;
                           //testOP.Text += text + "\n";//can display text output in a text field
                       }
                    }
                }
                catch (Exception)
                {
                }

            });
           
        }
       

        private void ButtonLedOn_Tapped(object sender, TappedRoutedEventArgs e)
        {
            CommunicationMessage commMsg = new CommunicationMessage();
            commMsg.id = instanceid;
            commMsg.msg = "ledon";
            publishMessage(reciveTopic, SerializeIt(commMsg));
        }

        private void ButtonLedOff_Tapped(object sender, TappedRoutedEventArgs e)
        {
            CommunicationMessage commMsg = new CommunicationMessage();
            commMsg.id = instanceid;
            commMsg.msg = "ledoff";
            publishMessage(reciveTopic,SerializeIt(commMsg));
        }

        private void ButtonStop_Tapped(object sender, TappedRoutedEventArgs e)
        {
            CommunicationMessage commMsg = new CommunicationMessage();
            commMsg.id = instanceid;
            commMsg.msg = "stop";
            publishMessage(reciveTopic, SerializeIt(commMsg));
        }

        private void ButtonRun_Tapped(object sender, TappedRoutedEventArgs e)
        {
            CommunicationMessage commMsg = new CommunicationMessage();
            commMsg.id = instanceid;
            commMsg.msg = "run";
            publishMessage(reciveTopic, SerializeIt(commMsg));
        }
        public void publishMessage(String topic, byte[] message)
        {
            try
            {
                cl.Publish(topic, message);
            }
            catch (Exception)
            {


            }
        }
        public byte[] SerializeIt(Object obj)
        {
            MemoryStream ms = new MemoryStream();
            JsonSerializer serializer = new JsonSerializer();

            // serialize product to BSON
            BsonWriter writer = new BsonWriter(ms);
            serializer.Serialize(writer, obj);
            return ms.ToArray();
        }
        public CommunicationMessage deserializeIt(byte[] b)
        {
            MemoryStream ms = new MemoryStream(b);
            JsonSerializer serializer = new JsonSerializer();
            BsonReader reader = new BsonReader(ms);
            CommunicationMessage rcv = serializer.Deserialize<CommunicationMessage>(reader);
            return rcv;
        }
    }

Windows phone 8.1 Xaml file

XML
This is to be pasted in Xaml file.This is the UI of the phone app
<StackPanel Orientation="Vertical">
        <Button Content="led on" HorizontalAlignment="Stretch" Tapped="ButtonLedOn_Tapped">
            
        </Button>
        <Button Content="led off" HorizontalAlignment="Stretch" Tapped="ButtonLedOff_Tapped">

        </Button>
        <!--this is to control optional timer code -->
        <Button Content="Stop" HorizontalAlignment="Stretch" Tapped="ButtonStop_Tapped">

        </Button>
        <!--this is to control optional timer code -->
        <Button Content="Run" HorizontalAlignment="Stretch" Tapped="ButtonRun_Tapped">

        </Button>
    </StackPanel>

Communication message class structure

C#
This is a common code file for sending and reciving communication message from phone to device
  public class CommunicationMessage
    {
        public String id = "";
        public String msg = "";
    }

Credits

Bhairav Pardiwala

Bhairav Pardiwala

8 projects • 16 followers
Polyglot dev

Comments