WiFi not coming up with matter devices

Dloranger
Posts: 1
Joined: Thu Mar 14, 2024 3:02 pm

WiFi not coming up with matter devices

Postby Dloranger » Tue Apr 16, 2024 8:16 pm

I am working on creating/learning about the matter implementations using the arduino IDE with a ESP32-Wroom based design. Mostly just using a generic development kit while I wait for next gen custom pcbs to be designed and fabricated.

I am using the https://github.com/Yacubane/esp32-arduino-matter library as a launching point, and can successfully commission a thermostat device (although limits to temperature imposed by amazon will be a problem here, but that's later). During the commissioning process (Bluetooth I assume is used), I am asked for my Wi-Fi credentials which are given, and that appears to be accepted, no errors in the serial port logs that I can catch. After this point, the device is registered in my Alexa devices and data is updated so I think that is all working.

Now, I want to be able to do an http(s) over the air update based on a web server. To implement this I have implemented the unsecure implementation of https://github.com/chrisjoyce911/esp32FOTA, specifically https://github.com/chrisjoyce911/esp32F ... t_cert.ino with applicable pointers to the json, firmware type, on L27-28 to match my needs. This works as well in a stand-alone implementation.

Now I am trying to merge them, and finding that in-fact the WiFi is not connecting to my network based on the credentials acquired in the commissioning process so the update routine fails to contact the server.

How can I merge these two and get the user provided (as opposed to hard coded) WiFi credentials to bring up the WiFi network?

when I try to bring up my network manually with hard coded values (line 265 in sourcecode), I get error

Code: Select all

E (8450) esp_netif_lwip: esp_netif_new: Failed to configure netif with config=0x3ffd9104 (config or if_key is NULL or duplicate key)
assert failed: esp_netif_create_default_wifi_ap wifi_default.c:319 (netif)
Backtrace: 0x40083801:0x3ffd8ba0 0x40095b61:0x3ffd8bc0 0x4009b2f9:0x3ffd8be0 0x400f07cd:0x3ffd8d10 0x400d7e11:0x3ffd8d40 0x400d7f8e:0x3ffd8ed0 0x400d806c:0x3ffd8ef0 0x400d8824:0x3ffd8f10 0x400d2da2:0x3ffd8f30 0x400dde69:0x3ffd8f80
source code to reproduce

Code: Select all

/* there is a limitation on alexa that thermostats cannot go higher than 90F
* so they will not work for this application.  It will be reverted to a temp
* sensor and some other form of set-point comparison
*/
#include <esp_task_wdt.h>

#include <Arduino.h>
//#include <WiFi.h>
#include <esp_wifi.h>
// ----------------------------- Over The Air updates -------------------------
//#include <FS.h>
//#include <SPIFFS.h>
#include <esp32fota.h>
const char *manifest_url = "https://ics-ctrl.com/files/ArduinoFirmware/Kitchenery/fota.json";
const String VERSION = "0.0.1";
const String TYPE = "esp32-Kettle-http";
esp32FOTA esp32FOTA(TYPE, VERSION, false, true);
// -----------------------------------------------------------------------------
// ------------------------------ MATTER BEGIN ---------------------------------
// -----------------------------------------------------------------------------

// update platform.txt to change esp32 -std=gnu++11 to -std=gnu++17
// C:\Users\<user>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.14
// manually install matter library
// https://github.com/Yacubane/esp32-arduino-matter

#include <Matter.h>
#include <app/server/OnboardingCodesUtil.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <esp_matter_attribute_utils.h>
// Configure device version, vendor names, see here for comments and details
// C:\Users\<user>\Documents\Arduino\libraries\ESP32_Arduino_Matter\src\include\platform\CHIPDeviceConfig.h"
// ...
// lots more options, go see the file mentioned above
using namespace chip;
using namespace chip::app::Clusters;
using namespace esp_matter;
using namespace esp_matter::endpoint;
// Cluster and attribute ID used by Matter Temperature device
const uint32_t CLUSTER_ID_TEMP = TemperatureMeasurement::Id;
const uint32_t ATTRIBUTE_ID_TEMP = TemperatureMeasurement::Attributes::MeasuredValue::Id;
const uint16_t temperature_endpoint_id = 1;
int16_t Temper;            // formatted temperature for matter updates
int16_t Mode = 4;          //mode for the system to use under matter
int16_t HeatingTemp = 60;  //(Degrees C)
// Cluster and attribute ID used by Matter Thermostat device
const uint16_t thermostat_endpoint_id = 1;
const uint32_t CLUSTER_ID_THERM = Thermostat::Id;

esp_matter_attr_val_t matterValue;  //share variable that should be set locally prior to usage





// There is possibility to listen for various device events, related for example
// to setup process. Leaved as empty for simplicity.
static void on_device_event(const ChipDeviceEvent *event, intptr_t arg) {}
static esp_err_t on_identification(identification::callback_type_t type,
                                   uint16_t endpoint_id, uint8_t effect_id,
                                   uint8_t effect_variant, void *priv_data) {
  return ESP_OK;
}


// Listener on attribute update requests.
int newValue = 0;
static esp_err_t on_attribute_update(attribute::callback_type_t type,
                                     uint16_t endpoint_id, uint32_t cluster_id,
                                     uint32_t attribute_id,
                                     esp_matter_attr_val_t *val,
                                     void *priv_data) {
  // do something useful here
  if (type == attribute::PRE_UPDATE) {
    Serial.print("Update on endpoint: ");
    Serial.print(endpoint_id);
    Serial.print(" cluster: ");
    Serial.print(cluster_id);
    Serial.print(" attribute: ");
    Serial.print(attribute_id);
    newValue = val->val.i;
    Serial.print(" value: ");
    Serial.println(newValue);
    //.val_print(endpoint_id,cluster_id,attribute_id,*val,true);
  }
  if (endpoint_id == thermostat_endpoint_id) {
    //Serial.println("entering into endpoint ID checkpoint");
    if (cluster_id == CLUSTER_ID_THERM) {
      // Update the thermostat occupied setpoint value
      if (attribute_id == Thermostat::Attributes::OccupiedHeatingSetpoint::Id) {
        Serial.println("entering into Occupied Setpoint checkpoint");
        HeatingTemp = newValue;
      }
    }
  }
  return ESP_OK;
}


void print_endpoint_info(String clusterName, endpoint_t *endpoint) {
  uint16_t endpoint_id = endpoint::get_id(endpoint);
  Serial.print(clusterName);
  Serial.print(" has endpoint: ");
  Serial.println(endpoint_id);
}


// ------------------------------ General user timers--------------------------


#define SERIAL_BAUDRATE 115200
unsigned long sysTimer5000 = 0;
unsigned long sysTimer500 = 0;
unsigned long sysTimer50 = 0;
unsigned long sysTimer1 = 0;


// -----------------------------------------------------------------------------
// ------------------------------ADC SENSORS BEGIN -----------------------------
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --------------------- ADC SENSORS - NTC TEMP BEGIN --------------------------
// -----------------------------------------------------------------------------
#define TEMP_SENSOR_POWER_PIN 32
#define TEMP_SENSOR_PIN A3
#define TEMP_REFERENCE_RESISTANCE 10000
#define TEMP_NOMINAL_RESISTANCE 10000
#define TEMP_NOMINAL_TEMPERATURE 25
#define TEMP_B_VALUE 3950
#define ESP32_ANALOG_RESOLUTION 4095
#include "NTC_Thermistor.h"

Thermistor *thermistor;
float ntcReadTemp(bool Celsius) {
  float temp;
  // power up the power (GPIO power supply)
  digitalWrite(TEMP_SENSOR_POWER_PIN, HIGH);
  delay(3);  // need ~3ms to ramp up the capacitor due to RC time constant
  // * delay and power has been left ON as the delay causes the LCD to flicker
  thermistor = new NTC_Thermistor(
    TEMP_SENSOR_PIN,
    TEMP_REFERENCE_RESISTANCE,
    TEMP_NOMINAL_RESISTANCE,
    TEMP_NOMINAL_TEMPERATURE,
    TEMP_B_VALUE,
    ESP32_ANALOG_RESOLUTION  // <- for a thermistor calibration
  );
  if (!Celsius) {
    temp = thermistor->readFahrenheit();  // Read temperature F
  } else {
    temp = thermistor->readCelsius();  // Read temperature C
  }
  //power down the power pin
  digitalWrite(TEMP_SENSOR_POWER_PIN, LOW);
  return (temp);
}
// -----------------------------------------------------------------------------
// --------------------- ADC SENSORS - NTC TEMP END ----------------------------
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// ----------------------------- ADC SENSORS END--------------------------------
// -----------------------------------------------------------------------------


#define WLAN_SSID "Loranger_U"
#define WLAN_PASS "FFFFF00000"
void setup() {
  // some online examples thought there might be some watchdog timeouts on http,
  // give it some extra time to work.
  esp_task_wdt_init(60, true);

  // Init serial port and clean garbage
  Serial.begin(115200);
  Serial.println();
  delay(3000);  //debugging delay to allow the serial port to enumerate in windows


  //make sure the wifi is in a good state
  esp_log_level_set("wifi", ESP_LOG_INFO);  // Enable wifi driver logging
  tcpip_adapter_init();
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  ESP_ERROR_CHECK(esp_wifi_init(&cfg));


  //power pin for the NTC temp probe
  pinMode(TEMP_SENSOR_POWER_PIN, OUTPUT);


  // ------------------------------ MATTER STUFF  --------------------------------
  // Enable debug logging
  esp_log_level_set("*", ESP_LOG_ERROR);

  // Create the node (layer 2)
  node::config_t node_config;
  node_t *node = node::create(&node_config, on_attribute_update, on_identification);

  //create thermostat endpoint
  endpoint_t *therm_endpoint;
  cluster_t *therm_cluster;
  thermostat::config_t therm_config;
  therm_config.thermostat.local_temperature = 2400;

  therm_endpoint = thermostat::create(node, &therm_config, ENDPOINT_FLAG_NONE, NULL);
  print_endpoint_info("thermostat", therm_endpoint);

  uint16_t therm_endpoint_id = endpoint::get_id(therm_endpoint);
  print_endpoint_info("Thermostat_endpoint", therm_endpoint);
  // Add additional feature
  therm_cluster = cluster::get(therm_endpoint, Thermostat::Id);
  cluster::thermostat::feature::heating::config_t heating_config;

  //units of temperature are in 0.01 Celsius for matter interactions
  heating_config.abs_max_heat_setpoint_limit = 10500;
  heating_config.abs_min_heat_setpoint_limit = 1500;
  heating_config.max_heat_setpoint_limit = 10500;
  heating_config.min_heat_setpoint_limit = 1500;
  heating_config.pi_heating_demand = 0;
  heating_config.occupied_heating_setpoint = 10500;
  cluster::thermostat::feature::heating::add(therm_cluster, &heating_config);


  //set heating step size
  matterValue = esp_matter_int16(5);  //5C
  attribute::update(thermostat_endpoint_id, CLUSTER_ID_THERM, Thermostat::Attributes::SetpointChangeAmount::Id, &matterValue);

  // set operating mode to heating (default to "auto", trying to override that)
  matterValue = esp_matter_int16(4);
  attribute::update(thermostat_endpoint_id, CLUSTER_ID_THERM, Thermostat::Attributes::ThermostatRunningMode::Id, &matterValue);
  attribute::update(thermostat_endpoint_id, CLUSTER_ID_THERM, Thermostat::Attributes::SystemMode::Id, &matterValue);
  //set heating occupied setpoint temp (units of degrees C)
  matterValue = esp_matter_int16(HeatingTemp);
  attribute::update(thermostat_endpoint_id, CLUSTER_ID_THERM, Thermostat::Attributes::OccupiedHeatingSetpoint::Id, &matterValue);
  // set maximum set point
  matterValue = esp_matter_int16(HeatingTemp + 5);
  attribute::update(thermostat_endpoint_id, CLUSTER_ID_THERM, Thermostat::Attributes::AbsMaxHeatSetpointLimit::Id, &matterValue);
  attribute::update(thermostat_endpoint_id, CLUSTER_ID_THERM, Thermostat::Attributes::MaxHeatSetpointLimit::Id, &matterValue);

  // Setup DAC (this is good place to also set custom commission data, passcodes etc.)
  esp_matter::set_custom_dac_provider(chip::Credentials::Examples::GetExampleDACProvider());

  esp_matter::start(on_device_event);

  PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
}

void loop() {
  if (millis() > (sysTimer5000)) {
    sysTimer5000 = millis() + 5000;  // update timer
    esp32FOTA.setManifestURL(manifest_url);
    esp32FOTA.printConfig();
    //if (false) {
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("WIFI IS CONNECTED  -- HOORAY");
      bool OTAneeded = esp32FOTA.execHTTPcheck();
      Serial.print("OTAneeded: ");
      Serial.println(OTAneeded);
      if (OTAneeded) {
        Serial.println("OTA update is needed, running updates now");
        Serial.print("OTA update starting");
        esp32FOTA.execOTA();
        Serial.print("OTA update completed");
        ESP.restart();
      }
    } else {
      Serial.println("WIFI IS NOT CONNECTED  -- BOOOO");
      WiFi.begin(WLAN_SSID, WLAN_PASS);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }

      Serial.println("");
      Serial.println(WiFi.localIP());
    }

    if (millis() > (sysTimer500)) {
      sysTimer500 = millis() + 1500;  // update timer
      //Send temperature to Matter
      matterValue = esp_matter_int16(((75 - 32) * 5 / 9) * 100);  //scale measured value to matter input
      attribute::update(thermostat_endpoint_id, CLUSTER_ID_THERM, Thermostat::Attributes::LocalTemperature::Id, &matterValue);
    }

    if (millis() > (sysTimer50)) {
      sysTimer50 = millis() + 50;  // update timer
    }

    if (millis() > (sysTimer1)) {
      sysTimer1 = millis() + 1;  // update timer
    }
  }
}

lbernstone
Posts: 826
Joined: Mon Jul 22, 2019 3:20 pm

Re: WiFi not coming up with matter devices

Postby lbernstone » Wed Apr 17, 2024 6:31 am

My guess is a port conflict. They will both be trying to set up an httpd on port 80. Try using the OTA push example running on a different port and see if that works for you.

Who is online

Users browsing this forum: No registered users and 40 guests