The new TinyCLR and I2C

I had some spare time (Ya… like I always have at my age)

I was having a bit of a problem with I2C and I found some old code by GHI and it got me brain working again.
Posting for anybody that needs something to get them started.

Nothing pretty but it worked!



/* 
 Based on GHI Electronics Source Code
 ghi_elect-gadgeteer-5c8596ffc9f6.zip
 TempHumidSI70_43.cs (namespace Gadgeteer.Modules.GHIElectronics)

 Using a USB FTDI 3.3V cable for serial. (PC using Tera Term)
 Pin
 1 Black Ground To 8 pin header GND(Arrow Mark on connector)
 2 Brown CTS# (Not used)
 3 Red VCC(+5V) (Not used)
 4 Orange TXD To 8 pin header COM1 RX <--- 8 pin header D0 COM1
 5 Yellow RXD To 8 pin header COM1 TX <--- 8 pin header D1 COM1
 6 Green  RTS# (Not used)
 
 Using a Panda III 
 Using a TempHumid SI70 Gadgeteer Module and Breakout Module

 Breakout pin Gnd to Panda III Gnd
 Breakout pin 3V3 to Panda III 3V3
 Breakout pin P4 to Panda III 8 Pin Header D3 (I2C_SCL)
 Breakout pin P5 to Panda III 8 Pin Header D2 (I2C_SDA)

 PB7/I2C1/SDA Cpu Pin 93 - X2 8 pin header Pin 3 - D2
 PB6/I2C1/SCL Cpu Pin 92 - X2 8 pin header Pin 4 - D3

*/

using System;
using System.Threading;
using GHIElectronics.TinyCLR.Pins;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.I2c;
using GHIElectronics.TinyCLR.Devices.Enumeration;

using GTC_DS = GHIElectronics.TinyCLR.Devices.SerialCommunication;
using GTC_SS = GHIElectronics.TinyCLR.Storage.Streams;


namespace TinyCLR_I2C_Test
{
    public class Program
    {
        private static bool loop = true;

        // On board LED
        public static GpioPin LED4; //Red PE9/PWM0

        // I2C1
        private static I2cDevice I2c;
        public static GpioPin SCL;
        public static GpioPin SDA;

        // Serial
        private static GTC_DS.SerialDevice _com1;
        private static GTC_SS.IOutputStream _outStream;
        private static GTC_SS.IInputStream _inStream;
        private static char[] charsToTrim = { '-', '0' };

        private static GTC_SS.Buffer _Serialmsgbuffer;
        private static GTC_SS.Buffer _Serialreadbuffer;
        //

        // * Slave address *
        private static byte I2C_ADDRESS = 0x40; // Dec. 64 Bin. ‭01000000‬

        // * Measure Relative Humidity, Clock stretching (Hold Master Mode) *
        private static byte MEASURE_HUMIDITY_HOLD = 0xE5; // Dec. 229 ‭Bin. 1110 0101‬

        // * Read Temperature Value from Previous RH Measurement *
        private static byte READ_TEMP_FROM_PREVIOUS = 0xE0; // Dec. 224 Bin. ‭1110 0000‬

        // Measure Relative Humidity, No Hold Master Mode
        //private static byte RH_NOHOLD = 0xF5; // Dec. 245 Bin. ‭1111 0101‬
        // Measure Temperature, Clock stretching (Hold Master Mode)
        //private static byte TEMP_HOLD = 0xE3; // Dec. 227 Bin. ‭1110 0011‬
        // Measure Temperature, No Hold Master Mode
        //private static byte TEMP_NOHOLD = 0xF3; // Dec. 243 Bin. ‭1111 0011‬
        // Reset
        //private static byte RESET = 0xFE; // Dec. 254 Bin. ‭1111 1110‬
        // Write RH/T User Register 1
        //private static byte WRITE_USER_REG = 0xE6; // Dec. 230 Bin. ‭1110 0110‬
        // Read RH/T User Register 1
        //private static byte READ_USER_REG = 0xE7; // Dec. 231 Bin. ‭1110 0111‬
        // Write Heater Control Register 0x51 // Dec. 81 Bin. ‭0101 0001‬
        // Read Heater Control Register 0x11 // Dec. 17 Bin. ‭0001 0001‬


        private static byte[] I2CwriteBuffer1;
        private static byte[] I2CwriteBuffer2;
        private static byte[] I2CreadBuffer1;
        private static byte[] I2CreadBuffer2;

        private static bool blink = false;

        public static void Main()
        {
            var gpio = GpioController.GetDefault();

            // PC Board Red LED  PE9/PWM0 CPU Pin 40
            LED4 = gpio.OpenPin(FEZPandaIII.Gpio.Led4); 
            LED4.SetDriveMode(GpioPinDriveMode.Output);

            // COM port using a USB FTDI 3.3V cable for serial. (PC using Tera Term)
            _com1 = GTC_DS.SerialDevice.FromId("COM1");
            _outStream = _com1.OutputStream;
            _inStream = _com1.InputStream;

            // Returns one I2C device and 4 SPI devices
            // Devices Returns [0] = "I2C1", [1] = "SPI1", [2] = "SPI2", [3] = "SPI3", [4] = "SPI4"
            var Devices = DeviceInformation.FindAll(FEZPandaIII.I2cBus.I2c1);

            // Device I2C1 Slave address
            I2cConnectionSettings Setting = new I2cConnectionSettings(I2C_ADDRESS);
            //Setting.BusSpeed = I2cBusSpeed.StandardMode; // 100kHz
            // Or
            Setting.BusSpeed = I2cBusSpeed.FastMode; // 400kHz

            I2c = I2cDevice.FromId(Devices[0].Id, Setting);

            SendMsg("\r\n Type a upper case Q to exit the while loop\r\n");
            SendMsg("\r\n Type a lower case t to read Temperature and RelativeHumidity\r\n");
            SendMsg("\r\n i2c.DeviceId Dec: " + I2c.ConnectionSettings.SlaveAddress.ToString() +
                " Hex: " + I2c.ConnectionSettings.SlaveAddress.ToString("X"));
            SendMsg("\r\n i2c.BusSpeed " + I2c.ConnectionSettings.BusSpeed.ToString());
            SendMsg("\r\n StandardMode = 0 - FastMode = 1\r\n");

            // Here we go
            while (loop)
            {
                ToggleLED();
                _Serialreadbuffer = new GTC_SS.Buffer(2);

                if (_inStream.Read(_Serialreadbuffer, _Serialreadbuffer.Capacity, GTC_SS.InputStreamOptions.None) > 0)
                {
                    byte[] b = _Serialreadbuffer.Data;
                    string stng = b.GetValue(0).ToString();

                    // Q ascii - 81 Dec , 51 Hex
                    // q ascii - 113 Dec , 71 Hex
                    if (stng == "81") // Is character received a uppercase Q?
                    {
                        SendMsg("\r\n !!! Upper case Q received. Exit while loop.");
                        SendMsg("\r\nReset the board.\r\n");
                        loop = false;
                    }
                    //
                    if (stng == "114") //Char r - 114 Dec , 0X72 Hex
                    {
                        //Read (Not used)
                        SendMsg("\r\n The r key was pressed\r\n");
                    }
                    //
                    if (stng == "119") //Char w - 119 Dec , 0x77 Hex
                    {
                        //Write (Not used)
                        SendMsg("\r\n The w key was pressed (write)\r\n");
                    }
                    //
                    //
                    if (stng == "116") //Char t - 119 Dec , 0x74 Hex
                    {
                        SendMsg("\r\n The t key was pressed - I2C test\r\n");
                        TempHumidity();
                    }
                    //
                }
                //

                Thread.Sleep(500);
            }
            // while

             SendMsg("\r\nExit while()\r\n");
        }
        // Main

        private static void TempHumidity()
        {

            I2CwriteBuffer1 = new byte[1] { MEASURE_HUMIDITY_HOLD }; //0xE5
            I2CwriteBuffer2 = new byte[1] { READ_TEMP_FROM_PREVIOUS }; //0xE0
            I2CreadBuffer1 = new byte[2];
            I2CreadBuffer2 = new byte[2];

            I2c.WriteRead(I2CwriteBuffer1, I2CreadBuffer1);
            Thread.Sleep(10);
            I2c.WriteRead(I2CwriteBuffer2, I2CreadBuffer2);

            int rawRH = I2CreadBuffer1[0] << 8 | I2CreadBuffer1[1];
            int rawTemp = I2CreadBuffer2[0] << 8 | I2CreadBuffer2[1];

            SendMsg("\r\n rawRH " + rawRH.ToString());
            SendMsg("\r\n rawTemp " + rawTemp.ToString() + "\r\n");

            double temperature = 175.72 * rawTemp / 65536.0 - 46.85;
            double relativeHumidity = 125.0 * rawRH / 65536.0 - 6.0;

            if (relativeHumidity < 0.0)
            {
                relativeHumidity = 0.0;
            }
            if (relativeHumidity > 100.0)
            {
                relativeHumidity = 100.0;
            }
            
            SendMsg("\r\n Celsius: " + temperature.ToString("F1"));
            SendMsg("\r\n Fahrenheit: " + (temperature * 1.8 + 32.0).ToString("F1"));
            SendMsg("\r\n RH: " + relativeHumidity.ToString("F1") + "\r\n");
        }
        //

        // PC Board Red LED
        private static void ToggleLED()
        {
            if (blink)
            {
                LED4.Write(GpioPinValue.High);
            }
            else
            {
                LED4.Write(GpioPinValue.Low);
            }
            //
            blink = !blink;
        }
        //

        private static void SendMsg(string theMsg)
        {
            // Send theMsg to the serial terminal.
            _Serialmsgbuffer = new GTC_SS.Buffer(System.Text.Encoding.UTF8.GetBytes(theMsg));
            _outStream.Write(_Serialmsgbuffer);
        }
        //

        private static byte[] GetBytes(string theMsg)
        {
            return System.Text.Encoding.UTF8.GetBytes(theMsg);
        }
        //

    } // Class
} // Namespace
//

Thanks GHI for the code!

2 Likes

I was going through this yesterday. Looks like Windows now has an easier way. We will be implementing it in TinyCLR in future releases. We will explain it as well.

1 Like

@ Gus - [quote]We will explain it as well[/quote]

On the 7th of next month?

1 Like

@ Gus - Did you choose March 7th because that was the day in 1876 that Bell got the patent for the telephone?

[url]https://www.ghielectronics.com/community/forum/topic?id=24044&page=10#msg224240[/url] 8) :slight_smile:

@ Gus -
March 7th …

New VS 2017 released then also?

I’m get so confused using VS2017. Well, back to school I guess.

@ Mike - [quote]Did you choose March 7th because that was the day in 1876 that Bell got the patent for the telephone[/quote]

…but of course.