diff --git a/IotThermometer/App.config b/IotThermometer/App.config
deleted file mode 100644
index 4bba09a..0000000
--- a/IotThermometer/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/IotThermometer/IotThermometer.csproj b/IotThermometer/IotThermometer.csproj
index e5c4454..27df099 100644
--- a/IotThermometer/IotThermometer.csproj
+++ b/IotThermometer/IotThermometer.csproj
@@ -43,14 +43,13 @@
+
+
-
-
-
{8C5D4DE9-377F-4EC8-873D-6EEF15F43516}
diff --git a/IotThermometer/Librarys/Bme280.cs b/IotThermometer/Librarys/Bme280.cs
index 8eebcbe..53547b5 100644
--- a/IotThermometer/Librarys/Bme280.cs
+++ b/IotThermometer/Librarys/Bme280.cs
@@ -1,274 +1,154 @@
using System;
+using BlubbFish.Iot.Thermometer.System;
using BlubbFish.Utils;
-using Unosquare.RaspberryIO;
-using Unosquare.RaspberryIO.Gpio;
namespace BlubbFish.Iot.Thermometer.Librarys {
- class Bme280 {
- public Bme280(Int32 address) => this.w = Pi.I2C.AddDevice(address);
+ class Bme280 : ATwi {
+ private CalibrationData dig;
+ private Boolean init = false;
+ public Double Temperatur { get; private set; }
+ public Double Pressure { get; private set; }
+ public Double Humidity { get; private set; }
+
+ public Bme280(Int32 address) : base(address) { }
+
+ #region Main
public void Begin() {
- if(this.Read8((Byte)Register.BME280_REG_ID) != 0x60) {
- Helper.WriteError("Fail to init Barometer\n");
+ if(!this.init) {
+ if(this.ReadByte(RegisterAddress.ID) != 0x60) {
+ Helper.WriteError("Fail to init Barometer");
+ return;
+ }
+ this.dig = new CalibrationData(this);
+ //Humidity oversampling 16X oversampling [2..0]
+ this.WriteByte(RegisterAddress.CTRL_HUM, 0b00000101);
+ //Pressure oversampling 16X oversampling [7..5], Temperature oversampling 16X oversampling [4..2], Mode Normal mode [1..0]
+ this.WriteByte(RegisterAddress.CTRL_MEAS, 0b10110111);
+ //inactive duration 250 ms [7..5], IIR filter Filter coefficient 16 [4..2], SPI Interface off [0]
+ this.WriteByte(RegisterAddress.CONFIG, 0b01110000);
+ Console.WriteLine("Barometer ok");
+ this.init = true;
}
- this.ReadTrimming();
- //Humidity oversampling 16X oversampling [2..0]
- this.WriteRegister((Byte)Register.BME280_REG_CTRL_HUM, 0b00000101);
- //Pressure oversampling 16X oversampling [7..5], Temperature oversampling 16X oversampling [4..2], Mode Normal mode [1..0]
- this.WriteRegister((Byte)Register.BME280_REG_CTRL_MEAS, 0b10110111);
- //inactive duration 250 ms [7..5], IIR filter Filter coefficient 16 [4..2], SPI Interface off [0]
- this.WriteRegister((Byte)Register.BME280_REG_CONFIG, 0b01110000);
- Console.WriteLine("Barometer ok\n");
}
public void Measure() {
- this._adc_T = (Int32)this.Read20((Byte)Register.BME280_REG_TEMP_DATA);
- this._adc_P = (Int32)this.Read20((Byte)Register.BME280_REG_PRESS_DATA);
- //this._adc_H = this.Read16((Byte)Register.BME280_REG_HUM_DATA);
+ if(this.init) {
+ UInt32 temperatur = this.Read20(RegisterAddress.TEMP_DATA);
+ UInt32 pressure = this.Read20(RegisterAddress.PRESS_DATA);
+ UInt16 humidity = this.ReadShortLE(RegisterAddress.HUM_DATA);
+ this.CalcTemp((Int32)temperatur);
+ this.CalcPress((Int32)pressure);
+ this.CalcHum(humidity);
+ }
+ }
+ #endregion
+
+ #region Calculation
+ private void CalcTemp(Int32 adc_T) {
+ Double var1 = (adc_T / 16384.0 - this.dig.T1 / 1024.0) * this.dig.T2;
+ Double var2 = ((adc_T / 131072.0 - this.dig.T1 / 8192.0) * (adc_T / 131072.0 - this.dig.T1 / 8192.0)) * this.dig.T3;
+ this.Temperatur = (var1 + var2) / 5120.0;
}
- public Double GetTemperature() {
- Int32 adc_T = this._adc_T;
- //Int32 var1, var2;
-
- Double var1, var2;
- var1 = (adc_T / 16384.0 - this._dig_T1 / 1024.0) * this._dig_T2;
- var2 = ((adc_T / 131072.0 - this._dig_T1 / 8192.0) * (adc_T / 131072.0 - this._dig_T1 / 8192.0)) * this._dig_T3;
- this._t_fine = (Int32)(var1 + var2);
- return (var1 + var2) / 5120.0;
-
- /*var1 = (((adc_T >> 3) - (this._dig_T1 << 1)) * this._dig_T2) >> 11;
- var2 = (((((adc_T >> 4) - this._dig_T1) * ((adc_T >> 4) - this._dig_T1)) >> 12) * this._dig_T3) >> 14;
- this._t_fine = var1 + var2;
- return ((Double)(this._t_fine * 5 + 128 >> 8)) / 100;*/
-
- /*adc_T >>= 4;
- var1 = (((adc_T >> 3) - ((int32_t)(this->_dig_T1 << 1))) * ((int32_t)this->_dig_T2)) >> 11;
- var2 = (((((adc_T >> 4) - ((int32_t)this->_dig_T1)) * ((adc_T >> 4) - ((int32_t)this->_dig_T1))) >> 12) * ((int32_t)this->_dig_T3)) >> 14;
- t_fine = var1 + var2;
- float T = (t_fine * 5 + 128) >> 8;
- return T/100;*/
- }
-
- public Double GetPressure() {
- Int32 adc_P = this._adc_P;
-
- Double var1, var2, p;
- var1 = (this._t_fine / 2.0) - 64000.0;
- var2 = var1 * var1 * this._dig_P6 / 32768.0;
- var2 = var2 + var1 * this._dig_P5 * 2.0;
- var2 = (var2 / 4.0) + (this._dig_P4 * 65536.0);
- var1 = (this._dig_P3 * var1 * var1 / 524288.0 + this._dig_P2 * var1) / 524288.0;
- var1 = (1.0 + var1 / 32768.0) * this._dig_P1;
+ private void CalcPress(Int32 adc_P) {
+ Double var1 = (this.Temperatur * 5120 / 2.0) - 64000.0;
+ Double var2 = var1 * var1 * this.dig.P6 / 32768.0;
+ var2 = var2 + var1 * this.dig.P5 * 2.0;
+ var2 = (var2 / 4.0) + (this.dig.P4 * 65536.0);
+ var1 = (this.dig.P3 * var1 * var1 / 524288.0 + this.dig.P2 * var1) / 524288.0;
+ var1 = (1.0 + var1 / 32768.0) * this.dig.P1;
if(var1 == 0.0) {
- return 0; // avoid exception caused by division by zero
+ this.Pressure = 0; // avoid exception caused by division by zero
+ return;
}
- p = 1048576.0 - adc_P;
+ Double p = 1048576.0 - adc_P;
p = (p - (var2 / 4096.0)) * 6250.0 / var1;
- var1 = this._dig_P9 * p * p / 2147483648.0;
- var2 = p * this._dig_P8 / 32768.0;
- return (p + (var1 + var2 + this._dig_P7) / 16.0) / 100.0;
-
- /*Int64 var1, var2, P;
-
- var1 = ((Int64)this._t_fine) - 128000;
- var2 = var1 * var1 * this._dig_P6;
- var2 = var2 + ((var1 * this._dig_P5) << 17);
- var2 = var2 + (((Int64)this._dig_P4) << 35);
- var1 = ((var1 * var1 * this._dig_P3) >> 8) + ((var1 * this._dig_P2) << 12);
- var1 = ((((Int64)1) << 47) + var1) * this._dig_P1 >> 33;
- if(var1 == 0) {
- return 0.0; // avoid exception caused by division by zero
- }
- P = 1048576 - adc_P;
- P = (((P << 31) - var2) * 3125) / var1;
- var1 = (this._dig_P9 * (P >> 13) * (P >> 13)) >> 25;
- var2 = (this._dig_P8 * P) >> 19;
- P = ((P + var1 + var2) >> 8) + (((Int64)this._dig_P7) << 4);
- return ((Double)((UInt32)P)) / 25600;*/
-
-
- /*adc_P >>= 4;
- var1 = ((int64_t)t_fine) - 128000;
- var2 = var1 * var1 * (int64_t)this->_dig_P6;
- var2 = var2 + ((var1*(int64_t)this->_dig_P5)<<17);
- var2 = var2 + (((int64_t)this->_dig_P4)<<35);
- var1 = ((var1 * var1 * (int64_t)this->_dig_P3)>>8) + ((var1 * (int64_t)this->_dig_P2)<<12);
- var1 = (((((int64_t)1)<<47)+var1))*((int64_t)this->_dig_P1)>>33;
- if (var1 == 0) {
- return 0; // avoid exception caused by division by zero
- }
- p = 1048576-adc_P;
- p = (((p<<31)-var2)*3125)/var1;
- var1 = (((int64_t)this->_dig_P9) * (p>>13) * (p>>13)) >> 25;
- var2 = (((int64_t)this->_dig_P8) * p) >> 19;
- p = ((p + var1 + var2) >> 8) + (((int64_t)this->_dig_P7)<<4);
- return ((float)(uint32_t)p/256)/100;*/
+ var1 = this.dig.P9 * p * p / 2147483648.0;
+ var2 = p * this.dig.P8 / 32768.0;
+ this.Pressure = (p + (var1 + var2 + this.dig.P7) / 16.0) / 100.0;
}
- public Double GetHumidity() {
- Int32 adc_H = this._adc_H;
+ private void CalcHum(Int32 adc_H) {
+ Double var_H = (this.Temperatur * 5120) - 76800.0;
+ var_H = (adc_H - (this.dig.H4 * 64.0 + this.dig.H5 / 16384.0 * var_H)) *
+ (this.dig.H2 / 65536.0 * (1.0 + this.dig.H6 / 67108864.0 * var_H * (1.0 + this.dig.H3 / 67108864.0 * var_H)));
+ var_H = var_H * (1.0 - this.dig.H1 * var_H / 524288.0);
+ this.Humidity = var_H > 100 ? 100 : var_H < 0 ? 0 : var_H;
+ }
+ #endregion
- Double var_H;
- var_H = this._t_fine - 76800.0;
- var_H = (adc_H - (this._dig_H4 * 64.0 + this._dig_H5 / 16384.0 * var_H)) * (this._dig_H2 / 65536.0 * (1.0 + this._dig_H6 / 67108864.0 * var_H * (1.0 + this._dig_H3 / 67108864.0 * var_H)));
- var_H = var_H * (1.0 - this._dig_H1 * var_H / 524288.0);
- return var_H;
- return var_H > 100 ? 100 : var_H < 0 ? 0: var_H;
- /*if(var_H > 100.0) {
- var_H = 100.0;
- } else if(var_H < 0.0) {
- var_H = 0.0;
+ private struct CalibrationData {
+ public CalibrationData(Bme280 bme) {
+ this.T1 = bme.ReadShort(RegisterAddress.CALIB00);
+ this.T2 = bme.ReadSingedShort(RegisterAddress.CALIB02);
+ this.T3 = bme.ReadSingedShort(RegisterAddress.CALIB04);
+ this.P1 = bme.ReadShort(RegisterAddress.CALIB06);
+ this.P2 = bme.ReadSingedShort(RegisterAddress.CALIB08);
+ this.P3 = bme.ReadSingedShort(RegisterAddress.CALIB10);
+ this.P4 = bme.ReadSingedShort(RegisterAddress.CALIB12);
+ this.P5 = bme.ReadSingedShort(RegisterAddress.CALIB14);
+ this.P6 = bme.ReadSingedShort(RegisterAddress.CALIB16);
+ this.P7 = bme.ReadSingedShort(RegisterAddress.CALIB18);
+ this.P8 = bme.ReadSingedShort(RegisterAddress.CALIB20);
+ this.P9 = bme.ReadSingedShort(RegisterAddress.CALIB22);
+ this.H1 = bme.ReadByte(RegisterAddress.CALIB25);
+ this.H2 = bme.ReadSingedShort(RegisterAddress.CALIB26);
+ this.H3 = bme.ReadByte(RegisterAddress.CALIB28);
+ this.H4 = (Int16)((bme.ReadByte(RegisterAddress.CALIB29) << 4) | (0b00001111 & bme.ReadByte(RegisterAddress.CALIB30)));
+ this.H5 = (Int16)((bme.ReadByte(RegisterAddress.CALIB31) << 4) | ((0b11110000 & bme.ReadByte(RegisterAddress.CALIB30)) >> 4));
+ this.H6 = (SByte)bme.ReadByte(RegisterAddress.CALIB32);
}
- return var_H;*/
- /*Int32 H;
-
- H = this._t_fine - 76800;
- H = ((((adc_H << 14) - (this._dig_H4 << 20) - (this._dig_H5 * H)) + 16384) >> 15) *
- (((((((H * this._dig_H6) >> 10) * (((H * this._dig_H3) >> 11) + 32768)) >> 10) + 2097152) * this._dig_H2 + 8192) >> 14);
- H = H - (((((H >> 15) * (H >> 15)) >> 7) * this._dig_H1) >> 4);
- H = H < 0 ? 0 : H;
- H = H > 419430400 ? 419430400 : H;
- return ((Double)(H >> 12)) / 1024;*/
+ public UInt16 T1 { get; private set; }
+ public Int16 T2 { get; private set; }
+ public Int16 T3 { get; private set; }
+ public UInt16 P1 { get; private set; }
+ public Int16 P2 { get; private set; }
+ public Int16 P3 { get; private set; }
+ public Int16 P4 { get; private set; }
+ public Int16 P5 { get; private set; }
+ public Int16 P6 { get; private set; }
+ public Int16 P7 { get; private set; }
+ public Int16 P8 { get; private set; }
+ public Int16 P9 { get; private set; }
+ public Byte H1 { get; private set; }
+ public Int16 H2 { get; private set; }
+ public Byte H3 { get; private set; }
+ public Int16 H4 { get; private set; }
+ public Int16 H5 { get; private set; }
+ public SByte H6 { get; private set; }
}
- public void ReadTrimming() {
- this._dig_T1 = this.Read16LE((Byte)Calibration.BME280_REG_CALIB00);
- this._dig_T2 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB02);
- this._dig_T3 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB04);
- this._dig_P1 = this.Read16LE((Byte)Calibration.BME280_REG_CALIB06);
- this._dig_P2 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB08);
- this._dig_P3 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB10);
- this._dig_P4 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB12);
- this._dig_P5 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB14);
- this._dig_P6 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB16);
- this._dig_P7 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB18);
- this._dig_P8 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB20);
- this._dig_P9 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB22);
- this._dig_H1 = this.Read8((Byte)Calibration.BME280_REG_CALIB25);
- this._dig_H2 = this.ReadS16LE((Byte)Calibration.BME280_REG_CALIB26);
- this._dig_H3 = this.Read8((Byte)Calibration.BME280_REG_CALIB28);
- this._dig_H4 = (Int16)((this.Read8((Byte)Calibration.BME280_REG_CALIB29) << 4) | (0b00001111 & this.Read8((Byte)Calibration.BME280_REG_CALIB30)));
- this._dig_H5 = (Int16)((this.Read8((Byte)Calibration.BME280_REG_CALIB31) << 4) | ((0b11110000 & this.Read8((Byte)Calibration.BME280_REG_CALIB30)) >> 4));
- this._dig_H6 = (SByte)this.Read8((Byte)Calibration.BME280_REG_CALIB32);
- }
-
- private readonly I2CDevice w;
- private Int32 _adc_T;
- private Int32 _adc_P;
- private Int32 _adc_H;
- private Int32 _t_fine;
-
- private UInt16 _dig_T1;
- private Int16 _dig_T2;
- private Int16 _dig_T3;
- private UInt16 _dig_P1;
- private Int16 _dig_P2;
- private Int16 _dig_P3;
- private Int16 _dig_P4;
- private Int16 _dig_P5;
- private Int16 _dig_P6;
- private Int16 _dig_P7;
- private Int16 _dig_P8;
- private Int16 _dig_P9;
- private Byte _dig_H1;
- private Int16 _dig_H2;
- private Byte _dig_H3;
- private Int16 _dig_H4;
- private Int16 _dig_H5;
- private SByte _dig_H6;
-
- //Calibration Register Adresses
- private enum Calibration {
- BME280_REG_CALIB00 = 0b10001000,
- BME280_REG_CALIB02 = 0b10001010,
- BME280_REG_CALIB04 = 0b10001100,
- BME280_REG_CALIB06 = 0b10001110,
- BME280_REG_CALIB08 = 0b10010000,
- BME280_REG_CALIB10 = 0b10010010,
- BME280_REG_CALIB12 = 0b10010100,
- BME280_REG_CALIB14 = 0b10010110,
- BME280_REG_CALIB16 = 0b10011000,
- BME280_REG_CALIB18 = 0b10011010,
- BME280_REG_CALIB20 = 0b10011100,
- BME280_REG_CALIB22 = 0b10011110,
- BME280_REG_CALIB25 = 0b10100001,
- BME280_REG_CALIB26 = 0b11100001,
- BME280_REG_CALIB28 = 0b11100011,
- BME280_REG_CALIB29 = 0b11100100,
- BME280_REG_CALIB30 = 0b11100101,
- BME280_REG_CALIB31 = 0b11100110,
- BME280_REG_CALIB32 = 0b11100111
+ private struct RegisterAddress {
+ public const Byte CALIB00 = 0x88;
+ public const Byte CALIB02 = 0x8A;
+ public const Byte CALIB04 = 0x8C;
+ public const Byte CALIB06 = 0x8E;
+ public const Byte CALIB08 = 0x90;
+ public const Byte CALIB10 = 0x92;
+ public const Byte CALIB12 = 0x94;
+ public const Byte CALIB14 = 0x96;
+ public const Byte CALIB16 = 0x98;
+ public const Byte CALIB18 = 0x9A;
+ public const Byte CALIB20 = 0x9C;
+ public const Byte CALIB22 = 0x9E;
+ public const Byte CALIB25 = 0xA1;
+ public const Byte ID = 0xD0;
+ public const Byte RESET = 0xE0;
+ public const Byte CALIB26 = 0xE1;
+ public const Byte CALIB28 = 0xE3;
+ public const Byte CALIB29 = 0xE4;
+ public const Byte CALIB30 = 0xE5;
+ public const Byte CALIB31 = 0xE6;
+ public const Byte CALIB32 = 0xE7;
+ public const Byte CTRL_HUM = 0xF2;
+ public const Byte STATUS = 0xF3;
+ public const Byte CTRL_MEAS = 0xF4;
+ public const Byte CONFIG = 0xF5;
+ public const Byte PRESS_DATA = 0xF7;
+ public const Byte TEMP_DATA = 0xFA;
+ public const Byte HUM_DATA = 0xFD;
};
-
- //Register Adresses
- private enum Register {
- BME280_REG_ID = 0b11010000,
- BME280_REG_RESET = 0b11100000,
- BME280_REG_CTRL_HUM = 0b11110010,
- BME280_REG_STATUS = 0b11110011,
- BME280_REG_CTRL_MEAS = 0b11110100,
- BME280_REG_CONFIG = 0b11110101,
- BME280_REG_PRESS_DATA = 0b11110111,
- BME280_REG_TEMP_DATA = 0b11111010,
- BME280_REG_HUM_DATA = 0b11111101
- };
-
-
-
- //TWI Writes
- private Byte Read8(Byte reg) => this.w.ReadAddressByte(reg);
- /*this->w->beginTransmission(address);
- this->w->write(reg);
- this->w->endTransmission();
- this->w->requestFrom(address, 1);
- while(!this->w->available())
- ;
- return this->w->read();*/
-
- private UInt16 Read16LE(Byte reg) => this.w.ReadAddressWord(reg);
- /*uint8_t msb, lsb;
- this->w->beginTransmission(address);
- this->w->write(reg);
- this->w->endTransmission();
- this->w->requestFrom(address, 2);
- while(this->w->available() < 2)
- ;
- msb = this->w->read();
- lsb = this->w->read();
- return (uint16_t)msb << 8 | lsb;*/
-
- private UInt16 Read16(Byte reg) {
- UInt16 data = this.Read16LE(reg);
- return (UInt16)((data >> 8) | (data << 8));
- }
-
- private Int16 ReadS16LE(Byte reg) => (Int16)this.Read16LE(reg);
-
- private UInt32 Read20(Byte reg) {
- UInt32 data;
- this.w.Write(reg);
- Byte[] dr = this.w.Read(3);
- /*this->w->beginTransmission(address);
- this->w->write(reg);
- this->w->endTransmission();
- this->w->requestFrom(address, 3);
- while(this->w->available() < 3)
- ;*/
- data = dr[0];
- data <<= 8;
- data |= dr[1];
- data <<= 8;
- data |= dr[2];
- data >>= 4;
- return data;
- }
-
- private void WriteRegister(Byte reg, Byte val) => this.w.WriteAddressByte(reg, val);
- /*this->w->beginTransmission(address);
- this->w->write(reg);
- this->w->write(val);
- this->w->endTransmission();*/
}
}
diff --git a/IotThermometer/Librarys/Rainbowdruino.cs b/IotThermometer/Librarys/Rainbowdruino.cs
new file mode 100644
index 0000000..44799f0
--- /dev/null
+++ b/IotThermometer/Librarys/Rainbowdruino.cs
@@ -0,0 +1,215 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Ports;
+
+namespace BlubbFish.Iot.Thermometer.Librarys {
+ class Rainbowdruino {
+ private readonly SerialPort serial;
+ private readonly UInt32[,] zbuffer = new UInt32[8, 16];
+
+ private struct Digets {
+ public static readonly Boolean[][] Null = {
+ new Boolean[]{ false, true, false },
+ new Boolean[] { true, false, true },
+ new Boolean[] { true, false, true },
+ new Boolean[] { true, false, true },
+ new Boolean[]{ false, true, false }
+ };
+ public static readonly Boolean[][] One = {
+ new Boolean[] { false, false, true },
+ new Boolean[] { false, true, true },
+ new Boolean[] { false, false, true },
+ new Boolean[] { false, false, true },
+ new Boolean[] { false, false, true }
+ };
+ public static readonly Boolean[][] Two = {
+ new Boolean[] { false, true, false },
+ new Boolean[] { true, false, true },
+ new Boolean[] { false, false, true },
+ new Boolean[] { false, true, false },
+ new Boolean[] { true, true, true }
+ };
+ public static readonly Boolean[][] Three = {
+ new Boolean[] { true, true, false },
+ new Boolean[] { false, false, true },
+ new Boolean[] { false, true, false },
+ new Boolean[] { false, false, true },
+ new Boolean[] { true, true, false }
+ };
+ public static readonly Boolean[][] Four = {
+ new Boolean[] { false, false, true },
+ new Boolean[] { false, true, true },
+ new Boolean[] { true, false, true },
+ new Boolean[] { true, true, true },
+ new Boolean[] { false, false, true }
+ };
+ public static readonly Boolean[][] Five = {
+ new Boolean[] { true, true, true },
+ new Boolean[] { true, false, false },
+ new Boolean[] { true, true, false },
+ new Boolean[] { false, false, true },
+ new Boolean[] { true, true, false }
+ };
+ public static readonly Boolean[][] Six = {
+ new Boolean[] { false, true, true },
+ new Boolean[] { true, false, false },
+ new Boolean[] { true, true, true },
+ new Boolean[] { true, false, true },
+ new Boolean[] { false, true, false }
+ };
+ public static readonly Boolean[][] Seven = {
+ new Boolean[] { true, true, true },
+ new Boolean[] { false, false, true },
+ new Boolean[] { false, true, false },
+ new Boolean[] { true, false, false },
+ new Boolean[] { true, false, false }
+ };
+ public static readonly Boolean[][] Eight = {
+ new Boolean[] { false, true, false },
+ new Boolean[] { true, false, true },
+ new Boolean[] { false, true, false },
+ new Boolean[] { true, false, true },
+ new Boolean[] { false, true, false }
+ };
+ public static readonly Boolean[][] Nine = {
+ new Boolean[] { false, true, false },
+ new Boolean[] { true, false, true },
+ new Boolean[] { true, true, true },
+ new Boolean[] { false, false, true },
+ new Boolean[] { true, true, false }
+ };
+ }
+
+ public Rainbowdruino(String com) {
+ this.serial = new SerialPort(com, 19200);
+ this.serial.Open();
+ }
+
+ public void DrawDigets(String number, UInt32 color) {
+ Int32 sub = number.Length;
+ if(number.Length > 4 && number.Substring(0, 5).Contains(".")) {
+ sub = 5;
+ } else if(number.Length >= 4) {
+ sub = 4;
+ }
+ String a = number.Substring(0, sub);
+ Int32 y = 0;
+ foreach(Char item in a) {
+ if(item != '.') {
+ this.CopyDigetToZbuffer(this.GetDiget(item), 3, y, color);
+ y += 4;
+ } else {
+ this.DrawDot(y - 1, 7, color);
+ }
+ }
+ }
+
+ public void DrawDot(Int32 x, Int32 y, UInt32 color) {
+ try {
+ this.zbuffer[y, x] = color;
+ } catch {
+ Console.WriteLine("out of bound");
+ }
+ }
+
+ public void DrawLineX(Int32 x, Int32 y, Int32 l, UInt32 color) {
+ for(Int32 i = x; i < x + l; i++) {
+ this.DrawDot(i, y, color);
+ }
+ }
+
+ public void DrawLineY(Int32 x, Int32 y, Int32 l, UInt32 color) {
+ for(Int32 i = y; i < y + l; i++) {
+ this.DrawDot(x, i, color);
+ }
+ }
+
+ public void Write() {
+ this.Clear();
+ List colors = this.GetAllColors();
+ foreach(UInt32 item in colors) {
+ this.serial.Write(String.Join(" ", this.GetZbufferPage(0, item)) + " " + String.Join(" ", this.GetZbufferPage(1, item)) + " " + String.Join(" ", this.GetAllColors(item)) + "\n");
+ }
+ this.ClearZbuffer();
+ }
+
+ public void Clear() => this.serial.Write("clear\n");
+
+ private void ClearZbuffer() {
+ for(Int32 i = 0; i < 8; i++) {
+ for(Int32 j = 0; j < 16; j++) {
+ this.zbuffer[i, j] = 0;
+ }
+ }
+ }
+
+ private String[] GetAllColors(UInt32 color) {
+ String[] ret = new String[3];
+ ret[0] = ((Byte)((color & 0x00FF0000) >> 16)).ToString().PadLeft(3, '0');
+ ret[1] = ((Byte)((color & 0x0000FF00) >> 8)).ToString().PadLeft(3, '0');
+ ret[2] = ((Byte)((color & 0x000000FF) >> 0)).ToString().PadLeft(3, '0');
+ return ret;
+ }
+
+ private String[] GetZbufferPage(Int32 page, UInt32 color) {
+ String[] ret = new String[8];
+ for(Int32 i = 0; i < 8; i++) {
+ Byte p = 0;
+ for(Int32 j = 0; j < 8; j++) {
+ if(this.zbuffer[i, j + (page * 8)] == color) {
+ p |= (Byte)(1 << (7 - j));
+ }
+ }
+ ret[i] = p.ToString().PadLeft(3, '0');
+ }
+ return ret;
+ }
+
+ private List GetAllColors() {
+ List colors = new List();
+ foreach(UInt32 item in this.zbuffer) {
+ if(!colors.Contains(item) && item != 0) {
+ colors.Add(item);
+ }
+ }
+ return colors;
+ }
+
+ private Boolean[][] GetDiget(Char item) {
+ switch(item) {
+ case '1':
+ return Digets.One;
+ case '2':
+ return Digets.Two;
+ case '3':
+ return Digets.Three;
+ case '4':
+ return Digets.Four;
+ case '5':
+ return Digets.Five;
+ case '6':
+ return Digets.Six;
+ case '7':
+ return Digets.Seven;
+ case '8':
+ return Digets.Eight;
+ case '9':
+ return Digets.Nine;
+ default:
+ return Digets.Null;
+ }
+ }
+
+ private void CopyDigetToZbuffer(Boolean[][] diget, Int32 x, Int32 y, UInt32 color) {
+ try {
+ for(Int32 i = 0; i < diget.Length; i++) {
+ for(Int32 j = 0; j < diget[i].Length; j++) {
+ this.zbuffer[i + x, j + y] = diget[i][j] ? color : this.zbuffer[i + x, j + y];
+ }
+ }
+ } catch {
+ Console.WriteLine("out of bound");
+ }
+ }
+ }
+}
diff --git a/IotThermometer/Librarys/TSL2591.cs b/IotThermometer/Librarys/TSL2591.cs
index b06f033..b52ecbf 100644
--- a/IotThermometer/Librarys/TSL2591.cs
+++ b/IotThermometer/Librarys/TSL2591.cs
@@ -1,170 +1,214 @@
using System;
using System.Threading;
+using BlubbFish.Iot.Thermometer.System;
using BlubbFish.Utils;
-using Unosquare.RaspberryIO;
-using Unosquare.RaspberryIO.Gpio;
namespace BlubbFish.Iot.Thermometer.Librarys {
- public class TSL2591 {
- public enum Gain {
- TSL2591_GAIN_LOW = 0b00000000, /// low gain (1x)
- TSL2591_GAIN_MED = 0b00010000, /// medium gain (25x)
- TSL2591_GAIN_HIGH = 0b00100000, /// medium gain (428x)
- TSL2591_GAIN_MAX = 0b00110000, /// max gain (9876x)
- };
- public enum IntegrationTime {
- TSL2591_INTEGRATIONTIME_100MS = 0b00000000, // INTEGRATION TIME 100 ms, MAX COUNT 37889
- TSL2591_INTEGRATIONTIME_200MS = 0b00000001, // INTEGRATION TIME 200 ms, MAX COUNT 65535
- TSL2591_INTEGRATIONTIME_300MS = 0b00000010, // INTEGRATION TIME 300 ms, MAX COUNT 65535
- TSL2591_INTEGRATIONTIME_400MS = 0b00000011, // INTEGRATION TIME 400 ms, MAX COUNT 65535
- TSL2591_INTEGRATIONTIME_500MS = 0b00000100, // INTEGRATION TIME 500 ms, MAX COUNT 65535
- TSL2591_INTEGRATIONTIME_600MS = 0b00000101, // INTEGRATION TIME 600 ms, MAX COUNT 65535
- };
- public enum LuxAlg {
- TSL2591_LUXALG1 = 0,
- TSL2591_LUXALG2 = 1,
- TSL2591_LUXALG3 = 2
- };
- public enum Persist {
- TSL2591_PERSIST_EVERY = 0b00000000, // Every ALS cycle generates an interrupt
- TSL2591_PERSIST_ANY = 0b00000001, // Any value outside of threshold range
- TSL2591_PERSIST_2 = 0b00000010, // 2 consecutive values out of range
- TSL2591_PERSIST_3 = 0b00000011, // 3 consecutive values out of range
- TSL2591_PERSIST_5 = 0b00000100, // 5 consecutive values out of range
- TSL2591_PERSIST_10 = 0b00000101, // 10 consecutive values out of range
- TSL2591_PERSIST_15 = 0b00000110, // 15 consecutive values out of range
- TSL2591_PERSIST_20 = 0b00000111, // 20 consecutive values out of range
- TSL2591_PERSIST_25 = 0b00001000, // 25 consecutive values out of range
- TSL2591_PERSIST_30 = 0b00001001, // 30 consecutive values out of range
- TSL2591_PERSIST_35 = 0b00001010, // 35 consecutive values out of range
- TSL2591_PERSIST_40 = 0b00001011, // 40 consecutive values out of range
- TSL2591_PERSIST_45 = 0b00001100, // 45 consecutive values out of range
- TSL2591_PERSIST_50 = 0b00001101, // 50 consecutive values out of range
- TSL2591_PERSIST_55 = 0b00001110, // 55 consecutive values out of range
- TSL2591_PERSIST_60 = 0b00001111 // 60 consecutive values out of range
- };
+ public class TSL2591 : ATwi {
+ private Boolean init = false;
- /// Class TSL2591 Constructor
- /// An instance of wificlass, that also can log
- /// The default integration time
- public TSL2591(IntegrationTime integration, Int32 address) {
- this.w = Pi.I2C.AddDevice(address);
- this._integration = integration;
- this._gain = Gain.TSL2591_GAIN_LOW;
- }
+ public Double Luminosity { get; private set; }
- /// Starts the Communication with the Device
+ public TSL2591(Int32 address) : base(address) { }
+
+ #region Main
public void Begin() {
- Byte id = this.Read8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_DEVICE_ID);
- if(id != 0x50) {
- Helper.WriteError("Fail to init Lightsensor");
- return;
+ if(!this.init) {
+ if(this.ReadByte(RegisterAddresses.ID) != 0x50) {
+ Helper.WriteError("Fail to init Lightsensor");
+ return;
+ }
+ this.IntegrationTime = ATime.I200MS;
+ this.IntegrationAmplifier = AGain.TSL2591_GAIN_LOW;
+ this.Disable();
+ Console.WriteLine("Lightsensor ok");
+ this.init = true;
}
- this.SetTiming(this._integration);
- this.SetGain(this._gain);
- this.Disable();
- Console.WriteLine("Lightsensor ok");
}
- /// Starts a measurement and stores the value internal
- public void Measure() => this._fulllum = this.GetLumAdv(this._gain);
+ public void Measure() {
+ if(this.init) {
+ this.CalcLux(this.GetLumAdv(this.IntegrationAmplifier));
+ }
+ }
+ #endregion
- /// Get the calculated lux value
- /// Select the algorith for calculating lux
- /// Lux in float
- public Double CalculateLux(LuxAlg alg) {
- UInt16 full = (UInt16)(this._fulllum & 0xFFFF);
- UInt16 ir = (UInt16)(this._fulllum >> 16);
- if(((full == 0xFFFF) || (ir == 0xFFFF)) && this._integration != IntegrationTime.TSL2591_INTEGRATIONTIME_100MS) {
+ #region Calculation
+ private struct CalculationConstances {
+ public const Double TSL2591_LUX_COEFA = 1.7;
+ public const Double TSL2591_LUX_COEFB = 1.64;
+ public const Double TSL2591_LUX_COEFC = 0.59;
+ public const Double TSL2591_LUX_COEFD = 0.86;
+ public const Double TSL2591_LUX_DF = 408;
+ }
+
+ private void CalcLux((UInt16 full, UInt16 ir) lum) => this.Luminosity = (this.CalculateLux(1, lum) + this.CalculateLux(2, lum) + this.CalculateLux(3, lum)) / 3;
+
+ private Double CalculateLux(Byte alg, (UInt16 full, UInt16 ir) lum) {
+ if(((lum.full == 0xFFFF) || (lum.ir == 0xFFFF)) && this.IntegrationTime != ATime.I100MS) {
return 200000.0F;
}
- if(((full >= 0x9400) || (ir >= 0x9400)) && this._integration == IntegrationTime.TSL2591_INTEGRATIONTIME_100MS) {
+ if(((lum.full >= 0x9400) || (lum.ir >= 0x9400)) && this.IntegrationTime == ATime.I100MS) {
return 200000.0F;
}
- UInt16 atime = 100;
- switch(this._integration) {
- case IntegrationTime.TSL2591_INTEGRATIONTIME_100MS:
- atime = 100;
- break;
- case IntegrationTime.TSL2591_INTEGRATIONTIME_200MS:
- atime = 200;
- break;
- case IntegrationTime.TSL2591_INTEGRATIONTIME_300MS:
- atime = 300;
- break;
- case IntegrationTime.TSL2591_INTEGRATIONTIME_400MS:
- atime = 400;
- break;
- case IntegrationTime.TSL2591_INTEGRATIONTIME_500MS:
- atime = 500;
- break;
- case IntegrationTime.TSL2591_INTEGRATIONTIME_600MS:
- atime = 600;
- break;
- }
- UInt16 again = 25;
- switch(this._gain) {
- case Gain.TSL2591_GAIN_LOW:
- again = 1;
- break;
- case Gain.TSL2591_GAIN_MED:
- again = 25;
- break;
- case Gain.TSL2591_GAIN_HIGH:
- again = 428;
- break;
- case Gain.TSL2591_GAIN_MAX:
- again = 9876;
- break;
- }
- Double cpl = ((Double)(atime * again)) / TSL2591_LUX_DF;
+ Double cpl = this.IntegrationTimeCount * this.IntegrationAmplifierCount / CalculationConstances.TSL2591_LUX_DF;
Double lux = 0;
- if(alg == LuxAlg.TSL2591_LUXALG1) {
- Double lux1 = (full - TSL2591_LUX_COEFB * ir) / cpl;
- Double lux2 = (full * TSL2591_LUX_COEFC - ir * TSL2591_LUX_COEFD) / cpl;
- lux = lux1 > lux2 ? lux1 : lux2;
- } else if(alg == LuxAlg.TSL2591_LUXALG2) {
- lux = full == 0 ? 0 : (full - ((Double)ir)) * (1.0F - (((Double)ir) / full)) / cpl;
- } else if(alg == LuxAlg.TSL2591_LUXALG3) {
- lux = (full - ir * TSL2591_LUX_COEFA) / cpl;
+ switch(alg) {
+ case 1:
+ Double lux1 = (lum.full - CalculationConstances.TSL2591_LUX_COEFB * lum.ir) / cpl;
+ Double lux2 = (lum.full * CalculationConstances.TSL2591_LUX_COEFC - lum.ir * CalculationConstances.TSL2591_LUX_COEFD) / cpl;
+ lux = lux1 > lux2 ? lux1 : lux2;
+ break;
+ case 2:
+ lux = lum.full == 0 ? 0 : (lum.full - ((Double)lum.ir)) * (1.0F - (((Double)lum.ir) / lum.full)) / cpl;
+ break;
+ case 3:
+ lux = (lum.full - lum.ir * CalculationConstances.TSL2591_LUX_COEFA) / cpl;
+ break;
}
return lux > 0 ? lux : 0;
}
- /// Get the calculated lux value with all algorthims and make an average over all values
- /// Lux in float
- public Double GetLux() => (this.CalculateLux(LuxAlg.TSL2591_LUXALG1) + this.CalculateLux(LuxAlg.TSL2591_LUXALG2) + this.CalculateLux(LuxAlg.TSL2591_LUXALG3)) / 3;
-
- /// Set the integration timing
- /// Integration timing value
- public void SetTiming(IntegrationTime integration) {
+ private (UInt16 full, UInt16 ir) GetFullLuminosity() {
this.Enable();
- this._integration = integration;
- this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_CONTROL, (Byte)((Byte)this._integration | (Byte)this._gain));
+ for(Byte d = 0; d <= this.IntegrationTime; d++) {
+ Thread.Sleep(108);
+ }
+ UInt16 ch0 = this.ReadShort(RegisterAddresses.C0DATAL);
+ UInt16 ch1 = this.ReadShort(RegisterAddresses.C1DATAL);
this.Disable();
+ return (full: ch0, ir: ch1);
}
- /// Get the activated timing value
- /// Active timing value
- public IntegrationTime GetTiming() => this._integration;
+ private (UInt16 full, UInt16 ir) GetLumAdv(Byte gain) {
+ if(gain != this.IntegrationAmplifier) {
+ this.IntegrationAmplifier = gain;
+ }
+ (UInt16 full, UInt16 ir) lum = this.GetFullLuminosity();
+ UInt16 max = 0;
+ if(this.IntegrationTime != ATime.I100MS) {
+ max = 60000;
+ } else {
+ max = 30000;
+ }
- /// Set the gain level
- /// Gain value
- public void SetGain(Gain gain) {
- this.Enable();
- this._gain = gain;
- this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_CONTROL, (Byte)((Byte)this._integration | (Byte)this._gain));
- this.Disable();
+ if(((lum.full < max * (1.0f / 25) && lum.full / (1.0f / 25) < max) && (lum.ir < max * (1.0f / 25) && lum.ir / (1.0f / 25) < max)) && this.IntegrationAmplifier == AGain.TSL2591_GAIN_LOW) {
+ return this.GetLumAdv(AGain.TSL2591_GAIN_MED);
+ }
+ if(((lum.full < max * (25.0f / 428) && lum.full / (25.0f / 428) < max) && (lum.ir < max * (25.0f / 428) && lum.ir / (25.0f / 428) < max)) && this.IntegrationAmplifier == AGain.TSL2591_GAIN_MED) {
+ return this.GetLumAdv(AGain.TSL2591_GAIN_HIGH);
+ }
+ if(((lum.full < max * (428.0f / 9876) && lum.full / (428.0f / 9876) < max) && (lum.ir < max * (428.0f / 9876) && lum.ir / (428.0f / 9876) < max)) && this.IntegrationAmplifier == AGain.TSL2591_GAIN_HIGH) {
+ return this.GetLumAdv(AGain.TSL2591_GAIN_MAX);
+ }
+ if((lum.full > max || lum.ir > max) && this.IntegrationAmplifier == AGain.TSL2591_GAIN_MAX) {
+ return this.GetLumAdv(AGain.TSL2591_GAIN_HIGH);
+ }
+ if((lum.full > max || lum.ir > max) && this.IntegrationAmplifier == AGain.TSL2591_GAIN_HIGH) {
+ return this.GetLumAdv(AGain.TSL2591_GAIN_MED);
+ }
+ if((lum.full > max || lum.ir > max) && this.IntegrationAmplifier == AGain.TSL2591_GAIN_MED) {
+ return this.GetLumAdv(AGain.TSL2591_GAIN_LOW);
+ }
+ return lum;
}
+ #endregion
- /// Get the activated gain value
- /// Active gain value
- public Gain GetGain() => this._gain;
+ #region Settings
+ #region IntegrationTime
+ public struct ATime {
+ public const Byte I100MS = 0b00000000; // INTEGRATION TIME 100 ms, MAX COUNT 37889
+ public const Byte I200MS = 0b00000001; // INTEGRATION TIME 200 ms, MAX COUNT 65535
+ public const Byte I300MS = 0b00000010; // INTEGRATION TIME 300 ms, MAX COUNT 65535
+ public const Byte I400MS = 0b00000011; // INTEGRATION TIME 400 ms, MAX COUNT 65535
+ public const Byte I500MS = 0b00000100; // INTEGRATION TIME 500 ms, MAX COUNT 65535
+ public const Byte I600MS = 0b00000101; // INTEGRATION TIME 600 ms, MAX COUNT 65535
+ };
+ private Byte integrationTime;
+ public Byte IntegrationTime {
+ get => this.integrationTime;
+ set {
+ this.Enable();
+ this.integrationTime = value;
+ this.WriteByte(RegisterAddresses.CONTROL, (Byte)(this.integrationTime | this.IntegrationAmplifier));
+ this.Disable();
+ }
+ }
+ public Double IntegrationTimeCount {
+ get {
+ switch(this.IntegrationTime) {
+ case ATime.I100MS:
+ return 100;
+ case ATime.I200MS:
+ return 200;
+ case ATime.I300MS:
+ return 300;
+ case ATime.I400MS:
+ return 400;
+ case ATime.I500MS:
+ return 500;
+ default:
+ return 600;
+ }
+ }
+ }
+ #endregion
+ #region Gain
+ public struct AGain {
+ public const Byte TSL2591_GAIN_LOW = 0b00000000; // low gain (1x)
+ public const Byte TSL2591_GAIN_MED = 0b00010000; // medium gain (25x)
+ public const Byte TSL2591_GAIN_HIGH = 0b00100000; // medium gain (428x)
+ public const Byte TSL2591_GAIN_MAX = 0b00110000; // max gain (9876x)
+ };
+ private Byte integrationAmplifier;
+ public Byte IntegrationAmplifier {
+ get => this.integrationAmplifier;
+ set {
+ this.Enable();
+ this.integrationAmplifier = value;
+ this.WriteByte(RegisterAddresses.CONTROL, (Byte)(this.IntegrationTime | this.integrationAmplifier));
+ this.Disable();
+ }
+ }
+ public Double IntegrationAmplifierCount {
+ get {
+ switch(this.IntegrationAmplifier) {
+ case AGain.TSL2591_GAIN_LOW:
+ return 1;
+ case AGain.TSL2591_GAIN_MED:
+ return 25;
+ case AGain.TSL2591_GAIN_HIGH:
+ return 428;
+ default:
+ return 9876;
+ }
+ }
+ }
+ #endregion
+ #endregion
- /// Clear the last Interrupt flag
+ #region Interrupts
+ public struct Persist {
+ public const Byte EVERY = 0b00000000; // Every ALS cycle generates an interrupt
+ public const Byte ANY = 0b00000001; // Any value outside of threshold range
+ public const Byte P2 = 0b00000010; // 2 consecutive values out of range
+ public const Byte P3 = 0b00000011; // 3 consecutive values out of range
+ public const Byte P5 = 0b00000100; // 5 consecutive values out of range
+ public const Byte P10 = 0b00000101; // 10 consecutive values out of range
+ public const Byte P15 = 0b00000110; // 15 consecutive values out of range
+ public const Byte P20 = 0b00000111; // 20 consecutive values out of range
+ public const Byte P25 = 0b00001000; // 25 consecutive values out of range
+ public const Byte P30 = 0b00001001; // 30 consecutive values out of range
+ public const Byte P35 = 0b00001010; // 35 consecutive values out of range
+ public const Byte P40 = 0b00001011; // 40 consecutive values out of range
+ public const Byte P45 = 0b00001100; // 45 consecutive values out of range
+ public const Byte P50 = 0b00001101; // 50 consecutive values out of range
+ public const Byte P55 = 0b00001110; // 55 consecutive values out of range
+ public const Byte P60 = 0b00001111; // 60 consecutive values out of range
+ };
public void ClearInterrupt() {
this.Enable();
- this.Write8((Byte)OP.TSL2591_COMMAND_CLEAR_INT);
+ this.WriteByte(RegisterAddresses.COMMAND_CLEAR_INT);
this.Disable();
}
@@ -172,160 +216,89 @@ namespace BlubbFish.Iot.Thermometer.Librarys {
/// Lower border for interrupt
/// Higher border for interrupt
/// Value for persist register, defines when the interrupt occours
- public void RegisterInterrupt(UInt16 lowerThreshold, UInt16 upperThreshold, Persist persist) {
+ public void RegisterInterrupt(UInt16 lowerThreshold, UInt16 upperThreshold, Byte persist) {
this.Enable();
- this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_PERSIST, (Byte)persist);
- this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_THRESHOLD_AILTL, (Byte)lowerThreshold);
- this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_THRESHOLD_AILTH, (Byte)(lowerThreshold >> 8));
- this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_THRESHOLD_AIHTL, (Byte)upperThreshold);
- this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_THRESHOLD_AIHTH, (Byte)(upperThreshold >> 8));
+ this.WriteByte(RegisterAddresses.PERSIST, persist);
+ this.WriteByte(RegisterAddresses.AILTL, (Byte)lowerThreshold);
+ this.WriteByte(RegisterAddresses.AILTH, (Byte)(lowerThreshold >> 8));
+ this.WriteByte(RegisterAddresses.AIHTL, (Byte)upperThreshold);
+ this.WriteByte(RegisterAddresses.AIHTH, (Byte)(upperThreshold >> 8));
this.Disable();
}
- /// Return the Interrupt flags
- /// Bit [5] Indicates that the device has encountered a no-persist interrupt condition,
- /// Bit [4] Indicates that the device is asserting an ALS interrupt,
- /// Bit [0] ALS Valid. Indicates that the ADC channels have completed an integration cycle since the AEN bit (This field activates ALS function.) was asserted.
- public Byte GetStatus() {
+ public struct StatusRegister {
+ public StatusRegister(Byte x) {
+ this.AVALID = (x & (1 << 0)) != 0;
+ this.AINT = (x & (1 << 4)) != 0;
+ this.NPINTR = (x & (1 << 5)) != 0;
+ }
+ ///
+ /// Indicates that the ADC channels have completed an integration cycle since the AEN bit (This field activates ALS function.) was asserted.
+ ///
+ public Boolean AVALID { get; private set; }
+ ///
+ /// Indicates that the device is asserting an ALS interrupt,
+ ///
+ public Boolean AINT { get; private set; }
+ ///
+ /// Indicates that the device has encountered a no-persist interrupt condition,
+ ///
+ public Boolean NPINTR { get; private set; }
+ }
+
+ public StatusRegister GetStatus() {
this.Enable();
- Byte x = this.Read8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_DEVICE_STATUS);
+ Byte x = this.ReadByte(RegisterAddresses.STATUS);
this.Disable();
- return x;
+ return new StatusRegister(x);
}
+ #endregion
- private readonly I2CDevice w;
- private IntegrationTime _integration;
- private Gain _gain;
- private UInt32 _fulllum;
+ #region Powerusage
+ private void Disable() => this.WriteByte(RegisterAddresses.ENABLE, RegisterValues.ENABLE_AEN);
+ private void Enable() => this.WriteByte(RegisterAddresses.ENABLE, RegisterValues.ENABLE_POWERON | RegisterValues.ENABLE_AEN);
+ #endregion
- /// The ENABLE register is used to power the device on/off, enable functions and interrupts.
- enum ENABLE {
- TSL2591_ENABLE_POWERON = 0b00000001, //PON = Power ON. This field activates the internal oscillator to permit the timers and ADC channels to operate. Writing a one activates the oscillator. Writing a zero disables the oscillator.
- TSL2591_ENABLE_AEN = 0b00000010, //AEN = ALS Enable. This field activates ALS function. Writing a one activates the ALS. Writing a zero disables the ALS.
- TSL2591_ENABLE_AIEN = 0b00001000, //AIEN = ALS Interrupt Enable. When asserted permits ALS interrupts to be generated, subject to the persist filter.
- TSL2591_ENABLE_NPIEN = 0b10000000 //NPIEN = No Persist Interrupt Enable. When asserted NP Threshold conditions will generate an interrupt, bypassing the persist filter.
+ private struct RegisterValues {
+ ///
+ /// PON = Power ON. This field activates the internal oscillator to permit the timers and ADC channels to operate. Writing a one activates the oscillator. Writing a zero disables the oscillator.
+ ///
+ public const Byte ENABLE_POWERON = 0b00000001;
+ ///
+ /// AEN = ALS Enable. This field activates ALS function. Writing a one activates the ALS. Writing a zero disables the ALS.
+ ///
+ public const Byte ENABLE_AEN = 0b00000010;
+ ///
+ /// AIEN = ALS Interrupt Enable. When asserted permits ALS interrupts to be generated, subject to the persist filter.
+ ///
+ public const Byte ENABLE_AIEN = 0b00001000;
+ ///
+ /// NPIEN = No Persist Interrupt Enable. When asserted NP Threshold conditions will generate an interrupt, bypassing the persist filter.
+ ///
+ public const Byte ENABLE_NPIEN = 0b10000000;
};
- /// he COMMAND register specifies the address of the target register for future read and write operations, as well as issues special function commands.
- private enum OP {
- TSL2591_COMMAND_NORMAL_OP = 0b10100000, //Select Command Register. Must write as 1 when addressing COMMAND register. TRANSACTION Normal Operation.
- TSL2591_COMMAND_CLEAR_INT = 0b11100111, //Select Command Register. Must write as 1 when addressing COMMAND register. TRANSACTION Special Function. ADDR/SF Clears ALS and no persist ALS interrupt.
+ private struct RegisterAddresses {
+ public const Byte ENABLE = 0x00 | 0b10100000; // Enable register
+ public const Byte CONTROL = 0x01 | 0b10100000; // Control register
+ public const Byte AILTL = 0x04 | 0b10100000; // ALS low threshold lower byte
+ public const Byte AILTH = 0x05 | 0b10100000; // ALS low threshold upper byte
+ public const Byte AIHTL = 0x06 | 0b10100000; // ALS high threshold lower byte
+ public const Byte AIHTH = 0x07 | 0b10100000; // ALS high threshold upper byte
+ //public const Byte NPAILTL = 0b00001000; // No Persist ALS low threshold lower byte
+ //public const Byte NPAILTH = 0b00001001; // No Persist ALS low threshold higher byte
+ //public const Byte NPAIHTL = 0b00001010; // No Persist ALS high threshold lower byte
+ //public const Byte NPAIHTH = 0b00001011; // No Persist ALS high threshold higher byte
+ public const Byte PERSIST = 0x0C | 0b10100000; // Interrupt persistence filter
+ //public const Byte PID = 0b00010001; // Package Identification
+ public const Byte ID = 0x12 | 0b10100000; // Device Identification
+ public const Byte STATUS = 0x13 | 0b10100000; // Internal Status
+ public const Byte C0DATAL = 0x14 | 0b10100000; // Channel 0 data, low byte
+ //public const Byte C0DATAH = 0b00010101; // Channel 0 data, high byte
+ public const Byte C1DATAL = 0x16 | 0b10100000; // Channel 1 data, low byte
+ //public const Byte C1DATAH = 0b00010111; // Channel 1 data, high byte
+ //public const Byte TSL2591_COMMAND_NORMAL_OP = 0b10100000;//Select Command Register. Must write as 1 when addressing COMMAND register. TRANSACTION Normal Operation.
+ public const Byte COMMAND_CLEAR_INT = 0b11100111; //Select Command Register. Must write as 1 when addressing COMMAND register. TRANSACTION Special Function. ADDR/SF Clears ALS and no persist ALS interrupt.
};
-
- /// Register Addresses
- private enum REGISTER {
- TSL2591_REGISTER_ENABLE = 0b00000000, // Enable register
- TSL2591_REGISTER_CONTROL = 0b00000001, // Control register
- TSL2591_REGISTER_THRESHOLD_AILTL = 0b00000100, // ALS low threshold lower byte
- TSL2591_REGISTER_THRESHOLD_AILTH = 0b00000101, // ALS low threshold upper byte
- TSL2591_REGISTER_THRESHOLD_AIHTL = 0b00000110, // ALS high threshold lower byte
- TSL2591_REGISTER_THRESHOLD_AIHTH = 0b00000111, // ALS high threshold upper byte
- TSL2591_REGISTER_THRESHOLD_NPAILTL = 0b00001000, // No Persist ALS low threshold lower byte
- TSL2591_REGISTER_THRESHOLD_NPAILTH = 0b00001001, // No Persist ALS low threshold higher byte
- TSL2591_REGISTER_THRESHOLD_NPAIHTL = 0b00001010, // No Persist ALS high threshold lower byte
- TSL2591_REGISTER_THRESHOLD_NPAIHTH = 0b00001011, // No Persist ALS high threshold higher byte
- TSL2591_REGISTER_PERSIST = 0b00001100, // Interrupt persistence filter
- TSL2591_REGISTER_PACKAGE_PID = 0b00010001, // Package Identification
- TSL2591_REGISTER_DEVICE_ID = 0b00010010, // Device Identification
- TSL2591_REGISTER_DEVICE_STATUS = 0b00010011, // Internal Status
- TSL2591_REGISTER_CHAN0_LOW = 0b00010100, // Channel 0 data, low byte
- TSL2591_REGISTER_CHAN0_HIGH = 0b00010101, // Channel 0 data, high byte
- TSL2591_REGISTER_CHAN1_LOW = 0b00010110, // Channel 1 data, low byte
- TSL2591_REGISTER_CHAN1_HIGH = 0b00010111, // Channel 1 data, high byte
- };
-
- /// Constances to calculating lux
- private const Single TSL2591_LUX_COEFA = 1.7f;
- private const Single TSL2591_LUX_COEFB = 1.64f;
- private const Single TSL2591_LUX_COEFC = 0.59f;
- private const Single TSL2591_LUX_COEFD = 0.86f;
- private const UInt16 TSL2591_LUX_DF = 408;
-
- /// Disable the device
- /// TSL2591::TSL2591_ENABLE_AEN | TSL2591::TSL2591_ENABLE_AIEN | TSL2591::TSL2591_ENABLE_NPIEN
- private void Disable() => this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_ENABLE, (Byte)ENABLE.TSL2591_ENABLE_AEN);
-
- /// Enable the device
- /// TSL2591::TSL2591_ENABLE_POWERON | TSL2591::TSL2591_ENABLE_AEN | TSL2591::TSL2591_ENABLE_AIEN | TSL2591::TSL2591_ENABLE_NPIEN
- private void Enable() => this.Write8((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_ENABLE, (Byte)ENABLE.TSL2591_ENABLE_POWERON | (Byte)ENABLE.TSL2591_ENABLE_AEN);
-
- /// Gets the Complete Luminosity of the Device, reads out
- /// Both Channels and return them in unsinged int32
- /// The upper unsinged int16 half contains the adc value
- /// of the ir channel, the lower half the visible channel
- private UInt32 GetFullLuminosity() {
- this.Enable();
- for(Byte d = 0; d <= (Byte)this._integration; d++) {
- Thread.Sleep(108);
- }
- UInt16 ch0 = this.Read16((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_CHAN0_LOW);
- UInt16 ch1 = this.Read16((Byte)OP.TSL2591_COMMAND_NORMAL_OP | (Byte)REGISTER.TSL2591_REGISTER_CHAN1_LOW);
- this.Disable();
- return (UInt32)ch1 << 16 | ch0;
- }
-
- /// Get the Complete Luminosity of the Device, reads out
- /// Both Channels and return them in unsinged int32, but Switch through
- /// the Gain if lower or higher bounds are reached
- /// Set the gainlevel for the measure
- /// The upper unsinged int16 half contains the adc value
- /// of the ir channel, the lower half the visible channel
- private UInt32 GetLumAdv(Gain gain) {
- if(gain != this._gain) {
- this.SetGain(gain);
- }
- UInt32 lum = this.GetFullLuminosity();
- UInt16 fu = (UInt16)(lum & 0xFFFF);
- UInt16 ir = (UInt16)(lum >> 16);
-
- UInt16 max = 0;
- if(this._integration != IntegrationTime.TSL2591_INTEGRATIONTIME_100MS) {
- max = 60000;
- } else {
- max = 30000;
- }
-
- if(((fu < max * (1.0f / 25) && fu / (1.0f / 25) < max) && (ir < max * (1.0f / 25) && ir / (1.0f / 25) < max)) && this._gain == Gain.TSL2591_GAIN_LOW) {
- return this.GetLumAdv(Gain.TSL2591_GAIN_MED);
- }
- if(((fu < max * (25.0f / 428) && fu / (25.0f / 428) < max) && (ir < max * (25.0f / 428) && ir / (25.0f / 428) < max)) && this._gain == Gain.TSL2591_GAIN_MED) {
- return this.GetLumAdv(Gain.TSL2591_GAIN_HIGH);
- }
- if(((fu < max * (428.0f / 9876) && fu / (428.0f / 9876) < max) && (ir < max * (428.0f / 9876) && ir / (428.0f / 9876) < max)) && this._gain == Gain.TSL2591_GAIN_HIGH) {
- return this.GetLumAdv(Gain.TSL2591_GAIN_MAX);
- }
- if((fu > max || ir > max) && this._gain == Gain.TSL2591_GAIN_MAX) {
- return this.GetLumAdv(Gain.TSL2591_GAIN_HIGH);
- }
- if((fu > max || ir > max) && this._gain == Gain.TSL2591_GAIN_HIGH) {
- return this.GetLumAdv(Gain.TSL2591_GAIN_MED);
- }
- if((fu > max || ir > max) && this._gain == Gain.TSL2591_GAIN_MED) {
- return this.GetLumAdv(Gain.TSL2591_GAIN_LOW);
- }
- return lum;
- }
-
- /// Write a unsinged int8 value to the TWI interface
- /// Value to write
- private void Write8(Byte reg) => this.w.Write(reg);
-
- /// Write two unsinged int8 value to the TWI interface
- /// Value to write
- /// Value to write
- private void Write8(Byte reg1, Byte reg2) => this.w.WriteAddressByte(reg1, reg2);
-
- /// Read a unsinged int16 value from two registers
- /// Lower address
- /// Value of the two int8 registers combined to unsinged int16
- private UInt16 Read16(Byte reg) => this.w.ReadAddressWord(reg);
- /*this.w.Write(reg);
- Byte[] data = this.w.Read(2);
- return (UInt16)(data[1] << 8 | data[0]);*/
-
- /// Read a unsinged int8 value from a registers
- /// Address of the Register
- /// Value of the register in unsinged int8
- private Byte Read8(Byte reg) => this.w.ReadAddressByte(reg);
}
}
diff --git a/IotThermometer/Program.cs b/IotThermometer/Program.cs
index 927f731..2a723d1 100644
--- a/IotThermometer/Program.cs
+++ b/IotThermometer/Program.cs
@@ -1,29 +1,44 @@
using System;
using BlubbFish.Iot.Thermometer.Librarys;
+using System.Threading;
namespace BlubbFish.Iot.Thermometer {
class Program {
private readonly TSL2591 tls;
private readonly Bme280 bme;
+ private readonly Rainbowdruino disp;
public Program(String[] args) {
- this.tls = new TSL2591(TSL2591.IntegrationTime.TSL2591_INTEGRATIONTIME_200MS, 0x29);
+ this.tls = new TSL2591(0x29);
this.bme = new Bme280(0x76);
+ this.disp = new Rainbowdruino("/dev/ttyUSB0");
this.tls.Begin();
this.bme.Begin();
while(true) {
- //this.tls.Measure();
+ this.tls.Measure();
this.bme.Measure();
- //Console.WriteLine(this.tls.GetLux()+" lux");
- Console.WriteLine(this.bme.GetTemperature() + " °C");
- Console.WriteLine(this.bme.GetPressure() + " mbHp");
- Console.WriteLine(this.bme.GetHumidity() + " Hm%");
-
-
- System.Threading.Thread.Sleep(1000);
+ this.DrawDisp(this.bme.Temperatur, 0x110000);
+ Thread.Sleep(5000);
+ this.DrawDisp(this.bme.Humidity, 0x001100);
+ Thread.Sleep(2000);
+ this.DrawDisp(this.bme.Pressure, 0x111100);
+ Thread.Sleep(2000);
+ this.DrawDisp(this.tls.Luminosity, 0x000011);
+ Thread.Sleep(2000);
+ Console.WriteLine(this.tls.Luminosity.ToString("F5") + " lux");
+ Console.WriteLine(this.bme.Temperatur.ToString("F2") + " °C");
+ Console.WriteLine(this.bme.Pressure.ToString("F2") + " mbHp");
+ Console.WriteLine(this.bme.Humidity.ToString("F3") + " Hm%");
+ Console.WriteLine();
}
}
+ private void DrawDisp(Double c, UInt32 color) {
+ this.disp.DrawDigets(c.ToString().Replace(",", "."), color);
+ this.disp.DrawLineX(0, 0, 16, color);
+ this.disp.Write();
+ }
+
static void Main(String[] args) => new Program(args);
}
}
diff --git a/IotThermometer/System/ATwi.cs b/IotThermometer/System/ATwi.cs
new file mode 100644
index 0000000..4038254
--- /dev/null
+++ b/IotThermometer/System/ATwi.cs
@@ -0,0 +1,39 @@
+using System;
+using Unosquare.RaspberryIO;
+using Unosquare.RaspberryIO.Gpio;
+
+namespace BlubbFish.Iot.Thermometer.System {
+ public abstract class ATwi {
+ protected readonly I2CDevice w;
+
+ protected ATwi(Int32 address) => this.w = Pi.I2C.AddDevice(address);
+
+ protected Byte ReadByte(Byte reg) => this.w.ReadAddressByte(reg);
+
+ protected void WriteByte(Byte reg, Byte val) => this.w.WriteAddressByte(reg, val);
+
+ protected void WriteByte(Byte reg) => this.w.Write(reg);
+
+ protected UInt16 ReadShort(Byte reg) => this.w.ReadAddressWord(reg);
+
+ protected UInt16 ReadShortLE(Byte reg) {
+ UInt16 data = this.ReadShort(reg);
+ return (UInt16)((data >> 8) | (data << 8));
+ }
+
+ protected Int16 ReadSingedShort(Byte reg) => (Int16)this.ReadShort(reg);
+
+ protected UInt32 Read20(Byte reg) {
+ UInt32 data;
+ this.w.Write(reg);
+ Byte[] dr = this.w.Read(3);
+ data = dr[0];
+ data <<= 8;
+ data |= dr[1];
+ data <<= 8;
+ data |= dr[2];
+ data >>= 4;
+ return data;
+ }
+ }
+}