--- a/main/iotbalkon.c Tue Mar 28 11:25:46 2023 +0200 +++ b/main/iotbalkon.c Tue Mar 28 22:13:06 2023 +0200 @@ -7,13 +7,27 @@ static const char *TAG = "iotbalkon"; +#define State_Init 0 +#define State_Connect 1 +#define State_Working 2 +#define State_WorkDone 3 +#define State_Stop 4 +#define State_Wait 5 +#define State_Measure 6 +#define State_GoSleep 7 + static TaskHandle_t xTaskBMP280 = NULL; +static TaskHandle_t xTaskINA219 = NULL; + extern BMP280_State *bmp280_state; ///< I2C state extern SemaphoreHandle_t xSemaphoreBMP280; ///< I2C lock semaphore extern bmp280_params_t bmp280_params; extern bmp280_t bmp280_dev; +extern SemaphoreHandle_t xSemaphoreINA219; +extern ina219_t ina219_b_dev; +extern ina219_t ina219_s_dev; void app_main(void) @@ -29,6 +43,8 @@ bmp280_init_default_params(&bmp280_params); memset(&bmp280_dev, 0, sizeof(bmp280_t)); + memset(&ina219_b_dev, 0, sizeof(ina219_t)); + memset(&ina219_s_dev, 0, sizeof(ina219_t)); i2c_dev_t dev = { 0 }; dev.cfg.sda_io_num = CONFIG_I2C_MASTER_SDA; @@ -41,10 +57,14 @@ } dev.addr = 0x40; if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) { + ESP_ERROR_CHECK(ina219_init_desc(&ina219_b_dev, 0x40, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL)); + ESP_ERROR_CHECK(ina219_init(&ina219_b_dev)); ESP_LOGI(TAG, "Found INA219 Battery"); } dev.addr = 0x41; if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) { + ESP_ERROR_CHECK(ina219_init_desc(&ina219_s_dev, 0x41, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL)); + ESP_ERROR_CHECK(ina219_init(&ina219_s_dev)); ESP_LOGI(TAG, "Found INA219 Solar"); } dev.addr = 0x76; @@ -52,10 +72,13 @@ ESP_ERROR_CHECK(bmp280_init_desc(&bmp280_dev, BMP280_I2C_ADDRESS_0, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL)); ESP_ERROR_CHECK(bmp280_init(&bmp280_dev, &bmp280_params)); ESP_LOGI(TAG, "Found BMP280 @ 0x76 id: 0x%02x", bmp280_dev.id); - } - dev.addr = 0x77; - if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) { - ESP_LOGI(TAG, "Found BMP280 @ 0x77"); + } else { + dev.addr = 0x77; + if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) { + ESP_ERROR_CHECK(bmp280_init_desc(&bmp280_dev, BMP280_I2C_ADDRESS_1, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL)); + ESP_ERROR_CHECK(bmp280_init(&bmp280_dev, &bmp280_params)); + ESP_LOGI(TAG, "Found BMP280 @ 0x77 id: 0x%02x", bmp280_dev.id); + } } /* @@ -64,13 +87,238 @@ xSemaphoreBMP280 = xSemaphoreCreateMutex(); xTaskCreate(&task_bmp280, "task_bmp280", 2560, NULL, 8, &xTaskBMP280); + xTaskCreate(&task_ina219, "task_ina219", 2560, NULL, 8, &xTaskINA219); /* * Main application loop. */ + int State = State_Init; + int OldState = State_Init + 1; + while (1) { - request_bmp280(); - vTaskDelay(2000 / portTICK_PERIOD_MS); + if (OldState != State) { + ESP_LOGI(TAG, "Switch to state %d", State); + OldState = State; + } + switch (State) { + case State_Init: request_bmp280(); + request_ina219(); + // getTempBaro(); + // getLightValues(); + // getVoltsCurrent(); + State = State_Connect; + break; + + case State_Connect: // Wake WiFi ?? + // if (NetworkConnect()) { + // State = State_Working; + // Alarm &= ~AL_NOWIFI; + // DisCounter = 0; + // } else { + // DisCounter++; + // if (DisCounter > 30) { + // Alarm |= AL_NOWIFI; + // } + // delay(2000); + // } + break; + + case State_Working: // WorkAgain = false; + // client.loop(); + + // // Measure + // getVoltsCurrent(); + // solarVolts = solarCurrent = batteryVolts = batteryCurrent = 0; + // loops = 0; + // totalTime = 0; + // for (int i = 0; i < loopno; i++) { + /* + * If there are only 2 loops, and the flag that we came from deep-sleep is set + * then assume the following: + * 1. No current (or very low for the dc converter) during DS_TIME seconds. + * 2. Low power during 0.5 second (no WiFi yet). + * 3. 5 seconds power usage for the last measurement. + * Calculate the average battery current from this. + * + * If there are more loops and we came from continues running do the following: + * 1. Take the current use from all exept the last one, weight loops * 10 seconds. + * 2. Take the last one, and weight for 5 seconds. + * Calculate the average battery current from this. + */ + // if (m_Valid[i]) { + // solarVolts += s_Volts[i]; + // solarCurrent += s_Current[i]; + // batteryVolts += b_Volts[i]; + // if (i == (loopno - 1)) { + // // Add the extra time + // m_Time[i] += SUB_TIME; + // } + // batteryCurrent += b_Current[i] * m_Time[i]; + // totalTime += m_Time[i]; + // loops++; + // } + // } + + // if (EEPROM.read(EM_DS_Active)) { + // totalTime += EEPROM.read(EM_DS_Time) * 1000; + // batteryCurrent += DS_CURRENT * EEPROM.read(EM_DS_Time) * 1000; + // // Serial.printf("Added %d totalTime %d\n", EEPROM.read(EM_DS_Time) * 1000, totalTime); + // } + + // If valid measurements + // if (loops) { + // solarVolts = solarVolts / loops; + // solarCurrent = solarCurrent / loops; + // solarPower = solarVolts * solarCurrent; + // batteryVolts = batteryVolts / loops; + // batteryCurrent = batteryCurrent / totalTime; + // batteryPower = batteryVolts * batteryCurrent; + // BatteryState(batteryVolts, (0 - batteryCurrent) + solarCurrent); + + // //#if Debug == true + // Serial.print(F(" Solar Volts: ")); + // Serial.print(solarVolts, 4); + // Serial.print(F("V Current: ")); + // Serial.print(solarCurrent, 4); + // Serial.print(F("mA Power: ")); + // Serial.print(solarPower, 4); + // Serial.println(F("mW")); + + // Serial.print(F("Battery Volts: ")); + // Serial.print(batteryVolts, 4); + // Serial.print(F("V Current: ")); + // Serial.print(batteryCurrent, 4); + // Serial.print(F("mA Power: ")); + // Serial.print(batteryPower, 4); + // Serial.print(F("mW Capacity ")); + // Serial.print(batteryState); + // Serial.println(F("%")); + // //#endif + + /* Check alarm conditions */ + // if (batteryState <= 10) { + // Alarm |= AL_ACCULOW; + // } else { + // Alarm &= ~AL_ACCULOW; + // } + // } + // getTempHumi(); + // Publish(); + // Subscribe + // #if Production == true + // client.subscribe("balkon/output/set/#"); + // #else + // client.subscribe("wemos/output/set/#"); + // #endif + // client.loop(); + // State = State_WorkDone; + // gTimeNext = millis() + SUB_TIME; + break; + + case State_WorkDone: // Hang around for a while to process the subscriptions. + // client.loop(); + // delay(1); + // if (WorkAgain) { + // // Some command was executed. + // State = State_Working; + // } + // if (gTimeInMillis > gTimeNext) { + // State = State_Stop; + // } + break; + + case State_Stop: // #if Production == true + // client.unsubscribe("balkon/output/set/#"); + // #else + // client.unsubscribe("wemos/output/set/#"); + // #endif + // delay(1); + // client.loop(); + // client.disconnect(); + // delay(1); + // WiFi.mode( WIFI_OFF ); + // // Reset values for average current measurement. + // HaveIP = false; + // loopno = 0; + // gLastTime = millis(); + // delay(10); + // #if defined(ARDUINO_ESP8266_WEMOS_D1MINI) + // WiFi.forceSleepBegin(0); // 0 == forever + // #endif + + /* + * If any output is on, use 6 10 seconds loops. + * If nothing on, do a deep sleep. + */ + // if (EEPROM.read(EM_Relay1) || EEPROM.read(EM_Relay2) || EEPROM.read(EM_Dimmer3) || EEPROM.read(EM_Dimmer4)) { + // if (EEPROM.read(EM_DS_Active)) { + // EEPROM.write(EM_DS_Active, 0); + // EEPROM.commit(); + // } + + // // Active mode, 60 seconds loop + // ST_LOOPS = 6; + // gTimeNext = millis() + ST_INTERVAL; + // #if Debug == true + // Serial.println(F("Start sleeploops")); + // #endif + // State = State_Wait; + // } else { + // ds_time = DS_TIME; + // if (solarVolts < 6) { + // // At night, increase the deep-sleep time. + // ds_time *= 4; + // } + // if ((! EEPROM.read(EM_DS_Active)) || (EEPROM.read(EM_DS_Time) != ds_time)) { + // EEPROM.write(EM_DS_Active, 1); + // EEPROM.write(EM_DS_Time, ds_time); + // EEPROM.commit(); + // Serial.println("wrote new deep-sleep settings"); + // } + // State = State_GoSleep; + // } + /* + * Update CRC and write rtcData. + */ + // rtcData.crc32 = calculateCRC32((uint8_t*) &rtcData.data, sizeof(rtcData)-4); + // #if defined(ARDUINO_ESP8266_WEMOS_D1MINI) + // if (ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData, sizeof(rtcData))) { + // #if Debug == true + // Serial.print("Write: "); + // printMemory(); + // #endif + // } else { + // Serial.println("Write error rtcData"); + // } + // #endif + break; + + case State_Wait: // if (gTimeInMillis > gTimeNext) { + // State = State_Measure; + // } + break; + + case State_Measure: // getVoltsCurrent(); + // if (isnan(Temperature)) { + // getTempHumi(); + // } + // gTimeNext = millis() + ST_INTERVAL; + // if (loopno >= ST_LOOPS) { + // getLightValues(); + // State = State_Connect; + // } else { + // State = State_Wait; + // } + break; + + case State_GoSleep: // ds_time = EEPROM.read(EM_DS_Time); + // #if Debug == true + // Serial.printf("Going to deep-sleep for %d seconds\n", ds_time); + // #endif + // ESP.deepSleep(ds_time * 1e6); + break; + } + vTaskDelay(20 / portTICK_PERIOD_MS); } // Not reached. }