/// <summary> /// Probes the specified I2C bus to discover any BH1750s attacked. /// </summary> /// <param name="i2c">The bus to probe</param> /// <param name="rate">The rate, in kHz</param> /// <returns></returns> public static async Task <IList <Bh1750> > ProbeAsync(I2C i2c, int rate = 100) { List <Bh1750> devs = new List <Bh1750>(); i2c.Enabled = true; bool oldExceptionsValue = TreehopperUsb.Settings.ThrowExceptions; TreehopperUsb.Settings.ThrowExceptions = true; try { var response = await i2c.SendReceiveAsync(0x23, null, 1).ConfigureAwait(false); devs.Add(new Bh1750(i2c, false, rate)); } catch (Exception) { } try { var response = await i2c.SendReceiveAsync(0x5C, null, 1).ConfigureAwait(false); devs.Add(new Bh1750(i2c, true, rate)); } catch (Exception) { } TreehopperUsb.Settings.ThrowExceptions = false; TreehopperUsb.Settings.ThrowExceptions = oldExceptionsValue; return(devs); }
/// <summary> /// Requests a reading from the sensor and updates its data properties with the gathered values. /// </summary> /// <returns>An awaitable Task</returns> /// <remarks> /// Note that when #AutoUpdateWhenPropertyRead is `true` (which it is, by default), this method is implicitly /// called when any sensor data property is read from --- there's no need to call this method unless you set /// AutoUpdateWhenPropertyRead to `false`. /// /// Unless otherwise noted, this method updates all sensor data simultaneously, which can often lead to more efficient /// bus usage (as well as reducing USB chattiness). /// </remarks> public async Task UpdateAsync() { var lsb = await i2c.SendReceiveAsync(0x38, null, 1).ConfigureAwait(false); var msb = await i2c.SendReceiveAsync(0x39, null, 1).ConfigureAwait(false); int val = msb[0] << 8 | lsb[0]; _uv = 5.0 * val / Math.Pow(2, (int)time - 1); // take into account the integration time PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Uv))); }
/// <summary> /// Construct a TLV493D-A1B6 3D magnetic / temperature sensor /// </summary> /// <param name="i2c"></param> /// <param name="address"></param> public Tlv493d(I2C i2c, byte address = 0x5E) { i2c.Enabled = true; this.i2c = i2c; this.address = address; // get the current data from the device var result = i2c.SendReceiveAsync(address, null, 10).Result; // set the config to Master-Controlled mode var dataToWrite = new byte[4]; dataToWrite[0] = 0x00; dataToWrite[1] = (byte)((result[7] & 0x18) | 0x03); // fastmode = 1, lp_mode = 1 dataToWrite[2] = result[8]; dataToWrite[3] = (byte)((result[9] & 0x1F) | 0x40); // LP = 1 -> 12 ms period Task.Run(() => i2c.SendReceiveAsync(address, dataToWrite, 0)).Wait(); }
/// <summary> /// Requests a reading from the sensor and updates its data properties with the gathered values. /// </summary> /// <returns>An awaitable Task</returns> /// <remarks> /// Note that when #AutoUpdateWhenPropertyRead is `true` (which it is, by default), this method is implicitly /// called when any sensor data property is read from --- there's no need to call this method unless you set /// AutoUpdateWhenPropertyRead to `false`. /// /// Unless otherwise noted, this method updates all sensor data simultaneously, which can often lead to more efficient /// bus usage (as well as reducing USB chattiness). /// </remarks> public override async Task UpdateAsync() { var value = await i2c.SendReceiveAsync(address, null, 7).ConfigureAwait(false); // the datasheet lists a digital value of 340 @ 25C, and a resolution of 1.1C per LSB celsius = (((short)((((value[3] & 0xf0) << 4) | value[6]) << 4) >> 4) - 340) * 1.1 + 25.0; // These are signed 12-bit values -- shift them up by 4 to pick up the sign, then shift them back down by 4 // ...then convert to mT _magnetometer.X = ((short)(((value[0] << 4) | (value[4] >> 4)) << 4) >> 4) * 0.098f; _magnetometer.Y = ((short)(((value[1] << 4) | value[4]) << 4) >> 4) * 0.098f; _magnetometer.Z = ((short)(((value[2] << 4) | value[5]) << 4) >> 4) * 0.098f; RaisePropertyChanged(this); RaisePropertyChanged(this, nameof(Magnetometer)); }
private Task sendControl(byte data, int digit) { return(i2c.SendReceiveAsync((byte)(ControlBase + digit), new[] { data }, 0)); }
// SMBus functions // Key to symbols // ============== // S (1 bit) : Start bit // P (1 bit) : Stop bit // Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0. // A, NA (1 bit) : Accept and reverse accept bit. // Addr (7 bits): I2C 7 bit address. Note that this can be expanded as usual to // get a 10 bit I2C address. // Comm (8 bits): Command byte, a data byte which often selects a register on // the device. // Data (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh // for 16 bit data. // Count (8 bits): A data byte containing the length of a block operation. // [..]: Data sent by I2C device, as opposed to data sent by the host adapter. /// <summary> /// Read a single byte from the device /// </summary> /// <returns></returns> public async Task <byte> ReadByteAsync() { // set the speed for this device, just in case another device mucked with these settings _i2C.Speed = _rateKhz; // S Addr Rd [A] [Data] NA P var data = await _i2C.SendReceiveAsync(_address, new byte[] { }, 1).ConfigureAwait(false); return(data[0]); }