Wed, 29 Mar 2023 21:39:07 +0200
Added Wifi task.
/** * @file iotbalkon.c * @brief iotbalkon project. */ #include "config.h" 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; static TaskHandle_t xTaskWifi = 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; extern SemaphoreHandle_t xSemaphoreWiFi; extern WIFI_State *wifi_state; ///< WiFi state void app_main(void) { #ifdef CONFIG_CODE_PRODUCTION ESP_LOGI(TAG, "Starting production"); #endif #ifdef CONFIG_CODE_TESTING ESP_LOGI(TAG, "Starting testing"); #endif ESP_ERROR_CHECK(i2cdev_init()); 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; dev.cfg.scl_io_num = CONFIG_I2C_MASTER_SCL; dev.cfg.master.clk_speed = 1000000; dev.addr = 0x39; if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) { ESP_LOGI(TAG, "Found ADPS-9930"); } 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; if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) { 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); } 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); } } /* * Create FreeRTOS tasks */ xSemaphoreBMP280 = xSemaphoreCreateMutex(); xSemaphoreINA219 = xSemaphoreCreateMutex(); xTaskCreate(&task_bmp280, "task_bmp280", 2560, NULL, 8, &xTaskBMP280); xTaskCreate(&task_ina219, "task_ina219", 2560, NULL, 8, &xTaskINA219); xTaskCreate(&task_wifi, "task_wifi", 4096, NULL, 3, &xTaskWifi); vTaskDelay(10 / portTICK_PERIOD_MS); /* * Main application loop. */ int State = State_Init; int OldState = State_Init + 1; while (1) { 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; 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); // } 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. }