private static void Scan(I2cBus twi) { char keyChar; do { Console.Clear(); keyChar = Console.KeyAvailable ? Console.ReadKey().KeyChar : ' '; // Scan for (int i = 3; i < 127; i++) { twi.Start(); var result = twi.SendDeviceAddrAndCheckACK((byte)i, false); if (result) { Console.WriteLine($"I2C Address {i,3} 0x{i:x}"); } twi.Stop(); } Console.WriteLine("Press x to exit"); Thread.Sleep(1000); } while (keyChar != 'x'); Console.ReadKey(); }
public static void Main(string[] args) { Console.WriteLine(FtdiInventory.DeviceListInfo()); var ftDeviceInfo = FtdiInventory.GetDevices(); if (ftDeviceInfo.Length == 0) { Console.WriteLine("No Device"); Console.ReadKey(); return; } var firstSerial = ftDeviceInfo.FirstOrDefault().SerialNumber; MpsseDevice.MpsseParams mpsseParams = new MpsseDevice.MpsseParams { Latency = 16, ReadTimeout = 50, WriteTimeout = 50, clockDevisor = 49 * 6 }; using (MpsseDevice mpsse = new FT232H(firstSerial, mpsseParams)) { Console.WriteLine("MPSSE init success with clock frequency {0:0.0} Hz", mpsse.ClockFrequency); var i2c = new I2cBus(mpsse); var gpio = new Gpio(mpsse); Selector(i2c, gpio); } }
public Pca9685(I2cBus twi, byte i2cAddress, float pwmFrequency) : base(twi, i2cAddress) { PwmFrequency = pwmFrequency; Reset(); SetPwmFreq(PwmFrequency); Reset(); }
/// <summary> /// Create a new TMP102 object using the default configuration for the sensor. /// </summary> /// <param name="address">I2C address of the sensor.</param> /// <param name="speed">Speed of the communication with the sensor.</param> public TMP102(byte address = 0x48, ushort speed = 100, ushort updateInterval = MinimumPollingPeriod, float temperatureChangeNotificationThreshold = 0.001F) { if ((speed < 10) || (speed > 1000)) { throw new ArgumentOutOfRangeException(nameof(speed), "Speed should be 10 KHz to 3,400 KHz."); } if (temperatureChangeNotificationThreshold < 0) { throw new ArgumentOutOfRangeException(nameof(temperatureChangeNotificationThreshold), "Temperature threshold should be >= 0"); } if ((updateInterval != 0) && (updateInterval < MinimumPollingPeriod)) { throw new ArgumentOutOfRangeException(nameof(updateInterval), "Update period should be 0 or >= than " + MinimumPollingPeriod); } TemperatureChangeNotificationThreshold = temperatureChangeNotificationThreshold; _updateInterval = updateInterval; _tmp102 = new I2cBus(address, speed); var configuration = _tmp102.ReadRegisters(0x01, 2); _sensorResolution = (configuration[1] & 0x10) > 0 ? Resolution.Resolution13Bits : Resolution.Resolution12Bits; if (updateInterval > 0) { StartUpdating(); } else { Update(); } }
private static void ArduinoSlave(I2cBus i2c) { var twi = new TwoWireBase(i2c, 0x08); byte[] array = Encoding.ASCII.GetBytes("Lech The Best\n"); Console.WriteLine($"{array} is {array.Length} long"); char keyChar1 = ' '; do { if (Console.KeyAvailable) { keyChar1 = Console.ReadKey().KeyChar; } var ret0 = twi.ReadBytes(0x00, 6); Console.WriteLine($"Recesived0 {BitConverter.ToString(ret0, 0)} as {Encoding.ASCII.GetString(ret0)}"); var ret1 = twi.ReadBytes(6); Console.WriteLine($"Recesived1 {BitConverter.ToString(ret1, 0)} as {Encoding.ASCII.GetString(ret1)}"); var ret2 = twi.ReadBytes(0x0102, 6); Console.WriteLine($"Recesived2 {BitConverter.ToString(ret2, 0)} as {Encoding.ASCII.GetString(ret2)}"); var ret3 = (char)twi.ReadByte(0x01); Console.WriteLine($"ReadByte {ret3}"); var ret4 = (char)twi.ReadByte(0x0102); Console.WriteLine($"ReadByte {ret4}"); // twi.WriteBytes(0x41, array); // foreach (var letter in array) // { // twi.WriteByte(0x41, (byte)letter); // } //var b = twi.ReadByte(0x00); //Console.WriteLine(b); // var list = new List<char>(); // twi.Twi.Start(); // twi.Twi.SendDeviceAddrAndCheckACK(0x08, true); // //var read = twi.Twi.ReadNBytes(6); // // for (int i = 0; i < 6; i++) // { // var r = twi.Twi.ReceiveByte(true); // list.Add((char)r); // } // // twi.Twi.Stop(); //Console.WriteLine($"Recesived {BitConverter.ToString(read, 0)}"); //Console.WriteLine($"Recesived {String.Join("", list)}"); Thread.Sleep(1000); } while (keyChar1 != 'x'); Console.ReadKey(); return; }
/// <summary> /// Create a new instance of the TSL2561 class with the specified I2C address. /// </summary> /// <remarks> /// By default the sensor will be set to low gain. /// <remarks> /// <param name="address">I2C address of the TSL2561</param> /// <param name="speed">Speed of the I2C bus (default = 100 KHz).</param> /// <param name="updateInterval">Update interval for the sensor (in milliseconds).</param> /// <param name="lightLevelChangeNotificationThreshold">Changes in light level greater than this value will generate an interrupt in auto-update mode.</param> public TSL2561(byte address = (byte)Addresses.Default, ushort speed = 100, ushort updateInterval = MinimumPollingPeriod, float lightLevelChangeNotificationThreshold = 10.0F) { if ((address != (byte)Addresses.Address0) && (address != (byte)Addresses.Default) && (address != (byte)Addresses.Address1)) { throw new ArgumentOutOfRangeException(nameof(address), "Address should be 0x29, 0x39 or 0x49."); } if (speed > 1000) { throw new ArgumentOutOfRangeException(nameof(speed), "Speed should be between 0 and 1000 KHz"); } if (lightLevelChangeNotificationThreshold < 0) { throw new ArgumentOutOfRangeException(nameof(lightLevelChangeNotificationThreshold), "Light level threshold change values should be >= 0"); } LightLevelChangeNotificationThreshold = lightLevelChangeNotificationThreshold; _updateInterval = updateInterval; var device = new I2cBus(address, speed); _tsl2561 = device; // // Wait for the sensor to prepare the first reading (402ms after power on). // Thread.Sleep(410); if (updateInterval > 0) { StartUpdating(); } else { Update(); } }
public ADS1115(I2cBus i2c, byte address) : base(i2c, address) { ConversionDelay = ADS1115_CONVERSIONDELAY; BitShift = 0; Gain = AdsGain.GAIN_TWOTHIRDS; /* +/- 6.144V range (limited to VDD +0.3V max!) */ }
public Tcs34725(I2cBus i2c, byte address, Tcs34725IntegrationTime it, Tcs34725Gain gain) : base(i2c, address) { _tcs34725Initialised = false; _tcs34725IntegrationTime = it; _tcs34725Gain = gain; }
public static Bme280 CreateBme280(I2cBus i2cBus) { var bme280 = new Bme280(i2cBus.CreateDevice(Bme280.DefaultI2cAddress)); SetupBme280(bme280); return(bme280); }
private static void Ads1115(I2cBus i2c) { var ads1115 = new ADS1115(i2c, 0x4A); char keyChar = ' '; do { if (Console.KeyAvailable) { keyChar = Console.ReadKey().KeyChar; } var ch0 = ads1115.ReadAdcSingleEnded(0); Thread.Sleep(10); var ch1 = ads1115.ReadAdcSingleEnded(1); Thread.Sleep(10); var v0 = ads1115.ConvertToVoltage(ch0); var v1 = ads1115.ConvertToVoltage(ch1); Console.WriteLine($"v0 {v0:F3} {ch0} v1 {v1:F3} {ch1}"); Thread.Sleep(300); } while (keyChar != 'x'); }
/// <inheritdoc/> public void Dispose() { if (_shouldDispose) { _i2cBus?.Dispose(); } else { LedMatrix?.Dispose(); LedMatrix = null !; Joystick?.Dispose(); Joystick = null !; Gyroscope?.Dispose(); Gyroscope = null !; Magnetometer?.Dispose(); Magnetometer = null !; TemperatureAndHumidity?.Dispose(); TemperatureAndHumidity = null !; PressureAndTemperature?.Dispose(); PressureAndTemperature = null !; } _i2cBus = null !; }
/// <summary> /// Create a new GroveTH02 object using the default parameters for the component. /// </summary> /// <param name="address">Address of the Grove TH02 (default = 0x4-).</param> /// <param name="speed">Speed of the I2C bus (default = 100 KHz).</param> /// <param name="updateInterval">Number of milliseconds between samples (0 indicates polling to be used)</param> /// <param name="humidityChangeNotificationThreshold">Changes in humidity greater than this value will trigger an event when updatePeriod > 0.</param> /// <param name="temperatureChangeNotificationThreshold">Changes in temperature greater than this value will trigger an event when updatePeriod > 0.</param> public GroveTH02(byte address = 0x40, ushort speed = 100, ushort updateInterval = MinimumPollingPeriod, float humidityChangeNotificationThreshold = 0.001F, float temperatureChangeNotificationThreshold = 0.001F) { I2cBus device = new I2cBus(address, speed); _groveTH02 = (ICommunicationBus)device; if (humidityChangeNotificationThreshold < 0) { throw new ArgumentOutOfRangeException(nameof(humidityChangeNotificationThreshold), "Humidity threshold should be >= 0"); } if (humidityChangeNotificationThreshold < 0) { throw new ArgumentOutOfRangeException(nameof(temperatureChangeNotificationThreshold), "Temperature threshold should be >= 0"); } TemperatureChangeNotificationThreshold = temperatureChangeNotificationThreshold; HumidityChangeNotificationThreshold = humidityChangeNotificationThreshold; _updateInterval = updateInterval; if (updateInterval > 0) { StartUpdating(); } else { Update(); } }
/// <inheritdoc/> public void Dispose() { if (_shouldDispose) { _i2cBus?.Dispose(); } else { _ledMatrix?.Dispose(); _ledMatrix = null !; _joystick?.Dispose(); _joystick = null !; _gyro?.Dispose(); _gyro = null !; _mag?.Dispose(); _mag = null !; _temp?.Dispose(); _temp = null !; _press?.Dispose(); _press = null !; } _i2cBus = null !; }
/// <summary> /// Creates an instance of an I2C bus, given the pins used for that bus /// </summary> /// <param name="board">The board that provides this bus</param> /// <param name="bus">The bus number</param> /// <param name="pins">The pins, in the logical scheme of the board. This must be an array of exactly two pins (for SCL and SDA)</param> /// <param name="busInstance">The wrapped bus instance</param> public I2cBusManager(Board board, int bus, int[]?pins, I2cBus busInstance) { if (pins == null || pins.Length != 2) { throw new ArgumentException("Must provide a valid set of 2 pins", nameof(pins)); } _board = board; _bus = bus; _busInstance = busInstance ?? throw new ArgumentNullException(nameof(busInstance)); _devices = new Dictionary <int, I2cDevice>(); _sdaPin = pins[0]; _sclPin = pins[1]; try { _board.ReservePin(_sdaPin, PinUsage.I2c, this); _board.ReservePin(_sclPin, PinUsage.I2c, this); } catch (Exception) { _board.ReleasePin(_sdaPin, PinUsage.I2c, this); _board.ReleasePin(_sclPin, PinUsage.I2c, this); throw; } }
private static void Tcs34725(I2cBus i2c) { var tcs = new Tcs34725.Tcs34725(i2c, Tcs34725IntegrationTime.TCS34725_INTEGRATIONTIME_50MS, Tcs34725Gain.TCS34725_GAIN_16X); tcs.Init(); bool even = false; char keyChar = ' '; do { if (Console.KeyAvailable) { keyChar = Console.ReadKey().KeyChar; } tcs.Enable(); tcs.GetData(); tcs.Disable(); ConsoleColorChanger.SetColor(System.ConsoleColor.Blue, tcs.Red, tcs.Green, tcs.Blue); Console.ForegroundColor = System.ConsoleColor.Blue; Console.WriteLine(tcs); Thread.Sleep(300); } while (keyChar != 'x'); }
private static void Mcp4725(I2cBus i2c) { var mcp = new Mcp4725.Mcp4725(i2c); var ads1115 = new ADS1115(i2c, 0x4A); char keyChar = ' '; UInt16 outVar = 0; do { if (Console.KeyAvailable) { keyChar = Console.ReadKey().KeyChar; if (keyChar == '+') { outVar += 10; } if (keyChar == '-') { outVar -= 10; } } mcp.SetVoltage(outVar, false); var ch0 = ads1115.ReadAdcSingleEnded(0); Thread.Sleep(10); var v0 = ads1115.ConvertToVoltage(ch0); Console.WriteLine($"OutVar {outVar} In {v0}"); Thread.Sleep(300); } while (keyChar != 'x'); }
private static void Roboter(I2cBus i2c) { var pca9685 = new Pca9685.Pca9685(i2c, 0x40, 50); var axis1 = new ServoAxis(0, pca9685, 158, 529); // Savöx var axis2 = new ServoAxis(1, pca9685, 172, 519); // Spektrum var axis3 = new ServoAxis(2, pca9685, 126, 528); // Tower // var axis4 = new ServoAxis(3, pca9685, 150, 650); // var axis5 = new ServoAxis(4, pca9685, 150, 650); // var axis6 = new ServoAxis(5, pca9685, 150, 650); var ads1115 = new ADS1115(i2c, 0x4A); var ctrl = new XInputController(UserIndex.One); if (!ctrl.IsConnected) { Console.WriteLine("No Controller Conected"); Console.ReadKey(); return; } ctrl.StartAutoUpdate(); ctrl.ButtonPressed += axis3.OnButtonPressed; ctrl.Updated += axis1.OnUpdate; char keyChar = ' '; do { if (Console.KeyAvailable) { keyChar = Console.ReadKey().KeyChar; } Console.Clear(); if (ctrl.A) { axis1.MoveAbsolute(ctrl.LeftThumbX); axis2.MoveAbsolute(ctrl.LeftThumbY); } else { var ch0 = ads1115.ReadAdcSingleEnded(0); var ch1 = ads1115.ReadAdcSingleEnded(1); var pot0 = ads1115.Normalize(ch0); var pot1 = ads1115.Normalize(ch1); axis1.MoveAbsolute(pot0); axis2.MoveAbsolute(pot1); } //axis2.MoveAbsolute(ctrl.LeftThumbY); axis3.MoveAbsolute(ctrl.RightThumbY); // axis4.MoveAbsolute(ctrl.RightThumbX); // axis5.MoveAbsolute(ctrl.LeftTrigger); // axis6.MoveAbsolute(ctrl.RightTrigger); } while (!ctrl.Start && keyChar != 'x'); }
public void I2C_I2cBus_Bme280CanRead() { using (I2cBus i2cBus = CreateI2cBusForBme280()) using (Bme280 bme280 = CreateBme280(i2cBus)) { TestBme280Reading(bme280); } }
/// <summary> /// Create a new AT24Cxx object using the default parameters for the component. /// </summary> /// <param name="address">Address of the MAG3110 (default = 0x50).</param> /// <param name="speed">Speed of the I2C bus (default = 400 KHz).</param> /// <param name="pageSize">Number of bytes in a page (default = 32 - AT24C32).</param> /// <param name="memorySize">Total number of bytes in the EEPROM (default = 8192 - AT24C32).</param> public AT24Cxx(byte address = 0x50, ushort speed = 10, ushort pageSize = 32, ushort memorySize = 8192) { var device = new I2cBus(address, speed); _eeprom = device; _pageSize = pageSize; _memorySize = memorySize; }
/// <summary> /// Create a new SI1145 sensor object. /// </summary> /// <param name="address">Address of the chip on the I2C bus (default to 0x60).</param> /// <param name="speed">Communication speed (default to 400 KHz).</param> public SI1145(byte address = 0x60, ushort speed = 400) { I2cBus device = new I2cBus(address, speed); _si1145 = (ICommunicationBus)device; if (_si1145.ReadRegister(Registers.PartID) != 0x45) { throw new Exception("Invalid part ID"); } }
private static void AddressOrReset() { Console.WriteLine("Enter 1 or 2 to select a mode:\n1. Change address.\n2. Reset chip."); if (int.TryParse(Console.ReadLine(), out int mode)) { switch (mode) { case 1: { Console.WriteLine("Enter a new address:"); if (ushort.TryParse(Console.ReadLine(), out ushort address)) { _expander.ChangeAddress(address); Console.WriteLine("Change address."); _expander.SaveAddress(); #if WIRING_PI _expander = Pi.I2C.GetGpioExpander(); #endif #if NOT_WIRING_PI _expander = I2cBus.Create(1).GetGpioExpander(); #endif Console.WriteLine("Save address."); } else { Console.WriteLine("Invalid new address value."); } break; } case 2: { _expander.Reset(); Console.WriteLine("Reset chip."); break; } default: { Console.WriteLine("Invalid mode value."); break; } } } }
private static void GpioTest(I2cBus i2c, Gpio gpio) { var timer = new System.Timers.Timer(); timer.Interval = 5; timer.Elapsed += (sender, args) => { gpio.Out0 = !gpio.Out0; gpio.Multiplex(); gpio.SetLowGpio(); }; timer.AutoReset = true; timer.Enabled = true; char keyChar = ' '; do { if (Console.KeyAvailable) { keyChar = Console.ReadKey().KeyChar; if (keyChar == '1') { gpio.Out0 = false; } if (keyChar == '2') { gpio.Out0 = true; } if (keyChar == '3') { gpio.Out1 = false; } if (keyChar == '4') { gpio.Out1 = true; } if (keyChar == '5') { gpio.Out2 = false; } if (keyChar == '6') { gpio.Out2 = true; } } Thread.Sleep(2); } while (keyChar != 'x'); }
/// <summary> /// Create a new MAG3110 object using the default parameters for the component. /// </summary> /// <param name="address">Address of the DS3231 (default = 0x68).</param> /// <param name="speed">Speed of the I2C bus (default = 100 KHz).</param> /// <param name="interruptPort">Digital port connected to the alarm interrupt pin on the RTC.</param> // TODO: revisit; `DigitalPin.Empty`? public DS3231(IDigitalInputPort interruptPort, byte address = 0x68, ushort speed = 100) { _ds323x = new I2cBus(address, speed); // TODO: i changed this from GPIO_NONE // samples will need to pass null if (interruptPort != null) { InterruptPin = interruptPort; } }
public static GpioExpander GetGpioExpander(this I2cBus bus, int address = GpioExpander.DefaultAddress) { if (bus is null) { throw ThrowHelper.ArgumentNullException(nameof(bus)); } if (address is < 0 or > 127) { throw ThrowHelper.ArgumentOutOfRangeException(nameof(address), address); } return(new RaspberryPiExpander(bus.CreateDevice(address))); }
/// <summary> /// Constructs SenseHat instance /// </summary> public SenseHat(I2cBus?i2cBus = null, bool shouldDispose = false) { _shouldDispose = shouldDispose || i2cBus == null; _i2cBus = i2cBus ?? I2cBus.Create(DefaultI2cBusId); Debug.Assert(SenseHatLedMatrixI2c.I2cAddress == SenseHatJoystick.I2cAddress, $"Default addresses for {nameof(SenseHatLedMatrixI2c)} and {nameof(SenseHatJoystick)} were expected to be the same"); I2cDevice joystickAndLedMatrixI2cDevice = _i2cBus.CreateDevice(SenseHatLedMatrixI2c.I2cAddress); _ledMatrix = new SenseHatLedMatrixI2c(joystickAndLedMatrixI2cDevice); _joystick = new SenseHatJoystick(joystickAndLedMatrixI2cDevice); _gyro = new SenseHatAccelerometerAndGyroscope(_i2cBus.CreateDevice(SenseHatAccelerometerAndGyroscope.I2cAddress)); _mag = new SenseHatMagnetometer(_i2cBus.CreateDevice(SenseHatMagnetometer.I2cAddress)); _temp = new SenseHatTemperatureAndHumidity(_i2cBus.CreateDevice(SenseHatTemperatureAndHumidity.I2cAddress)); _press = new SenseHatPressureAndTemperature(_i2cBus.CreateDevice(SenseHatPressureAndTemperature.I2cAddress)); }
/// <summary> /// Create an I2C device instance on a default bus. /// </summary> /// <param name="connectionSettings">Connection parameters (contains I2C address and bus number)</param> /// <returns>An I2C device instance</returns> /// <remarks>This method can only be used for bus numbers where the corresponding pins are hardwired /// (i.e. bus 0 and 1 on the Raspi always use pins 0/1 and 2/3)</remarks> public I2cDevice CreateI2cDevice(I2cConnectionSettings connectionSettings) { Initialize(); // Returns logical pin numbers for the selected bus (or an exception if using a bus number > 1, because that // requires specifying the pins) if (_i2cBuses.TryGetValue(connectionSettings.BusId, out var bus)) { return(bus.CreateDevice(connectionSettings.DeviceAddress)); } int[] pinAssignment = GetDefaultPinAssignmentForI2c(connectionSettings.BusId); I2cBus newBus = CreateOrGetI2cBus(connectionSettings.BusId, pinAssignment); return(newBus.CreateDevice(connectionSettings.DeviceAddress)); }
public static void SetFrequency(this I2cBus device, uint frequency) { var fields = typeof(I2cBus).GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.SetField | System.Reflection.BindingFlags.NonPublic); for (int index = 0; index < fields.Length; index++) { if (fields[index].Name.Contains("Frequency")) { fields[index].SetValue(device, frequency); return; } } }
public void OpenCloseTest() { MpsseDevice.MpsseParams mpsseParams = new MpsseDevice.MpsseParams { Latency = 16, ReadTimeout = 50, WriteTimeout = 50, clockDevisor = 49 * 6 }; using (MpsseDevice mpsse = new FT232H(FtdiHelper.GetFirstSerial(), mpsseParams)) { Console.WriteLine("MPSSE init success with clock frequency {0:0.0} Hz", mpsse.ClockFrequency); var i2c = new I2cBus(mpsse); } }
/// <summary> /// Create a new MPL3115A2 object with the default address and speed settings. /// </summary> /// <param name="address">Address of the sensor (default = 0x60).</param> /// <param name="speed">Bus speed to use when communicating with the sensor (Maximum is 400 kHz).</param> /// <param name="updateInterval">Number of milliseconds between samples (0 indicates polling to be used)</param> /// <param name="temperatureChangeNotificationThreshold">Changes in temperature greater than this value will trigger an event when updatePeriod > 0.</param> /// <param name="pressureChangedNotificationThreshold">Changes in pressure greater than this value will trigger an event when updatePeriod > 0.</param> public MPL3115A2(byte address = 0x60, ushort speed = 400, ushort updateInterval = MinimumPollingPeriod, float temperatureChangeNotificationThreshold = 0.001F, float pressureChangedNotificationThreshold = 10.0F) { if ((speed < 10) || (speed > 1000)) { throw new ArgumentOutOfRangeException(nameof(speed), "Speed should be 10 KHz to 3,400 KHz."); } if (temperatureChangeNotificationThreshold < 0) { throw new ArgumentOutOfRangeException(nameof(temperatureChangeNotificationThreshold), "Temperature threshold should be >= 0"); } if (pressureChangedNotificationThreshold < 0) { throw new ArgumentOutOfRangeException(nameof(pressureChangedNotificationThreshold), "Pressure threshold should be >= 0"); } if ((updateInterval != 0) && (updateInterval < MinimumPollingPeriod)) { throw new ArgumentOutOfRangeException(nameof(updateInterval), "Update period should be 0 or >= than " + MinimumPollingPeriod); } TemperatureChangeNotificationThreshold = temperatureChangeNotificationThreshold; PressureChangeNotificationThreshold = pressureChangedNotificationThreshold; _updateInterval = updateInterval; var device = new I2cBus(address, speed); _mpl3115a2 = device; if (_mpl3115a2.ReadRegister(Registers.WhoAmI) != 0xc4) { throw new Exception("Unexpected device ID, expected 0xc4"); } _mpl3115a2.WriteRegister(Registers.Control1, (byte)(ControlRegisterBits.Active | ControlRegisterBits.OverSample128)); _mpl3115a2.WriteRegister(Registers.DataConfiguration, (byte)(ConfigurationRegisterBits.DataReadyEvent | ConfigurationRegisterBits.EnablePressureEvent | ConfigurationRegisterBits.EnableTemperatureEvent)); if (updateInterval > 0) { StartUpdating(); } else { Update(); } }
private static void At24c32(I2cBus i2c) { var at = new AT24C32(i2c, 0x50); at.WriteByte((ushort)10, 0x42); Thread.Sleep(10); var ret = at.ReadByte((ushort)10); Console.WriteLine($"ret {ret:x}"); at.WriteBytes(10, new byte[] { 0, 8, 15 }); Thread.Sleep(10); var result = at.ReadBytes((ushort)10, 3); var disp = BitConverter.ToString(result); Console.WriteLine(disp); }