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("Temperaturet");
Serial.print("Humidityt");
Serial.print("Lightt");
Serial.print("eCO2t");
Serial.print("VOCt");
Serial.print("Powert");
Serial.print("n");
// Construct the second line of the headings
Serial.print("deg Ctt");
Serial.print("%tt");
Serial.print("Luxt");
Serial.print("PPMt");
Serial.print("PPBt");
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("tt");
Serial.print(Humidity, 1);
Serial.print("tt");
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 CO2VOC 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 Rn");
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。将核心调试级别启用为至少"debug",您可以在串行监视器中看到该事件。

只是一个通知-你有很多

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
}

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

最新更新