Paddy
Paddy

Reputation: 57

ESP ethernet and wifi

I am currently trying to make a sensor unit using the olimex POE esp32 device. the problem I'm running into is that the ESPMQTTClient library is prioritising wifi and therefore will connect one ethernet but won't provide data down wifi.

The aim is to have the device work on either, no ethernet use wifi etc.

The code

#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
#define ETH_PHY_POWER 12
#include <ETH.h>
#include "EspMQTTClient.h"
#include <Wire.h>
#include <WiFi.h>

EspMQTTClient client(
  "SSID",
  "password",
  "50X.50X.50X.50X",  // MQTT Broker server ip  "test.mosquitto.org"
  "XXXXXXXXX",   // Can be omitted if not needed
  "XXXXXXXXX",   // Can be omitted if not needed
  "testMultiSensor",     // Client name that uniquely identify your device
  1883              // The MQTT port, default to 1883. this line can be omitted
);
String MAC = "";
static bool eth_connected = false;
String SN = "123456";
String jsonString = "";
String jsonString1 = "";
char charBuf[256];
char charBuf1[256];
char jsonchar[256];
unsigned char buf[20];
unsigned char opt_sensors;
int incomingByte = 0;
int loopCount = 0;
char showTemp = 0, showHum = 0, showLight = 0, showSound = 0, degCorf = 0, showCO2 = 0, showVOC = 0, showPwr = 0, showEvents = 0;
String sampPeriodTxt;
float sampPeriod = 1;

void WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_ETH_START:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("LiteIP-MultiSensor");
      break;
    case SYSTEM_EVENT_ETH_CONNECTED:
      Serial.println("ETH Connected");
      break;
    case SYSTEM_EVENT_ETH_GOT_IP:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
    case SYSTEM_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case SYSTEM_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

void setup()
{
  MAC = WiFi.macAddress();
  Wire.begin();
  Serial.begin(115200);
  WiFi.onEvent(WiFiEvent);
  ETH.begin();
  
  // Optional functionalities of EspMQTTClient : 
  client.enableDebuggingMessages(); // Enable debugging messages sent to serial output
  client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overrited with enableHTTPWebUpdater("user", "password").
  client.enableLastWillMessage("TestClient/lastwill", "I am going offline");  // You can activate the retain flag by setting the third parameter to true
  Serial.println();
  Serial.print("MAC: ");
  Serial.println(WiFi.macAddress());
  MAC = WiFi.macAddress();

}

// This function is called once everything is connected (Wifi and MQTT)
// WARNING : YOU MUST IMPLEMENT IT IF YOU USE EspMQTTClient
void onConnectionEstablished()
{
}

void restart_info() {

  // Data and basic information are acquired from the module
  Wire.beginTransmission(0x2A); // transmit to device
  Wire.write(byte(0x80));       // sends instruction to read firmware version
  Wire.endTransmission();       // stop transmitting
  Wire.requestFrom(0x2A, 1);    // request byte from slave device
  unsigned char fw_ver = Wire.read(); // receive a byte

  Wire.beginTransmission(0x2A); // transmit to device
  Wire.write(byte(0x81));       // sends instruction to read firmware subversion
  Wire.endTransmission();       // stop transmitting
  Wire.requestFrom(0x2A, 1);    // request byte from slave device
  unsigned char fw_sub_ver = Wire.read(); // receive a byte

  Wire.beginTransmission(0x2A); // transmit to device
  Wire.write(byte(0x82));       // sends instruction to read optional sensors byte
  Wire.endTransmission();       // stop transmitting
  Wire.requestFrom(0x2A, 1);    // request byte from slave device
  opt_sensors = Wire.read();     // receive a byte

  delay(1000);

  //If device contains additional CO2 and audio sensor, it is indicated here
  Serial.print("AmbiMate sensors: 4 core");
  if (opt_sensors & 0x01)
    Serial.print(" + CO2");
  if (opt_sensors & 0x04)
    Serial.print(" + Audio");
  Serial.println(" ");

  Serial.print("AmbiMate Firmware version ");
  Serial.print(fw_ver);
  Serial.print(".");
  Serial.println(fw_sub_ver);

  
  sampPeriod = 15000;//sampPeriod * 1000;   // convert to mSecs
}

//Top line of headings are printed using the following
void printLabels(void) {

  Serial.println(" ");
  Serial.println(" ");
  // Construct the first line of the headings
    Serial.print("Temperature\t");
    Serial.print("Humidity\t");
    Serial.print("Light\t");
    Serial.print("eCO2\t");
    Serial.print("VOC\t");
    Serial.print("Power\t");
    Serial.print("\n");
    // Construct the second line of the headings
    Serial.print("deg C\t\t");
    Serial.print("%\t\t");
    Serial.print("Lux\t");
    Serial.print("PPM\t");
    Serial.print("PPB\t");
    Serial.print("volts");
    Serial.print("\n");
}

//Loop starts here 
void loop() {
  client.loop();
  if (loopCount == 0)
  {
    restart_info();
    loopCount = 1;
  }
  if (loopCount == 1)
  {
    printLabels();
    loopCount = 2;
  }
  // All sensors except the CO2 sensor are scanned in response to this command
  Wire.beginTransmission(0x2A); // transmit to device
  // Device address is specified in datasheet
  Wire.write(byte(0xC0));       // sends instruction to read sensors in next byte
  Wire.write(0xFF);             // 0xFF indicates to read all connected sensors
  Wire.endTransmission();       // stop transmitting
  // Delay to make sure all sensors are scanned by the AmbiMate
  delay(100);

  Wire.beginTransmission(0x2A); // transmit to device
  Wire.write(byte(0x00));       // sends instruction to read sensors in next byte
  Wire.endTransmission();       // stop transmitting
  Wire.requestFrom(0x2A, 15);    // request 6 bytes from slave device

  // Acquire the Raw Data
  unsigned int i = 0;
  while (Wire.available()) { // slave may send less than requested
    buf[i] = Wire.read(); // receive a byte as character and store in buffer
    i++;
  }

  // convert the raw data to engineering units, see application spec for more information 
  unsigned int status = buf[0];
  float temperatureC = (buf[1] * 256.0 + buf[2]) / 10.0;
  float temperatureF = ((temperatureC * 9.0) / 5.0) + 32.0;
  float Humidity = (buf[3] * 256.0 + buf[4]) / 10.0;
  unsigned int light = (buf[5] * 256.0 + buf[6]);
  unsigned int audio = (buf[7] * 256.0 + buf[8]);
  float batVolts = ((buf[9] * 256.0 + buf[10]) / 1024.0) * (3.3 / 0.330);
  unsigned int co2_ppm = (buf[11] * 256.0 + buf[12]);
  unsigned int voc_ppm = (buf[13] * 256.0 + buf[14]);

    Serial.print(temperatureC, 1);
    Serial.print("\t\t");
    Serial.print(Humidity, 1);
    Serial.print("\t\t");
    Serial.print(light);
    Serial.print("\t");
    Serial.print(co2_ppm);
    Serial.print("\t");
    Serial.print(voc_ppm);
    Serial.print("\t");
    Serial.print(batVolts);
    Serial.print("\t");
    Serial.print("\n");

  jsonString = "[{\"MAC\":\"" + MAC + "\",\"temp\":" + temperatureC + ",\"Humidity\":" + Humidity + ",\"light\":" + light + ",\"batVolts\":" + batVolts + ",\"co2_ppm\":" + co2_ppm + ",\"voc_ppm\":" + voc_ppm + "}]";

  // all sensors except the CO2\VOC sensor are scanned at this rate.
  // CO2/VOC sensor is only updated in AmbiMate every 60 seconds
  delay(sampPeriod - 100);
  incomingByte = Serial.read();

  if ((incomingByte == 'R') || (incomingByte == 'r'))
  {
    //Serial.print("Got R\n");
    loopCount = 0;
  }
  
  Serial.print("\n");
  //Serial.print(jsonString);
  //Serial.print("\n");
  client.publish("Liteip/BMS/multisense", jsonString);
  Serial.print("\n");
  Serial.print("MQTT PUBBED");
  Serial.print("\n");

}

The output I'm getting

    rst:0x1 (POWERON_RESET),boot:0x1b (S
MAC: ETH Started
C4:DD:57:60:E9:XX
AmbiMate sensors: 4 core + CO2 
AmbiMate Firmware version 2.8
 
 
Temperature Humidity    Light   eCO2    VOC Power   
deg C       %       Lux PPM PPB volts
25.3        40.9        142 2704    351 3.34    
ETH Connected
ETH MAC: C4:DD:57:60:E9:XX, IPv4: 192.168.1.28, FULL_DUPLEX, 100Mbps

MQTT! Trying to publish when disconnected, skipping.

MQTT PUBBED

WiFi: Connecting to 50X.50X.50X.50X ... (31.256000s) 
25.3        39.2        205 2970    391 3.33

I'm hoping I can mod this to try ethernet, then wifi. a side hope is to use the MAC address as part of the client ID!

Any help would be greatly appreciated! thanks in advance!

Upvotes: 0

Views: 1288

Answers (1)

Daniel Do
Daniel Do

Reputation: 151

I had the same problem trying to use ESPMQTTClient with Ethernet and/or WiFi and stopped.

Discard ESPMQTT and try to rebuild the functions with PubSubClient directly as it will work much easier. Overall the code is pretty much the same because ESPMQTTClient uses PubSubClient only the subscribe and is different and you need to implement connection/reconnect/callback yourself.

Also you won't have inbuild WiFi connection in there so you have to do that yourself aswell but that shouldn't be a problem.

For using either ETH or WiFi your best way is to use the void WiFiEvent(WiFiEvent_t event) { function as it works for WiFi and ETH. Enable your core debug level to atleast 'debug' and you can see the event in the serial monitor.

Just a notice - You have tons of

Wire.beginTransmission(0x2A); 
Wire.write(byte(0xC0));       // sends instruction to read sensors in next byte
Wire.write(0xFF);             // 0xFF indicates to read all connected sensors
Wire.endTransmission();       // stop transmitting

why not make function that does that?

void writeI2C(uint16_t i2c_addr, uint16_t i2c_register, uint16_t value){
  Wire.beginTransmission(i2c_addr);
  Wire.write(i2c_register);
  Wire.write(value);
  return Wire.endTransmission(); //For error catching
}

I hope this answer could help.

Upvotes: 2

Related Questions