From 08512fc5fa6ea028edc3da49403ed4578fbbe7f8 Mon Sep 17 00:00:00 2001 From: Louis Lagendijk Date: Sat, 19 Jan 2019 23:27:12 +0100 Subject: [PATCH] First draft of better MAX44009 detection --- sonoff/xsns_91_max44009.ino | 100 +++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 25 deletions(-) diff --git a/sonoff/xsns_91_max44009.ino b/sonoff/xsns_91_max44009.ino index 499a88eb0..e113f1e01 100644 --- a/sonoff/xsns_91_max44009.ino +++ b/sonoff/xsns_91_max44009.ino @@ -29,34 +29,47 @@ #define MAX44009_ADDR1 0x4A #define MAX44009_ADDR2 0x4B +#define MAX44009_NO_REGISTERS 8 #define REG_CONFIG 0x02 #define REG_LUMINANCE 0x03 #define MAX44009_CONTINUOUS_AUTO_MODE 0x80 // Start measurement in automatic, continous mode uint8_t max44009_address; -uint8_t max44009_addresses[] = { MAX44009_ADDR1, MAX44009_ADDR2 }; -uint8_t max44009_type = 0; +uint8_t max44009_addresses[] = { MAX44009_ADDR1, MAX44009_ADDR2, 0 }; //0 terminated list +uint8_t max44009_found = 0; uint8_t max44009_valid = 0; float max44009_illuminance = 0; char max44009_types[] = "MAX44009"; bool Max4409Read_lum(void) { - if (max44009_valid) { max44009_valid--; } - + max44009_valid = 0; /* Select luminance start register */ Wire.beginTransmission(max44009_address); Wire.write(REG_LUMINANCE); Wire.endTransmission(); - if (2 != Wire.requestFrom(max44009_address, (uint8_t)2)) { return false; } + if (2 != Wire.requestFrom(max44009_address, (uint8_t)2)) { + return false; + } byte msb = Wire.read(); byte lsb = Wire.read(); int exponent = (msb & 0xF0) >> 4; int mantissa = ((msb & 0x0F) << 4) | (lsb & 0x0F); max44009_illuminance = pow(2, exponent) * mantissa * 0.045; - max44009_valid = SENSOR_MAX_MISS; + max44009_valid = 1; + return true; +} + +bool Max4409Read_register(uint8_t regno, byte *value) { + Wire.beginTransmission(max44009_address); + Wire.write(regno); + if ((0 != Wire.endTransmission()) || + (1 != Wire.requestFrom(max44009_address, (uint8_t)1))) { + return false; + } + *value = (byte)Wire.read(); return true; } @@ -64,23 +77,63 @@ bool Max4409Read_lum(void) void Max4409Detect(void) { - if (max44009_type) { + byte reg[8]; + bool failed = false; + + if (max44009_found) { return; } - for (byte i = 0; i < sizeof(max44009_addresses); i++) { + for (byte i = 0; 0 != max44009_addresses[i]; i++) { max44009_address = max44009_addresses[i]; - Wire.beginTransmission(max44009_address); - /* select configuration register iand set mode */ - Wire.write(REG_CONFIG); - Wire.write(MAX44009_CONTINUOUS_AUTO_MODE); - if (!Wire.endTransmission()) { - max44009_type = 1; - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, max44009_types, max44009_address); + // we need to read each register separately, as auto-increment is only + // supported for illiminance registers + for (byte r = 0; r < MAX44009_NO_REGISTERS; r++) { + if (false == Max4409Read_register(r, ®[r])) { + snprintf_P(log_data, sizeof(log_data), "MAX44009 at %x: Failed to read register %d", + max44009_address, (int)r); + AddLog(LOG_LEVEL_DEBUG); + failed = true; + break; + } + } + if (failed) { + continue; + } + + snprintf_P(log_data, sizeof(log_data), "MAX44009 at %x: Read %x %x %x %x %x %x %x %x", + (int) max44009_address, (int)reg[0], (int)reg[1], (int)reg[2], (int)reg[3], + (int)reg[4], (int)reg[5], (int)reg[6], (int)reg[7]); + AddLog(LOG_LEVEL_DEBUG); + + if ( (0x00 == reg[0]) && + (0x00 == reg[1]) && + ( (0x00 == (reg[2] & 0xc0)) || (MAX44009_CONTINUOUS_AUTO_MODE == (reg[2] & 0xc0)) ) && + (0xef == reg[5]) && + (0x00 == reg[6]) && + (0xff == reg[7])) { + + // looks reasonable, try to initialize + + Wire.beginTransmission(max44009_address); + + // select configuration register and set mode + Wire.write(REG_CONFIG); + Wire.write(MAX44009_CONTINUOUS_AUTO_MODE); + if (0 == Wire.endTransmission()) { + max44009_found = 1; + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, max44009_types, max44009_address); + AddLog(LOG_LEVEL_DEBUG); + break; + } else { + snprintf_P(log_data, sizeof(log_data), "MAX44009 at %x: config failed!", max44009_address); + AddLog(LOG_LEVEL_DEBUG); + } + } else { + snprintf_P(log_data, sizeof(log_data), "Reading initial data failed: No MAX44009 at %x", max44009_address); AddLog(LOG_LEVEL_DEBUG); - break; - } + } } } @@ -92,11 +145,8 @@ void Max4409EverySecond(void) } else { // 1mS - if (max44009_type) { - if (!Max4409Read_lum()) { - AddLogMissed(max44009_types, max44009_valid); -// if (!max44009_valid) { max44009_type = 0; } - } + if (max44009_found) { + Max4409Read_lum(); } } } @@ -143,9 +193,9 @@ boolean Xsns91(byte function) if (i2c_flg) { switch (function) { - case FUNC_INIT: - Max4409Detect(); - break; +// case FUNC_INIT: +// Max4409Detect(); +// break; case FUNC_EVERY_SECOND: Max4409EverySecond(); break;