Adafruit_BME280_Humidity bm280HumiditySensor;
Adafruit_BME280::Adafruit_BME280() {
- static I2cDevice i2cDevice;
+ static I2cMaster i2cDevice;
t_fine_adjust = 0;
temp_sensor = &bm280TempSensor;
pressure_sensor = &bm280PressureSensor;
// #include <Adafruit_Sensor.h>
-#include "../i2cdevice.hpp"
+#include "../i2cmaster.hpp"
#include "../main.hpp"
#define byte uint8_t
void setTemperatureCompensation(float);
protected:
- I2cDevice *i2c_dev = NULL; ///< Pointer to I2C bus interface
+ I2cMaster *i2c_dev = NULL; ///< Pointer to I2C bus interface
// Adafruit_SPIDevice *spi_dev = NULL; ///< Pointer to SPI bus interface
Adafruit_BME280_Temp *temp_sensor;
#include "ens160.h"
#include "math.h"
#include <util/delay.h>
+#include <stdio.h>
+#include <avr/io.h>
ScioSense_ENS160::ScioSense_ENS160 () {
_revENS16x = 0;
bool ScioSense_ENS160::begin () {
i2cDevice.begin(ENS160_I2CADDR_1);
_delay_ms(ENS160_BOOTING);
-
if (reset()) {
if (checkPartID()) {
if (setMode(ENS160_OPMODE_IDLE)) {
// Reads the part ID and confirms valid sensor
bool ScioSense_ENS160::checkPartID () {
- uint8_t i2cbuf[2];
uint16_t part_id;
- read16(ENS160_REG_PART_ID, &part_id);
- part_id = i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8);
-
+ read16(ENS160_REG_PART_ID, &part_id);
_delay_ms(ENS160_BOOTING);
if (part_id == ENS160_PARTID) {
return true;
}
+bool ScioSense_ENS160::readStatus (uint8_t *status) {
+ return read8(ENS160_REG_DATA_STATUS, status);
+}
+
+bool ScioSense_ENS160::readData (ENS160_DATA *data) {
+ uint8_t buffer[1] = { 0x21 };
+ return i2cDevice.write_then_read(buffer, 1, (uint8_t *)data, sizeof(ENS160_DATA));
+}
+
// Perform prediction measurement and stores result in internal variables
bool ScioSense_ENS160::measure (bool waitForNew) {
uint8_t i2cbuf[8];
// Set default status for early bail out
if (waitForNew) {
do {
- _delay_ms(1);
if (!read8(ENS160_REG_DATA_STATUS, &status)) {
return false;
}
+ _delay_ms(1);
} while (!IS_NEWDAT(status));
} else {
if (!read8(ENS160_REG_DATA_STATUS, &status)) {
}
}
+
// Read predictions
if (IS_NEWDAT(status)) {
if (!readBytes(ENS160_REG_DATA_AQI, i2cbuf, 7)) {
return false;
}
+ return false;
_data_aqi = i2cbuf[0];
_data_tvoc = i2cbuf[1] | ((uint16_t)i2cbuf[2] << 8);
_data_eco2 = i2cbuf[3] | ((uint16_t)i2cbuf[4] << 8);
#ifndef __SCIOSENSE_ENS160_H_
#define __SCIOSENSE_ENS160_H_
-#include "../i2cdevice.hpp"
+#include "../i2cmaster.hpp"
#include <stdint.h>
#define byte uint8_t
#define CONVERT_RS_RAW2OHMS_I(x) (1 << ((x) >> 11))
#define CONVERT_RS_RAW2OHMS_F(x) (pow (2, (float)(x) / 2048))
+typedef struct {
+ uint8_t aqi;
+ uint16_t tvoc;
+ uint16_t eco2;
+} ENS160_DATA;
+
class ScioSense_ENS160 {
public:
bool addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3);
// Add a step to custom measurement profile with definition of duration, enabled data acquisition and temperature for each hotplate
- bool measure(bool waitForNew = true); // Perform measurement and stores result in internal variables
- bool measureRaw(bool waitForNew = true); // Perform raw measurement and stores result in internal variables
+ bool readData (ENS160_DATA *data);
+ bool readStatus(uint8_t *status);
+ bool measure(bool waitForNew); // Perform measurement and stores result in internal variables
+ bool measureRaw(bool waitForNew); // Perform raw measurement and stores result in internal variables
bool set_envdata(float t, float h); // Writes t (degC) and h (%rh) to ENV_DATA. Returns "0" if I2C transmission is successful
bool set_envdata210(uint16_t t, uint16_t h); // Writes t and h (in ENS210 format) to ENV_DATA. Returns "0" if I2C transmission is successful
uint8_t getMajorRev() { return this->_fw_ver_major; } // Get major revision number of used firmware
uint8_t getMISR() { return this->_misr; } // Return status code of sensor
private:
- I2cDevice i2cDevice;
+ I2cMaster i2cDevice;
bool reset(); // Sends a reset to the ENS160. Returns false on I2C problems.
bool checkPartID(); // Reads the part ID and confirms valid sensor
bool clearCommand(); // Initialize idle mode and confirms
+++ /dev/null
-#include <avr/io.h>
-#include <stdio.h>
-
-#include "i2cdevice.hpp"
-
-I2cDevice i2cDevice;
-
-I2cDevice::I2cDevice () {
- address = 0;
-}
-
-bool I2cDevice::begin (uint8_t addr) {
- this->address = addr;
- // TWBR = 13; // 100kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 100000) / (2 * 100000 * 4);
- TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4);
- TWCR = (1 << TWEN);
- return true;
-}
-
-void I2cDevice::end () {
- TWCR = (1 << TWEN);
- TWBR = 0;
-}
-
-bool I2cDevice::write (const uint8_t *buffer, uint8_t len) {
- if (start(false)) {
- if (writeBytes(buffer, len)) {
- if (stop()) {
- return true;
- }
- }
- }
- return false;
-}
-
-bool I2cDevice::write_then_read (const uint8_t *write_buffer, uint8_t write_len, uint8_t *read_buffer, uint8_t read_len) {
- if (start(false)) {
- if (writeBytes(write_buffer, write_len)) {
- if (start(true)) {
- if (readBytes(read_buffer, read_len)) {
- if (stop()) {
- return true;
- }
- }
- }
- }
- }
- return false;
-}
-
-bool I2cDevice::readBytes (uint8_t *buffer, uint8_t len) {
- while (len-- > 0) {
- if (len > 0) {
- TWCR = (1 << TWEA) | (1 << TWINT) | (1 << TWEN); // read data byte with ACK enabled
- } else {
- TWCR = (1 << TWINT) | (1 << TWEN); // read data byte with ACK disabled
- }
- while (!(TWCR & (1 << TWINT))) {}; // wait until last action done
- uint8_t sr = TWSR & 0xf8;
- if ((len > 0 && sr != 0x50) || (len == 0 && sr != 0x58)) {
- return false;
- }
- *buffer++ = TWDR;
- }
- return true;
-}
-
-bool I2cDevice::writeBytes (const uint8_t *buffer, uint8_t len) {
- while (len-- > 0) {
- // printf("[wB:len=%d, byte=%02x]", len + 1, *buffer);
- TWDR = *buffer++;
- TWCR = (1 << TWINT) | (1 << TWEN); // send data byte
- while (!(TWCR & (1 << TWINT))) {}; // wait until last action done
- //printf("TWSR=%02x", TWSR);
- if ((TWSR & 0xf8) != 0x28) {
- return false;
- }
- }
- return true;
-}
-
-bool I2cDevice::writeByteAndBuffer (uint8_t byte, const uint8_t *buffer, uint8_t len) {
- do {
- TWDR = byte;
- TWCR = (1 << TWINT) | (1 << TWEN); // send byte
- while (!(TWCR & (1 << TWINT))) {}; // wait until last action done
- if ((TWSR & 0xf8) != 0x28) {
- return false;
- }
- byte = *buffer++;
- } while (len-- > 0);
- return true;
-}
-
-bool I2cDevice::start (bool read) {
- TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // send START condition
- while (!(TWCR & (1 << TWINT))) {}; // wait until last action done
- uint8_t sr = TWSR & 0xf8;
- if (sr != 0x08 && sr != 0x10) {
- return false;
- }
- TWDR = (address << 1) | (read ? 1 : 0); // address + R/nW
- TWCR = (1 << TWINT) | (1 << TWEN); // send address/RW
- while (!(TWCR & (1 << TWINT))) {}; // wait until last action done
- sr = TWSR & 0xf8;
- if ((!read && sr != 0x18) || (read && sr != 0x40)) {
- return false;
- }
- return true;
-}
-
-bool I2cDevice::stop () {
- TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
- while (TWCR & ( 1 << TWSTO));
- return true;
-}
-
+++ /dev/null
-#ifndef I2C_DEVICE
-#define I2C_DEVICE
-
-#include <stdint.h>
-
-class I2cDevice {
- public:
- static void end ();
-
- public:
- I2cDevice ();
- bool begin (uint8_t addr);
- bool write(const uint8_t *buffer, uint8_t len);
- bool write_then_read(const uint8_t *write_buffer, uint8_t write_len, uint8_t *read_buffer, uint8_t read_len);
- bool writeByteAndBuffer (uint8_t byte, const uint8_t *buffer, uint8_t len);
-
- private:
- uint8_t address;
- bool start (bool read);
- bool stop ();
- bool writeBytes (const uint8_t *buffer, uint8_t len);
- bool readBytes (uint8_t *buffer, uint8_t len);
-};
-
-extern I2cDevice i2cDevice;
-
-#endif
\ No newline at end of file
--- /dev/null
+#include <avr/io.h>
+#include <stdio.h>
+
+#include "i2cmaster.hpp"
+
+I2cMaster::I2cMaster () {
+ address = 0;
+ timer = 0;
+}
+
+void I2cMaster::tick1ms () {
+ if (timer > 0) {
+ timer--;
+ }
+}
+
+bool I2cMaster::begin (uint8_t addr) {
+ this->address = addr;
+ // TWBR = 13; // 100kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 100000) / (2 * 100000 * 4);
+ TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4);
+ TWCR = (1 << TWEN);
+ return true;
+}
+
+void I2cMaster::end () {
+ TWCR = (1 << TWEN);
+ TWBR = 0;
+}
+
+bool I2cMaster::read (uint8_t *buffer, uint8_t len) {
+ if (start(true)) {
+ if (readBytes(buffer, len)) {
+ if (stop()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+bool I2cMaster::write (const uint8_t *buffer, uint8_t len) {
+ if (start(false)) {
+ if (writeBytes(buffer, len)) {
+ if (stop()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool I2cMaster::writeByteAndBuffer (uint8_t byte, const uint8_t *buffer, uint8_t len) {
+ if (start(false)) {
+ do {
+ TWDR = byte;
+ TWCR = (1 << TWINT) | (1 << TWEN); // send byte
+ while (!(TWCR & (1 << TWINT))) {}; // wait until last action done
+ if ((TWSR & 0xf8) != 0x28) {
+ return false;
+ }
+ byte = *buffer++;
+ } while (len-- > 0);
+ return true;
+ }
+ return false;
+}
+
+
+bool I2cMaster::write_then_read (const uint8_t *write_buffer, uint8_t write_len, uint8_t *read_buffer, uint8_t read_len) {
+ if (start(false)) {
+ if (writeBytes(write_buffer, write_len)) {
+ if (start(true)) {
+ if (readBytes(read_buffer, read_len)) {
+ if (stop()) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+// -------------------------------------------------------------
+
+bool I2cMaster::readBytes (uint8_t *buffer, uint8_t len) {
+ while (len-- > 0) {
+ if (len > 0) {
+ TWCR = (1 << TWEA) | (1 << TWINT) | (1 << TWEN); // read data byte with ACK enabled
+ } else {
+ TWCR = (1 << TWINT) | (1 << TWEN); // read data byte with ACK disabled
+ }
+ while (!(TWCR & (1 << TWINT))) {}; // wait until last action done
+ uint8_t sr = TWSR & 0xf8;
+ if ((len > 0 && sr != 0x50) || (len == 0 && sr != 0x58)) {
+ return false;
+ }
+ *buffer++ = TWDR;
+ }
+ return true;
+}
+
+bool I2cMaster::writeBytes (const uint8_t *buffer, uint8_t len) {
+ while (len-- > 0) {
+ // printf("[wB:len=%d, byte=%02x]", len + 1, *buffer);
+ TWDR = *buffer++;
+ TWCR = (1 << TWINT) | (1 << TWEN); // send data byte
+ timer = 5;
+ while (timer > 0 && !(TWCR & (1 << TWINT))) {}; // wait until last action done
+ if (!timer || (TWSR & 0xf8) != 0x28) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+bool I2cMaster::start (bool read) {
+ TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // send START condition
+ timer = 5;
+ while (timer > 0 && !(TWCR & (1 << TWINT))) {}; // wait until last action done
+ uint8_t sr = TWSR & 0xf8;
+ if (!timer || (sr != 0x08 && sr != 0x10)) {
+ return false;
+ }
+ TWDR = (address << 1) | (read ? 1 : 0); // address + R/nW
+ TWCR = (1 << TWINT) | (1 << TWEN); // send address/RW
+ timer = 5;
+ while (timer > 0 && !(TWCR & (1 << TWINT))) {}; // wait until last action done
+ sr = TWSR & 0xf8;
+ if (!timer || (!read && sr != 0x18) || (read && sr != 0x40)) {
+ return false;
+ }
+ return true;
+}
+
+bool I2cMaster::stop () {
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
+ while (TWCR & ( 1 << TWSTO));
+ return true;
+}
+
--- /dev/null
+#ifndef I2C_MASTER
+#define I2C_MASTER
+
+#include <stdint.h>
+
+class I2cMaster {
+ public:
+ static void end ();
+
+ public:
+ I2cMaster ();
+ void tick1ms ();
+ bool begin (uint8_t addr);
+ bool read (uint8_t *buffer, uint8_t len);
+ bool write(const uint8_t *buffer, uint8_t len);
+ bool write_then_read(const uint8_t *write_buffer, uint8_t write_len, uint8_t *read_buffer, uint8_t read_len);
+ bool writeByteAndBuffer (uint8_t byte, const uint8_t *buffer, uint8_t len);
+
+ private:
+ uint8_t address;
+ uint8_t timer;
+ bool start (bool read);
+ bool stop ();
+ bool writeBytes (const uint8_t *buffer, uint8_t len);
+ bool readBytes (uint8_t *buffer, uint8_t len);
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+#include <avr/io.h>
+#include <stdio.h>
+#include <util/atomic.h>
+
+#include "i2cslave.hpp"
+
+I2cSlave::I2cSlave () {
+ timer = 0;
+ fromMaster.rIndex = 0;
+ fromMaster.wIndex = 0;
+ toMaster.rIndex = 0;
+ toMaster.wIndex = 0;
+}
+
+void I2cSlave::tick1ms () {
+ if (timer > 0) {
+ timer--;
+ }
+}
+
+bool I2cSlave::begin (uint8_t addr, bool acceptGeneralCalls) {
+ if (addr > 127) {
+ return false;
+ }
+ TWAR = addr << 1 | (acceptGeneralCalls ? 1 : 0);
+ TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4);
+ TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWIE);
+ return true;
+}
+
+void I2cSlave::end () {
+ TWCR = (1 << TWEN);
+ TWBR = 0;
+}
+
+int I2cSlave::read () {
+ return getByte(fromMaster);
+}
+
+void I2cSlave::write (uint8_t byte) {
+ putByte(toMaster, byte);
+}
+
+
+void I2cSlave::putByte (RingBuffer& buffer, uint8_t byte) {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ buffer.data[buffer.wIndex++] = byte;
+ if (buffer.wIndex >= sizeof(buffer.data)) {
+ buffer.wIndex = 0;
+ }
+ if (buffer.wIndex == buffer.rIndex) {
+ buffer.rIndex++;
+ if (buffer.rIndex >= sizeof(buffer.data)) {
+ buffer.rIndex = 0;
+ }
+ }
+ }
+}
+
+int I2cSlave::getByte (RingBuffer& buffer) {
+ uint8_t b;
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ if (buffer.rIndex == buffer.wIndex) {
+ return EOF;
+ }
+ b = buffer.data[buffer.rIndex++];
+ if (buffer.rIndex >= sizeof(buffer.data)) {
+ buffer.rIndex = 0;
+ }
+ }
+ return b;
+}
+
+void I2cSlave::handleTWIIsr () {
+ uint8_t sr = TWSR & 0xf8;
+ switch (sr) {
+ case 0x80: { // Previously addressed with own SLA+W; data has been received; ACK has been returned
+ putByte(fromMaster, TWDR);
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); // no TWEA -> only one byte accepted
+ break;
+ }
+ case 0xa8: { // Own SLA+R has been received; ACK has been returned
+ int response = getByte(toMaster);;
+ TWDR = response < 0 ? 0x00 : (uint8_t)response;
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); // no TWEA -> only one byte accepted
+ break;
+ }
+ default: TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN) | (1 << TWIE); break;
+ }
+
+}
+
--- /dev/null
+#ifndef I2C_SLAVE
+#define I2C_SLAVE
+
+#include <stdint.h>
+
+class I2cSlave {
+ private:
+ typedef struct {
+ uint8_t rIndex;
+ uint8_t wIndex;
+ uint8_t data[8];
+ } RingBuffer;
+
+ public:
+ I2cSlave ();
+ void tick1ms ();
+ bool begin (uint8_t addr, bool acceptGeneralCalls);
+ void end ();
+ void handleTWIIsr ();
+ int read ();
+ void write (uint8_t byte);
+
+ private:
+ uint8_t timer;
+ RingBuffer fromMaster;
+ RingBuffer toMaster;
+ void putByte (RingBuffer& buffer, uint8_t byte);
+ int getByte (RingBuffer& buffer);
+
+};
+
+#endif
\ No newline at end of file
Uart1 uart1;
Modbus modbus;
Ieee485 ieee485;
- I2c i2cSparkfun(SparkFunEnvCombo);
- I2c i2cMaster(Master);
- I2c i2cSlave(Slave);
+ I2c i2cSparkfun(I2c::SparkFunEnvCombo);
+ I2c i2cMaster(I2c::Master);
+ I2c i2cSlave(I2c::Slave);
}
timer1ms--;
}
systemMillis++;
+ i2cMaster.tick1ms();
+ i2cSlave.tick1ms();
+ i2cSparkfun.tick1ms();
}
timer500ms++;
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
+#include <math.h>
#include "i2c.hpp"
-#include "../i2cdevice.hpp"
+#include "../adafruit/bme280.h"
#include "../main.hpp"
enabled = false;
TWCR = (1 << TWEN);
TWBR = 0;
+ ADMUX = 0;
+ ADCSRA = 0;
}
int8_t I2c::run (uint8_t subtest) {
TWBR = 28; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4);
TWBR = 100; // 50kHz (TWPS1:0 = 00), TWBR = (F_CPU - 16 * 50000) / (2 * 50000 * 4);
TWCR = (1 << TWEN);
+ ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V
+ ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128
enabled = true;
printf("init");
- } else if (subtest == 1 && mode == SparkFunEnvCombo) {
+ } else if (subtest == 1 && mode == I2c::SparkFunEnvCombo) {
printf(" BM280 ... ");
if (!bm280.begin()) {
printf("ERROR");
printf("ERROR");
return -1;
}
+ if (!ens160.setMode(ENS160_OPMODE_STD)) {
+ printf("ERROR");
+ return -1;
+ }
+ if (!ens160.set_envdata(25.0, 65)) {
+ printf("ERROR");
+ return -1;
+ }
+
printf("OK");
+ float accTemp = 0, accHumidity = 0;
+ int8_t accCount = -1;
do {
+ // BME280
float p = bm280.readPressure();
- printf("\n => pressure: %.3fhPa", (double)p);
+ printf("\n => BM280: P= %.3fbar", (double)p / 100000.0);
float t = bm280.readTemperature();
- printf(", temp: %.2f°C", (double)t);
+ printf(", T= %.2f°C", (double)t);
float h = bm280.readHumidity();
- printf(", humidity: %.2f%%", (double)h);
- } while (wait(1000) == EOF);
+ printf(", H= %.2f%%", (double)h);
- } else if (subtest == 1) {
- int key = EOF;
- uint8_t buffer[18];
- int errorCode;
- while (key == EOF) {
- printf("\n => START+WRITE -> ");
- errorCode = startWrite(0x77);
- if (errorCode > 0) {
- stop();
- printf ("ERROR (0x%04x)", errorCode);
- continue;
+ if (accCount >= 0 && !isnanf(h) && !isnan(t)) {
+ accTemp += t;
+ accHumidity += h;
+ accCount++;
}
- printf("OK");
- printf(", DATA 0xd0 ->");
- errorCode = writeByte(0xd0);
- if (errorCode > 0) {
- stop();
- printf ("ERROR (0x%04x)", errorCode);
- continue;
- }
- printf("OK");
+ bm280.setSampling(
+ Adafruit_BME280::MODE_NORMAL,
+ Adafruit_BME280::SAMPLING_X16,
+ Adafruit_BME280::SAMPLING_X16,
+ Adafruit_BME280::SAMPLING_X16,
+ Adafruit_BME280::FILTER_OFF,
+ Adafruit_BME280::STANDBY_MS_1000
+ );
- printf("\n => RESTART+READ -> ");
- errorCode = startRead(0x77);
- if (errorCode > 0) {
- stop();
- printf ("ERROR (0x%04x)", errorCode);
- continue;
+ // ENS160 only activated every 32s to avoid wrong temperature measuerment
+ // if ES160 would be continously active, the temperature would be 4°C higher
+ // -> ES160 has not enough distance to BM280
+ // This solution causes only a +0.3°C higher temperatur value
+ if (accCount < 0 || accCount >= 32) {
+ printf(" | ENS160 (");
+ if (accCount > 0) {
+ h = accHumidity / accCount;
+ t = accTemp / accCount;
+ accTemp = 0;
+ accHumidity = 0;
+ }
+ accCount = 0;
+ if (!ens160.set_envdata(t, h)) {
+ printf("E1)");
+ } else {
+ printf("%.1f°C/%.1f%%): ", (double)t, (double)h);
+ if (!ens160.setMode(ENS160_OPMODE_STD)) {
+ printf("E2");
+ } else {
+ for (uint8_t i = 0; i < 100; i++) {
+ _delay_ms(15);
+ uint8_t status;
+ if (ens160.readStatus(&status)) {
+ if (status & ENS160_DATA_STATUS_NEWDAT) {
+ ENS160_DATA data;
+ if (ens160.readData(&data)) {
+ printf(" aqi=%d(", data.aqi);
+ switch(data.aqi) {
+ case 1: printf("excellent"); break;
+ case 2: printf("good"); break;
+ case 3: printf("moderate"); break;
+ case 4: printf("poor"); break;
+ case 5: printf("unhealthy"); break;
+ default: printf("?"); break;
+ }
+ printf("), tvoc=%dppb", data.tvoc);
+ printf(", eco2=%d(", data.eco2);
+ if (data.eco2 < 400) {
+ printf("?");
+ } else if (data.eco2 < 600) {
+ printf("excellent");
+ } else if (data.eco2 < 800) {
+ printf("good");
+ } else if (data.eco2 < 1000) {
+ printf("fair");
+ } else if (data.eco2 < 1500) {
+ printf("poor");
+ } else {
+ printf("dad");
+ }
+ printf(")");
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (!ens160.setMode(ENS160_OPMODE_IDLE)) {
+ printf("E3");
+ }
+ }
}
- printf("OK");
- printf(", DATA -> ");
- errorCode = readData(1, buffer);
- if (errorCode > 0) {
- stop();
- printf ("ERROR (0x%04x)", errorCode);
- continue;
- }
- printf("OK (%02x %02x)", buffer[0], buffer[1]);
+ } while (wait(1000) == EOF);
- printf("\n => read trimming -> ");
- errorCode = startWrite(0x77);
- if (errorCode == 0) {
- errorCode = writeByte(0x88); // dig_T1
- errorCode = errorCode != 0 ? 0x1000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = startRead(0x77);
- errorCode = errorCode != 0 ? 0x2000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = readData(6, buffer);
- errorCode = errorCode != 0 ? 0x3000 | errorCode : 0;
+ } else if (subtest == 1 && mode == I2c::Master) {
+ if (!master.begin(0x01)) {
+ printf("E1");
+ return -1;
+ }
+ do {
+ uint8_t buffer[1];
+ // read poti
+ ADCSRA |= (1 << ADSC); // start ADC
+ while (ADCSRA & (1 << ADSC)) {} // wait for result
+ buffer[0] = ADCH;
+ printf("\n write 0x%02x", buffer[0]);
+ if (!master.write(buffer, 1)) {
+ printf(" -> ERROR");
}
- if (errorCode == 0) {
- // bm280.digT[0] = ((uint16_t)buffer[1] << 8) | buffer[0];
- // bm280.digT[1] = ((uint16_t)buffer[3] << 8) | buffer[2];
- // bm280.digT[2] = ((uint16_t)buffer[5] << 8) | buffer[4];
- // printf(" T(%04x %04x %04x)", bm280.digT[0], bm280.digT[1], bm280.digT[2]);
+ printf(", read ");
+ if (master.read(buffer, 1)) {
+ printf("0x%02x", buffer[0]);
} else {
- stop();
- printf("ERROR(%04x)", errorCode);
- continue;
- }
-
- printf("\n => set ctrl register f2 and f4");
- errorCode = startWrite(0x77);
- errorCode = errorCode != 0 ? 0x1000 | errorCode : 0;
- if (errorCode == 0) {
- errorCode = writeByte(0xf2); // ctl_hum
- errorCode = errorCode != 0 ? 0x2000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = writeByte(0x01); // oversampling x 1
- errorCode = errorCode != 0 ? 0x3000 | errorCode : 0;
+ printf(" -> ERROR");
}
+ } while (wait(1000) == EOF);
+ master.end();
- if (errorCode == 0) {
- errorCode = startWrite(0x77);
- errorCode = errorCode != 0 ? 0x4000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = writeByte(0xf4); // ctl_meas
- errorCode = errorCode != 0 ? 0x5000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = writeByte((3 << 4) | (3 << 2) | 3); // oversampling 1, normal mode
- errorCode = errorCode != 0 ? 0x6000 | errorCode : 0;
+ } else if (subtest == 1 && mode == I2c::Slave) {
+ if (!slave.begin(0x01, false)) {
+ printf("E1");
+ return -1;
+ }
+ do {
+ int fromMaster = slave.read();
+ if (fromMaster != EOF) {
+ ADCSRA |= (1 << ADSC); // start ADC
+ while (ADCSRA & (1 << ADSC)) {} // wait for result
+ slave.write(ADCH);
+ printf("\n => from master: 0x%02x -> to master: 0x%02x", fromMaster, ADCH);
}
-
- stop();
- _delay_us(200);
-
- do {
- if (errorCode == 0) {
- printf("\n => register 0xf7..0xff:");
- errorCode = startWrite(0x77);
- errorCode = errorCode != 0 ? 0x7000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = writeByte(0xf7);
- errorCode = errorCode != 0 ? 0x8000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = startRead(0x77);
- errorCode = errorCode != 0 ? 0x9000 | errorCode : 0;
- }
- if (errorCode == 0) {
- errorCode = readData(8, buffer);
- errorCode = errorCode != 0 ? 0xa000 | errorCode : 0;
- }
- if (errorCode == 0) {
- for (uint8_t i = 0; i < 8; i++) {
- printf(" %02x", buffer[i]);
- }
- int32_t adcT = (int32_t)( ((uint32_t)(buffer[3] << 12)) | (uint16_t)(buffer[4] << 4) | (buffer[5] >> 4) );
- int32_t t = compensateBm280T(adcT);
- printf(" T=%ld ", t);
- } else {
- printf("ERROR (%04x)", errorCode);
- break;
- }
- stop();
- key = wait(5000);
- } while (key == EOF);
-
- stop();
- printf("\n");
-
- } while (wait(5000) == EOF);
+ } while (wait(0) == EOF);
+ slave.end();
} else {
- I2cDevice::end();
printf("end");
return -1;
}
}
void I2c::handleTwiIrq () {
- TWCR |= (1 << TWINT); // clear Interrupt Request
+ if (mode == I2c::Slave) {
+ DDRD |= (1 << PD7);
+ PORTD |= (1 << PD7);
+ slave.handleTWIIsr();
+ PORTD &= ~(1 << PD7);
+ } else {
+ TWCR |= (1 << TWINT); // clear Interrupt Request
+ }
}
uint16_t I2c::startRead (uint8_t address) {
#include "../main.hpp"
#include "../adafruit/bme280.h"
#include "../adafruit/ens160.h"
-
-typedef enum I2cMode { SparkFunEnvCombo, Master, Slave } I2cMode;
+#include "../i2cmaster.hpp"
+#include "../i2cslave.hpp"
class I2c : public TestUnit {
+ public:
+ typedef enum I2cMode { SparkFunEnvCombo, Master, Slave } I2cMode;
+
private:
I2cMode mode;
Adafruit_BME280 bm280;
ScioSense_ENS160 ens160;
+ I2cMaster master;
+ I2cSlave slave;
public:
bool enabled;
public:
I2c (I2cMode mode) { enabled = false; this->mode = mode; }
+ void tick1ms () { master.tick1ms(); slave.tick1ms(); }
virtual void cleanup ();
virtual int8_t run (uint8_t subtest);
virtual const char *getName ();