ESP 以太网和 wifi

问题描述

我目前正在尝试使用 olimex POE esp32 设备制作传感器单元。我遇到的问题是 ESPMQTTClient 库优先考虑 wifi,因此将连接一个以太网,但不会在 wifi 下提供数据。 目的是让设备在任何一个上工作,没有以太网使用 wifi 等。

代码

    #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();
  
  // Optionnal functionnalities 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");

}

我得到的输出

    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

我希望我可以修改它来尝试以太网,然后是 wifi。 一方面希望使用MAC地址作为客户端ID的一部分!

任何帮助将不胜感激! 提前致谢!

解决方法

我在尝试将 ESPMQTTClient 与以太网和/或 WiFi 结合使用时遇到了同样的问题并停止了。

放弃 ESPMQTT 并尝试直接使用 PubSubClient 重建函数,因为它会更容易工作。 总的来说,代码几乎相同,因为 ESPMQTTClient 仅使用 PubSubClient 订阅,并且不同,您需要自己实现连接/重新连接/回调。

此外,您不会在那里建立内置 WiFi 连接,因此您也必须自己这样做,但这应该不是问题。

对于使用 ETH 或 WiFi,您最好的方法是使用 void WiFiEvent(WiFiEvent_t event) { 函数,因为它适用于 WiFi 和 ETH。启用您的核心调试级别至少为“调试”,您可以在串行监视器中看到该事件。

只是一个通知 - 你有很多

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

为什么不让函数做到这一点?

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
}

我希望这个答案能有所帮助。