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

Physical Computing - Scratch 2.0 for Raspberry Pi
Easy
  • 157
  • 5

Full instructions

This is my 3rd tutorial with a focus on Scratch and Physical Computing using RPi. Here we will explore the new version of Scratch, the 2.0.

Break your heart - IoT Project - IoT Blocky
Easy
  • 70
  • 2

Full instructions

Using this project to control the LEDs on the Raspberry Pi Sense HAT

Hey Mycroft, Where Is the International Space Station?
Easy
  • 1,909
  • 37

Full instructions

Developing my first skill with the Mycroft.ai open source voice assistant on a Raspberry Pi 3 - aka Picroft!

Break your heart - IoT Project - Blinky - 2 LEDs
Easy
  • 23
  • 1

Full instructions

The Blinky project with two leds

Break your heart - IoT Project - Hello World
Easy
  • 34
  • 1

Full instructions

Hello World sample

Break your heart - IoT Project - Blinky
Easy
  • 41
  • 1

Full instructions

Break your heart project with IoT project: Blinky app!!!!!!!!!!!

Sign up / LoginProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlog