Things used in this project

Code

CONTROLLER.csC#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Devices.Gpio;
using Windows.Devices.I2c;
using Windows.Devices.SerialCommunication;
using Windows.Devices.Spi;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;

namespace IoTController
{
    class CONTROLLER
    {
        private List<I2cDevice> i2cDeviceList;

        public CONTROLLER(string remoteHostname, string localPortName, string remotePortName)
        {
            var now = DateTime.Now;
            Debug.WriteLine(now + " : " + " Controller Unit CONSTRUCTOR");
            i2cDeviceList = new List<I2cDevice>();
            
            RemoteHostname = remoteHostname;
            LocalPortName = localPortName;
            RemotePortName = remotePortName;
            InitGPIOController();
            InitNetworkUPD();
        }

        public string RemoteHostname
        {
            get; set;
        }

        public string LocalPortName
        {
            get; set;
        }

        public string RemotePortName
        {
            get; set;
        }

        private HostName remoteHostname;
        private DatagramSocket socket = new DatagramSocket();
        private DatagramSocket listenerSocket = new DatagramSocket();

        private DataWriter writer;
        private IOutputStream outputStream;

        public async void InitNetworkUPD()
        {
            remoteHostname = new HostName(RemoteHostname);
            listenerSocket.MessageReceived += UDPMessageReceived;
            //listenerSocket.Control.MulticastOnly = true;
            // Start listen operation.

            try
            {
                await listenerSocket.BindServiceNameAsync(LocalPortName); //ServiceName.Text
                //listenerSocket.JoinMulticastGroup(remoteHostname);  //RemoteAddress.Text
            }
            catch (Exception exception)
            {
                listenerSocket.Dispose();
                listenerSocket = null;

                // If this is an unknown status it means that the error is fatal and retry will likely fail.
                if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
                {
                    throw;
                }

                Debug.WriteLine("Start listening failed with error: " + exception.Message);
            }

            try
            {
                // UPD SENDING SETUP ======================================================
                outputStream = await socket.GetOutputStreamAsync(remoteHostname, RemotePortName);
                // Send out some multicast or broadcast data. Datagrams generated by the IOutputStream will use
                // <source host, source port> information obtained from the parent socket (i.e., 'listenSocket' in
                // this case).
                writer = new DataWriter(outputStream);
            }
            catch (Exception exception)
            {
                Debug.WriteLine("outputStream error: " + exception.Message);
            }
        }

        private void UDPMessageReceived(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs eventArguments)
        {
            try
            {
                // Interpret the incoming datagram's entire contents as a string.
                uint stringLength = eventArguments.GetDataReader().UnconsumedBufferLength;
                string receivedMessage = eventArguments.GetDataReader().ReadString(stringLength);


                Debug.WriteLine(
                    "Received data from remote peer (Remote Address: " +
                    eventArguments.RemoteAddress.CanonicalName +
                    ", Remote Port: " +
                    eventArguments.RemotePort + "): \"" +
                     receivedMessage + "\"");
            }
            catch (Exception exception)
            {
                SocketErrorStatus socketError = SocketError.GetStatus(exception.HResult);

                if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
                {
                    Debug.WriteLine($"Unknown UDPMessageReceived Error: {exception}");
                }

                Debug.WriteLine("Error happened when receiving a datagram:" + exception.Message);
            }
        }

        public async void Send_UDP(byte[] ReadBuf) //MPUDATA mpudata
        {
            try
            {
                // GetOutputStreamAsync can be called multiple times on a single DatagramSocket instance to obtain
                // IOutputStreams pointing to various different remote endpoints. The remote hostname given to
                // GetOutputStreamAsync can be a unicast, multicast or broadcast address.


                //Array.Copy(ReadBuf, 0, updData, 1, ReadBuf.Length-1);
                writer.WriteBytes(ReadBuf);

                //writer.WriteString(sOut);
                await writer.StoreAsync();
            }
            catch (Exception exception)
            {
                // If this is an unknown status it means that the error is fatal and retry will likely fail.
                if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
                {
                    Debug.WriteLine($"Unknown Sending UPD Error: {exception}");
                }
            }
        }


        public async Task<I2cDevice> InitI2cCommunication(DEVICE device)
        {
            string aqs = I2cDevice.GetDeviceSelector();                     /* Get a selector string that will return all I2C controllers on the system */
            var dis = await DeviceInformation.FindAllAsync(aqs);            /* Find the I2C bus controller device with our selector string           */

            /* Checking number of I2C ports available
            for (int i=0;i<dis.Count;i++)
            {
                Debug.WriteLine(dis[i].Id.ToString());
            }
            */

            if (dis.Count == 0)
            {
                Debug.WriteLine("No I2C controllers were found on the system");
                return null;
            }

            int I2CPort = (int)device.I2CPort;

            var settings = new I2cConnectionSettings(device.I2C_ADDRESS);
            settings.BusSpeed = I2cBusSpeed.FastMode;
            
            device.I2cCommunication = await I2cDevice.FromIdAsync(dis[I2CPort].Id, settings);    /* Create an I2cDevice with our selected bus controller and I2C settings */

            if (device.I2cCommunication != null)
            {
                i2cDeviceList.Add(device.I2cCommunication); //Debug.WriteLine("i2C List Count: " + i2cDeviceList.Count.ToString());
            }

            else
            {
                Debug.WriteLine($"Slave address {settings.SlaveAddress} on I2C Controller {dis[I2CPort].Id} is currently in use by another application.");
                return null;
            }

            return device.I2cCommunication;
        }

        public async Task<SpiDevice> InitSPICommunication(DEVICE device)
        {
            const string SPI_CONTROLLER_NAME = "SPI0";  /* For DragonBoard, use SPI0                                */
            const Int32 SPI_CHIP_SELECT_LINE = 0;       /* Line 0 maps to physical pin number 12 on the DragonBoard */
            try
            {
                var settings = new SpiConnectionSettings(SPI_CHIP_SELECT_LINE);
                settings.ClockFrequency = 4800000;                              /* 5MHz is the rated speed of the ADXL345 accelerometer                     */
                settings.Mode = SpiMode.Mode3;                                  /* The accelerometer expects an idle-high clock polarity, we use Mode3    
                                                                                 * to set the clock polarity and phase to: CPOL = 1, CPHA = 1         
                                                                                 */

                string aqs = SpiDevice.GetDeviceSelector(SPI_CONTROLLER_NAME);                     /* Get a selector string that will return all SPI controllers on the system */
                var dis = await DeviceInformation.FindAllAsync(aqs);            /* Find the SPI bus controller devices with our selector string             */
                device.SPICommunication = await SpiDevice.FromIdAsync(dis[0].Id, settings);    /* Create an SpiDevice with our bus controller and SPI settings             */
                if (device.SPICommunication == null)
                {
                    Debug.WriteLine($"SPI Controller {dis[0].Id} is currently in use by another application.");
                    return null;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("SPI Initialization failed. Exception: " + ex.Message);
                return null;
            }

            return device.SPICommunication;
        }

        public async Task<SerialDevice> InitUARTCommunication(DEVICE device)
        {
            string aqs = SerialDevice.GetDeviceSelector();
            var dis = await DeviceInformation.FindAllAsync(aqs);

            int UARTPort = -1;
            for (int i = 0; i < dis.Count; i++)
            {
                //string stest = dis[i].Id.ToString();
                if (dis[i].Id.ToString().Contains(device.UARTPort))
                {
                    UARTPort = i;
                    break;
                }
            }
            //Debug.WriteLine(dis[UARTPort].Id.ToString());

            if (UARTPort != -1)
            {
                try
                {
                    device.UARTCommunication = await SerialDevice.FromIdAsync(dis[UARTPort].Id);
                    device.UARTCommunication.WriteTimeout = TimeSpan.FromMilliseconds(device.UARTWriteTimeout);
                    device.UARTCommunication.ReadTimeout = TimeSpan.FromMilliseconds(device.UARTReadTimeout);
                    device.UARTCommunication.BaudRate = device.UARTBaudRate;
                    device.UARTCommunication.Parity = SerialParity.None;
                    device.UARTCommunication.StopBits = SerialStopBitCount.One;
                    device.UARTCommunication.DataBits = 8;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }

            return device.UARTCommunication;
        }

        public GpioController IoController
        {
            get; set;
        }

        public void InitGPIOController()
        {
            IoController = GpioController.GetDefault(); /* Get the default GPIO controller on the system */

            if (IoController == null)
            {
                throw new Exception("GPIO does not exist on the current system.");
            }
        }

        public void InitGPIOInterruptPin(DEVICE device)
        {
            try
            {
                device.IoInterruptPin = IoController.OpenPin(device.IoInterruptPinID);
                //Check if input pull-up resistors are supported
                if (device.IoInterruptPin.IsDriveModeSupported(GpioPinDriveMode.InputPullUp))
                    device.IoInterruptPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
                else
                    device.IoInterruptPin.SetDriveMode(GpioPinDriveMode.Input);

                // Set a debounce timeout to filter out switch bounce noise from a button press
                device.IoInterruptPin.DebounceTimeout = TimeSpan.FromMilliseconds(0);
                //Debug.WriteLine("GPIO pins " + sensor.IoInterruptPinID.ToString() + " initialized correctly.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Fail to Open INTERRUPT Pin: {ex}");
            }            
        }

        public void InitGPIOControlPin(DEVICE device)
        {
            try
            {
                device.IoControlPin = IoController.OpenPin(device.IoControlPinID);
                if (device.IoControlPin == null)
                {
                    return;
                }
                device.IoControlPin.SetDriveMode(GpioPinDriveMode.Output);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Fail to Open CONTROL Pin: {ex}");
            }
        }
    }
}
Device.csC#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Gpio;
using Windows.Devices.I2c;
using Windows.Devices.SerialCommunication;
using Windows.Devices.Spi;
using Windows.Storage.Streams;

namespace IoTController
{
    public enum I2CPortID { I2C0, I2C1 };

    abstract class DEVICE
    {
        public DEVICE()
        {
            this.DeviceName = "Device Name";
            this.DeviceID = 0;
            this.DeviceDescription = " Device Description";
            this.DeviceAvailable = false;
        }

        #region Device Info

        public int DeviceID
        {
            get; set;
        }

        public string DeviceDescription
        {
            get; set;
        }

        public string DeviceName
        {
            get; set;
        }

        public bool DeviceAvailable
        {
            get; set;
        }
        #endregion

        #region SPI-Communication
        public SpiDevice SPICommunication
        {
            get; set;
        }

        public void SPIWriteByte(byte regAddr, byte data)
        {
            byte[] buffer = new byte[2];
            buffer[0] = regAddr;
            buffer[1] = data;
            SPICommunication.Write(buffer);
        }
        #endregion

        #region I2C Communication

        public I2CPortID I2CPort
        {
            get; set;
        }

        public byte I2C_ADDRESS
        {
            get; set;
        }

        public I2cDevice I2cCommunication
        {
            get; set;
        }

        byte[] i2CWriteByte_writeBuffer = new byte[2];
        public void I2CWriteByte(byte regAddr, byte data)
        {
            i2CWriteByte_writeBuffer[0] = regAddr;
            i2CWriteByte_writeBuffer[1] = data;
            I2cCommunication.Write(i2CWriteByte_writeBuffer);
        }

        byte[] i2cReadByte_writeBuffer = new byte[1];
        byte[] i2cReadByte_readBuffer = new byte[1];
        public byte I2CReadByte(byte regAddr)
        {
            i2cReadByte_writeBuffer[0] = regAddr;
            I2cCommunication.WriteRead(i2cReadByte_writeBuffer, i2cReadByte_readBuffer);
            return i2cReadByte_readBuffer[0];
        }

        #endregion

        #region Serial Communication- UART

        public SerialDevice UARTCommunication
        {
            get; set;
        }

        public string UARTPort
        {
            get; set;
        }

        public uint UARTBaudRate
        {
            get; set;
        }

        public int UARTWriteTimeout
        {
            get; set;
        }

        public int UARTReadTimeout
        {
            get; set;
        }

        public DataWriter UARTDataWriteObject
        {
            get; set;
        }
        public DataReader UARTDataReaderObject
        {
            get; set;
        }
        #endregion

        #region GPIO

        public int IoInterruptPinID
        {
            get; set;
        }

        public int IoControlPinID
        {
            get; set;
        }

        public GpioPin IoInterruptPin
        {
            get; set;
        }

        public GpioPin IoControlPin
        {
            get; set;
        }
        #endregion
    }
}
SHT21.csC#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.I2c;

namespace IoTController
{
    class SHT21 : DEVICE
    {

        private byte[] Reg_SHT21_TEMP_HOLD_CMD = new byte[] { SHT21_I2C_REG_TEMP_HOLD_CMD }; /* Register address we want to read from */
        private byte[] Read_SHT21_Temperature_Buf = new byte[3];

        private byte[] Reg_SHT21_HUMIDITY_HOLD_CMD = new byte[] { SHT21_I2C_REG_HUMIDITY_HOLD_CMD }; /* Register address we want to read from */
        private byte[] Read_SHT21_Humidity_Buf = new byte[3];
        private ushort temperature_RAW, humidity_RAW;

        // Contructor
        public SHT21()
        {
            DeviceName = "SHT21";
            DeviceID = 21;
            DeviceDescription = "Temperature Sensor";
            DeviceAvailable = true;

            I2C_ADDRESS = SHT21_I2C_ADDR;
            temperature_RAW = humidity_RAW = 0;

            var now = DateTime.Now;
            Debug.WriteLine(now + " : " + " Temperature Sensor Default CONSTRUCTOR");
        }

        private ushort I2CReadHumidityRAWSHT21()
        {
            try
            {
                I2cCommunication.Write(Reg_SHT21_HUMIDITY_HOLD_CMD);
                I2cCommunication.Read(Read_SHT21_Humidity_Buf);
                humidity_RAW = (ushort)((Read_SHT21_Humidity_Buf[0] << 8 | Read_SHT21_Humidity_Buf[1]) & 0xFFFC); //humidity_RAW = (ushort)(humidity_RAW & 0xFFFC);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Failed to read HUMIDITY from SHT21: " + ex.Message);
            }

            return humidity_RAW;
        }
        private ushort I2CReadTemperatureRAWSHT21()
        {
            try
            {
                I2cCommunication.Write(Reg_SHT21_TEMP_HOLD_CMD);
                I2cCommunication.Read(Read_SHT21_Temperature_Buf);
                temperature_RAW = (ushort)((Read_SHT21_Temperature_Buf[0] << 8 | Read_SHT21_Temperature_Buf[1]) & 0xFFFC); //temperature_RAW = (ushort)(temperature_RAW & 0xFFFC); //ushort temp = 0xFFFC; 
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Failed to read TEMPERATURE from SHT21: " + ex.Message);
            }

            return temperature_RAW;
        }

        public int GetHumidity_RAW
        {
            get
            {
                //humidity_RAW = I2CReadTemperatureRAWSHT21();
                return I2CReadHumidityRAWSHT21();
            }
            //set;
        }

        public double GetHumidity
        {
            get
            {
                return -6.0 + 125.0 / 65536.0 * GetHumidity_RAW;
            }
        }

        public int GetTemperature_RAW
        {
            get
            {
                //temperature_RAW = I2CReadTemperatureRAWSHT21();
                return I2CReadTemperatureRAWSHT21();
            }
            //set;
        }

        public double GetTemperature
        {
            get
            {
                return -46.85 + 175.72 / 65536.0 * GetTemperature_RAW;
            }
        }


        // ===============================================================================================
        private const byte SHT21_I2C_ADDR = 0x40;
        private const byte SHT21_I2C_REG_TEMP_HOLD_CMD = 0xE3;
        private const byte SHT21_I2C_REG_HUMIDITY_HOLD_CMD = 0xE5;
        private const byte SHT21_I2C_REG_TEMP_NO_HOLD_CMD = 0xF3;
        private const byte SHT21_I2C_REG_HUMIDITY_NO__HOLD_CMD = 0xF5;

       

      
    }
}

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Using Android Phone as Raspberry Pi's Display
Easy
  • 95
  • 3

Full instructions

Using Android Phone as Raspberry Pi's display via SSH through VNC Viewer.

Controlling Raspberry Pi's Terminal using Android Phone
Easy
  • 371
  • 6

Full instructions

Controlling the terminal window of the Raspberry Pi 3 using Android Phone via SSH.

Getting Started with BBC Micro:Bit
Easy
  • 278
  • 8

Full instructions

This tutorial will show you the basics to get started with BBC micro bit.

PIR Motion Sensor with Raspberry Pi
Easy
  • 473
  • 9

Full instructions

Quick project to interface PIR sensor to Raspberry Pi.

SMART HOME SECURITY SYSTEM
Easy
  • 1,977
  • 14

Full instructions

Detects intrusion and notifies house owner. The owner remotely watches the house and if any theft is suspected will turn on the buzzer.

Boost Your Google Home With Prota OS for RPi
Easy
  • 1,670
  • 8

Full instructions

Extend your Google Home features to smart light, smart speakers, smart cam and smart appliances with those DIY tricks based on Raspberry Pi.

ProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login
Feedback