我目前正在尝试使用 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();
// 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");
}
我得到的输出
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
我希望我可以修改它来尝试以太网,然后是无线网络。 一方面希望使用 MAC 地址作为客户端 ID 的一部分!
任何帮助将不胜感激! 预先感谢!
我在尝试通过以太网和/或 WiFi 使用 ESPMQTTClient 时遇到了同样的问题,然后停止了。
放弃 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
}
希望这个答案可以帮助到你。