--- a/main/iotbalkon.c Thu Mar 30 17:05:05 2023 +0200 +++ b/main/iotbalkon.c Thu Mar 30 21:55:24 2023 +0200 @@ -24,6 +24,8 @@ #define MAX_LOOPS 32 +float temperature; +float pressure; RTC_DATA_ATTR float solarVolts, solarCurrent, solarPower; RTC_DATA_ATTR float batteryVolts, batteryCurrent, batteryPower; RTC_DATA_ATTR int batteryState; @@ -34,8 +36,11 @@ RTC_DATA_ATTR bool m_Valid[MAX_LOOPS + 1]; RTC_DATA_ATTR unsigned long m_Time[MAX_LOOPS + 1]; RTC_DATA_ATTR unsigned long gLastTime; // millis() -RTC_DATA_ATTR uint8_t loopno; -RTC_DATA_ATTR uint8_t loops; + +uint8_t loopno = 0; +uint8_t loops = 0; + +int DisCounter = 0; extern BMP280_State *bmp280_state; ///< I2C state extern SemaphoreHandle_t xSemaphoreBMP280; ///< I2C lock semaphore @@ -44,6 +49,7 @@ extern SemaphoreHandle_t xSemaphoreINA219; extern ina219_t ina219_b_dev; extern ina219_t ina219_s_dev; +extern INA219_State *ina219_state; extern SemaphoreHandle_t xSemaphoreWiFi; extern WIFI_State *wifi_state; ///< WiFi state @@ -165,6 +171,87 @@ +/* + * Read the temperature and pressure from the BMP280. + */ +void getTempBaro() { + temperature = 20; + pressure = 1000; + + request_bmp280(); + + while (! ready_bmp280()) { + vTaskDelay(10 / portTICK_PERIOD_MS); + } + + if (xSemaphoreTake(xSemaphoreBMP280, 25) == pdTRUE) { + temperature = bmp280_state->temperature; + pressure = bmp280_state->pressure / 100.0; + ESP_LOGI(TAG, "Temperature: %.3f Pressure: %.1f hPa\n", temperature, pressure); + xSemaphoreGive(xSemaphoreBMP280); + } else { + ESP_LOGE(TAG, "Can't lock xSemaphoreBMP280"); + } +} + + + +/* + * Read voltage and current from both INA219 boards. The results + * are stored in an array so that we later can average the results. + */ +void getVoltsCurrent() { + + request_ina219(); + + while (! ready_ina219()) { + vTaskDelay(10 / portTICK_PERIOD_MS); + } + + if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) { + + s_Volts[loopno] = ina219_state->Solar.volts + (ina219_state->Solar.shunt / 1000); + s_Current[loopno] = ina219_state->Solar.current; + b_Volts[loopno] = ina219_state->Battery.volts + (ina219_state->Battery.shunt / 1000); + b_Current[loopno] = ina219_state->Battery.current; + m_Valid[loopno] = ina219_state->valid; + xSemaphoreGive(xSemaphoreINA219); + + /* + * Check for crazy values + */ + if ((b_Volts[loopno] < 10) || (b_Volts[loopno] > 15.0)) { + m_Valid[loopno] = false; + } + if ((b_Current[loopno] < 0) || (b_Current[loopno] > 2000)) { + m_Valid[loopno] = false; + } + if (s_Volts[loopno] < 0) { + s_Volts[loopno] = 0.0; + } + if (s_Volts[loopno] > 24) { + m_Valid[loopno] = false; + } + if (s_Current[loopno] < 0) { + s_Current[loopno] = 0.0; + } + if (s_Current[loopno] > 2000) { + m_Valid[loopno] = false; + } + } + + // m_Time[loopno] = millis() - gLastTime; + //gLastTime = millis(); + + ESP_LOGI(TAG, "Measure: %d Valid: %s Solar: %.4fV %.4fmA Battery: %.4fV %.4fmA time %ld", + loopno, (m_Valid[loopno]) ? "true":"false", s_Volts[loopno], s_Current[loopno], b_Volts[loopno], b_Current[loopno], m_Time[loopno]); + + if (loopno < (MAX_LOOPS - 1)) + loopno++; +} + + + void app_main(void) { #ifdef CONFIG_CODE_PRODUCTION @@ -244,34 +331,33 @@ OldState = State; } switch (State) { - case State_Init: request_bmp280(); - request_ina219(); - // getTempBaro(); + case State_Init: getTempBaro(); // getLightValues(); - // getVoltsCurrent(); + getVoltsCurrent(); State = State_Connect; + DisCounter = 0; request_WiFi(true); 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); - // } + case State_Connect: if (ready_WiFi() && ready_mqtt()) { + State = State_Working; + Alarm &= ~AL_NOWIFI; + DisCounter = 0; + } else { + DisCounter++; + if (DisCounter > 30) { + Alarm |= AL_NOWIFI; + request_WiFi(false); + State = State_Init; + } + vTaskDelay(2000 / portTICK_PERIOD_MS); + } break; case State_Working: // WorkAgain = false; - // client.loop(); - // // Measure - // getVoltsCurrent(); + // Measure + getVoltsCurrent(); solarVolts = solarCurrent = solarPower = batteryVolts = batteryCurrent = batteryPower = 0; // loops = 0; // totalTime = 0; @@ -329,15 +415,8 @@ Alarm &= ~AL_ACCULOW; } // } - // getTempHumi(); + getTempBaro(); // 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; @@ -354,19 +433,10 @@ // } 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 ); + case State_Stop: request_WiFi(false); // // Reset values for average current measurement. // HaveIP = false; - // loopno = 0; + loopno = 0; // gLastTime = millis(); // delay(10); // #if defined(ARDUINO_ESP8266_WEMOS_D1MINI) @@ -425,7 +495,7 @@ // } break; - case State_Measure: // getVoltsCurrent(); + case State_Measure: getVoltsCurrent(); // if (isnan(Temperature)) { // getTempHumi(); // }