Reputation: 57
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
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