Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
05dd3165ec | |||
2e8aaedf54 | |||
023e557014 | |||
5e433458c7 | |||
34eddf58ce | |||
655e8f6861 | |||
8935590aeb | |||
e581e4e3b1 | |||
1a467521e6 | |||
71dd0747d2 | |||
0ec1895128 | |||
67632ef43e |
@ -24,6 +24,7 @@
|
|||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/SPI}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/SPI}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/WiFi}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/WiFi}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/LiquidCrystal}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/LiquidCrystal}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/MQTT}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="it.baeyens.arduino.compiler.cpp.sketch.input.416726280" name="CPP source files" superClass="it.baeyens.arduino.compiler.cpp.sketch.input"/>
|
<inputType id="it.baeyens.arduino.compiler.cpp.sketch.input.416726280" name="CPP source files" superClass="it.baeyens.arduino.compiler.cpp.sketch.input"/>
|
||||||
</tool>
|
</tool>
|
||||||
@ -31,6 +32,7 @@
|
|||||||
<option id="it.baeyens.arduino.compiler.c.sketch.option.incpath.1559551443" name="Include Paths (-I)" superClass="it.baeyens.arduino.compiler.c.sketch.option.incpath" valueType="includePath">
|
<option id="it.baeyens.arduino.compiler.c.sketch.option.incpath.1559551443" name="Include Paths (-I)" superClass="it.baeyens.arduino.compiler.c.sketch.option.incpath" valueType="includePath">
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/arduino/core}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/arduino/core}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/arduino/variant}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/arduino/variant}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/WiModbusGateway/MQTT}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="it.baeyens.arduino.compiler.c.sketch.input.83886313" name="C Source Files" superClass="it.baeyens.arduino.compiler.c.sketch.input"/>
|
<inputType id="it.baeyens.arduino.compiler.c.sketch.input.83886313" name="C Source Files" superClass="it.baeyens.arduino.compiler.c.sketch.input"/>
|
||||||
</tool>
|
</tool>
|
||||||
@ -43,8 +45,9 @@
|
|||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="LiquidCrystal|WiFi|SPI|Libraries/*/?xamples|Libraries/*/?xtras" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
<entry excluding="MQTT|LiquidCrystal|WiFi|SPI|Libraries/*/?xamples|Libraries/*/?xtras" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="LiquidCrystal"/>
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="LiquidCrystal"/>
|
||||||
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTT"/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="SPI"/>
|
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="SPI"/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="WiFi"/>
|
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="WiFi"/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
|
@ -151,10 +151,10 @@ environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA
|
|||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.DTS/value=3600
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.DTS/value=3600
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/delimiter=\:
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/delimiter=\:
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/operation=replace
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/operation=replace
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/value=1430496628
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.LOCAL/value=1431979958
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/delimiter=\:
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/delimiter=\:
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/operation=replace
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/operation=replace
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/value=1430489428
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.UTC/value=1431972758
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/delimiter=\:
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/delimiter=\:
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/operation=replace
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/operation=replace
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/value=3600
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/A.EXTRA.TIME.ZONE/value=3600
|
||||||
@ -355,7 +355,7 @@ environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.
|
|||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARD_NAME/value=Arduino Mega or Mega 2560
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.BOARD_NAME/value=Arduino Mega or Mega 2560
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/delimiter=\:
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/delimiter=\:
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/operation=replace
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/operation=replace
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/value=/dev/tty.usbmodemfa131
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PORT/value=/dev/tty.usbmodemfd111
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/delimiter=\:
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/delimiter=\:
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/operation=replace
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/operation=replace
|
||||||
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/value=Default
|
environment/project/it.baeyens.arduino.core.toolChain.release.1600398586/JANTJE.COM_PROGMR/value=Default
|
||||||
|
365
MQTT/PubSubClient.cpp
Executable file
365
MQTT/PubSubClient.cpp
Executable file
@ -0,0 +1,365 @@
|
|||||||
|
/*
|
||||||
|
PubSubClient.cpp - A simple client for MQTT.
|
||||||
|
Nicholas O'Leary
|
||||||
|
http://knolleary.net
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PubSubClient.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
PubSubClient::PubSubClient(Client& client) {
|
||||||
|
this->_client = &client;
|
||||||
|
}
|
||||||
|
|
||||||
|
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, void (*callback)(char*,uint8_t*,unsigned int), Client& client) {
|
||||||
|
this->_client = &client;
|
||||||
|
this->callback = callback;
|
||||||
|
this->ip = ip;
|
||||||
|
this->port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
PubSubClient::PubSubClient(char* domain, uint16_t port, void (*callback)(char*,uint8_t*,unsigned int), Client& client) {
|
||||||
|
this->_client = &client;
|
||||||
|
this->callback = callback;
|
||||||
|
this->domain = domain;
|
||||||
|
this->port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::connect(char *id) {
|
||||||
|
return connect(id,NULL,NULL,0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::connect(char *id, char *user, char *pass) {
|
||||||
|
return connect(id,user,pass,0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::connect(char *id, char* willTopic, uint8_t willQos, uint8_t willRetain, char* willMessage)
|
||||||
|
{
|
||||||
|
return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::connect(char *id, char *user, char *pass, char* willTopic, uint8_t willQos, uint8_t willRetain, char* willMessage) {
|
||||||
|
// if (!connected()) {
|
||||||
|
if (true) {
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if (domain != NULL) {
|
||||||
|
result = _client->connect(this->domain, this->port);
|
||||||
|
} else {
|
||||||
|
result = _client->connect(this->ip, this->port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
nextMsgId = 1;
|
||||||
|
uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p',MQTTPROTOCOLVERSION};
|
||||||
|
// Leave room in the buffer for header and variable length field
|
||||||
|
uint16_t length = 5;
|
||||||
|
unsigned int j;
|
||||||
|
for (j = 0;j<9;j++) {
|
||||||
|
buffer[length++] = d[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t v;
|
||||||
|
if (willTopic) {
|
||||||
|
v = 0x06|(willQos<<3)|(willRetain<<5);
|
||||||
|
} else {
|
||||||
|
v = 0x02;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user != NULL) {
|
||||||
|
v = v|0x80;
|
||||||
|
|
||||||
|
if(pass != NULL) {
|
||||||
|
v = v|(0x80>>1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[length++] = v;
|
||||||
|
|
||||||
|
buffer[length++] = ((MQTT_KEEPALIVE) >> 8);
|
||||||
|
buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF);
|
||||||
|
length = writeString(id,buffer,length);
|
||||||
|
if (willTopic) {
|
||||||
|
length = writeString(willTopic,buffer,length);
|
||||||
|
length = writeString(willMessage,buffer,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user != NULL) {
|
||||||
|
length = writeString(user,buffer,length);
|
||||||
|
if(pass != NULL) {
|
||||||
|
length = writeString(pass,buffer,length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write(MQTTCONNECT,buffer,length-5);
|
||||||
|
|
||||||
|
lastInActivity = lastOutActivity = millis();
|
||||||
|
|
||||||
|
while (!_client->available()) {
|
||||||
|
unsigned long t = millis();
|
||||||
|
if (t-lastInActivity > MQTT_KEEPALIVE*1000UL) {
|
||||||
|
_client->stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint16_t len = readPacket();
|
||||||
|
|
||||||
|
if (len == 4 && buffer[3] == 0) {
|
||||||
|
lastInActivity = millis();
|
||||||
|
pingOutstanding = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_client->stop();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t PubSubClient::readByte() {
|
||||||
|
while(!_client->available()) {}
|
||||||
|
return _client->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t PubSubClient::readPacket() {
|
||||||
|
uint16_t len = 0;
|
||||||
|
buffer[len++] = readByte();
|
||||||
|
uint8_t multiplier = 1;
|
||||||
|
uint16_t length = 0;
|
||||||
|
uint8_t digit = 0;
|
||||||
|
do {
|
||||||
|
digit = readByte();
|
||||||
|
buffer[len++] = digit;
|
||||||
|
length += (digit & 127) * multiplier;
|
||||||
|
multiplier *= 128;
|
||||||
|
} while ((digit & 128) != 0);
|
||||||
|
|
||||||
|
for (uint16_t i = 0;i<length;i++)
|
||||||
|
{
|
||||||
|
if (len < MQTT_MAX_PACKET_SIZE) {
|
||||||
|
buffer[len++] = readByte();
|
||||||
|
} else {
|
||||||
|
readByte();
|
||||||
|
len = 0; // This will cause the packet to be ignored.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::loop() {
|
||||||
|
if (connected()) {
|
||||||
|
unsigned long t = millis();
|
||||||
|
if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) {
|
||||||
|
if (pingOutstanding) {
|
||||||
|
_client->stop();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
buffer[0] = MQTTPINGREQ;
|
||||||
|
buffer[1] = 0;
|
||||||
|
_client->write(buffer,2);
|
||||||
|
lastOutActivity = t;
|
||||||
|
lastInActivity = t;
|
||||||
|
pingOutstanding = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_client->available()) {
|
||||||
|
uint16_t len = readPacket();
|
||||||
|
if (len > 0) {
|
||||||
|
lastInActivity = t;
|
||||||
|
uint8_t type = buffer[0]&0xF0;
|
||||||
|
if (type == MQTTPUBLISH) {
|
||||||
|
if (callback) {
|
||||||
|
uint16_t tl = (buffer[2]<<8)+buffer[3];
|
||||||
|
char topic[tl+1];
|
||||||
|
for (uint16_t i=0;i<tl;i++) {
|
||||||
|
topic[i] = buffer[4+i];
|
||||||
|
}
|
||||||
|
topic[tl] = 0;
|
||||||
|
// ignore msgID - only support QoS 0 subs
|
||||||
|
uint8_t *payload = buffer+4+tl;
|
||||||
|
callback(topic,payload,len-4-tl);
|
||||||
|
}
|
||||||
|
} else if (type == MQTTPINGREQ) {
|
||||||
|
buffer[0] = MQTTPINGRESP;
|
||||||
|
buffer[1] = 0;
|
||||||
|
_client->write(buffer,2);
|
||||||
|
} else if (type == MQTTPINGRESP) {
|
||||||
|
pingOutstanding = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::publish(char* topic, char* payload) {
|
||||||
|
return publish(topic,(uint8_t*)payload,strlen(payload),false);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::publish(char* topic, uint8_t* payload, unsigned int plength) {
|
||||||
|
return publish(topic, payload, plength, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::publish(char* topic, uint8_t* payload, unsigned int plength, boolean retained) {
|
||||||
|
if (connected()) {
|
||||||
|
// Leave room in the buffer for header and variable length field
|
||||||
|
uint16_t length = 5;
|
||||||
|
length = writeString(topic,buffer,length);
|
||||||
|
uint16_t i;
|
||||||
|
for (i=0;i<plength;i++) {
|
||||||
|
buffer[length++] = payload[i];
|
||||||
|
}
|
||||||
|
uint8_t header = MQTTPUBLISH;
|
||||||
|
if (retained) {
|
||||||
|
header |= 1;
|
||||||
|
}
|
||||||
|
// Serial.print("pub len: "); Serial.println(length-5);
|
||||||
|
return write(header,buffer,length-5);
|
||||||
|
} else {
|
||||||
|
// Serial.println("connection lost");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::publish_P(char* topic, uint8_t* PROGMEM payload, unsigned int plength, boolean retained) {
|
||||||
|
uint8_t llen = 0;
|
||||||
|
uint8_t digit;
|
||||||
|
int rc;
|
||||||
|
uint16_t tlen;
|
||||||
|
int pos = 0;
|
||||||
|
int i;
|
||||||
|
uint8_t header;
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
|
if (!connected()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tlen = strlen(topic);
|
||||||
|
|
||||||
|
header = MQTTPUBLISH;
|
||||||
|
if (retained) {
|
||||||
|
header |= 1;
|
||||||
|
}
|
||||||
|
buffer[pos++] = header;
|
||||||
|
len = plength + 2 + tlen;
|
||||||
|
do {
|
||||||
|
digit = len % 128;
|
||||||
|
len = len / 128;
|
||||||
|
if (len > 0) {
|
||||||
|
digit |= 0x80;
|
||||||
|
}
|
||||||
|
buffer[pos++] = digit;
|
||||||
|
llen++;
|
||||||
|
} while(len>0);
|
||||||
|
|
||||||
|
pos = writeString(topic,buffer,pos);
|
||||||
|
|
||||||
|
rc += _client->write(buffer,pos);
|
||||||
|
|
||||||
|
for (i=0;i<plength;i++) {
|
||||||
|
rc += _client->write((char)pgm_read_byte_near(payload + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
lastOutActivity = millis();
|
||||||
|
return rc == len + 1 + plength;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
|
||||||
|
uint8_t lenBuf[4];
|
||||||
|
uint8_t llen = 0;
|
||||||
|
uint8_t digit;
|
||||||
|
uint8_t pos = 0;
|
||||||
|
uint8_t rc;
|
||||||
|
uint8_t len = length;
|
||||||
|
do {
|
||||||
|
digit = len % 128;
|
||||||
|
len = len / 128;
|
||||||
|
if (len > 0) {
|
||||||
|
digit |= 0x80;
|
||||||
|
}
|
||||||
|
lenBuf[pos++] = digit;
|
||||||
|
llen++;
|
||||||
|
} while(len>0);
|
||||||
|
|
||||||
|
buf[4-llen] = header;
|
||||||
|
for (int i=0;i<llen;i++) {
|
||||||
|
buf[5-llen+i] = lenBuf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serial.print("write len: "); Serial.println(length+1+llen);
|
||||||
|
// size_t olen = length + 1 + llen;
|
||||||
|
// rc = _client->write(buf+(4-llen),length+1+llen);
|
||||||
|
|
||||||
|
const size_t SEND_AT_ONCE = 64;
|
||||||
|
size_t remains = length + 1 + llen;
|
||||||
|
// Serial.print("write len: "); Serial.println(remains);
|
||||||
|
const uint8_t *writebuf = buf + (4 - llen);
|
||||||
|
bool result = true;
|
||||||
|
while ((remains > 0) && result) {
|
||||||
|
size_t actuallySendChars = (remains > SEND_AT_ONCE) ? SEND_AT_ONCE : remains;
|
||||||
|
// Serial.print("tbs: "); Serial.println(actuallySendChars);
|
||||||
|
size_t sentChars = _client->write(writebuf, actuallySendChars);
|
||||||
|
result = sentChars == actuallySendChars;
|
||||||
|
remains -= sentChars;
|
||||||
|
writebuf += sentChars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lastOutActivity = millis();
|
||||||
|
// return (rc == 1+llen+length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean PubSubClient::subscribe(char* topic) {
|
||||||
|
if (connected()) {
|
||||||
|
// Leave room in the buffer for header and variable length field
|
||||||
|
uint16_t length = 7;
|
||||||
|
nextMsgId++;
|
||||||
|
if (nextMsgId == 0) {
|
||||||
|
nextMsgId = 1;
|
||||||
|
}
|
||||||
|
buffer[0] = (nextMsgId >> 8);
|
||||||
|
buffer[1] = (nextMsgId & 0xFF);
|
||||||
|
length = writeString(topic, buffer,length);
|
||||||
|
buffer[length++] = 0; // Only do QoS 0 subs
|
||||||
|
return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-5);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PubSubClient::disconnect() {
|
||||||
|
buffer[0] = MQTTDISCONNECT;
|
||||||
|
buffer[1] = 0;
|
||||||
|
_client->write(buffer,2);
|
||||||
|
_client->stop();
|
||||||
|
lastInActivity = lastOutActivity = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t PubSubClient::writeString(char* string, uint8_t* buf, uint16_t pos) {
|
||||||
|
char* idp = string;
|
||||||
|
uint16_t i = 0;
|
||||||
|
pos += 2;
|
||||||
|
while (*idp) {
|
||||||
|
buf[pos++] = *idp++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
buf[pos-i-2] = (i >> 8);
|
||||||
|
buf[pos-i-1] = (i & 0xFF);
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean PubSubClient::connected() {
|
||||||
|
int rc = (int)_client->connected();
|
||||||
|
//Serial.print("rc: "); Serial.println(rc);
|
||||||
|
if (!rc) {
|
||||||
|
//Serial.println("would stop");
|
||||||
|
_client->stop();
|
||||||
|
// while (true);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
75
MQTT/PubSubClient.h
Executable file
75
MQTT/PubSubClient.h
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
PubSubClient.h - A simple client for MQTT.
|
||||||
|
Nicholas O'Leary
|
||||||
|
http://knolleary.net
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PubSubClient_h
|
||||||
|
#define PubSubClient_h
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "Client.h"
|
||||||
|
|
||||||
|
// MQTT_MAX_PACKET_SIZE : Maximum packet size
|
||||||
|
#define MQTT_MAX_PACKET_SIZE 256
|
||||||
|
|
||||||
|
// MQTT_KEEPALIVE : keepAlive interval in Seconds
|
||||||
|
#define MQTT_KEEPALIVE 15
|
||||||
|
|
||||||
|
#define MQTTPROTOCOLVERSION 3
|
||||||
|
#define MQTTCONNECT 1 << 4 // Client request to connect to Server
|
||||||
|
#define MQTTCONNACK 2 << 4 // Connect Acknowledgment
|
||||||
|
#define MQTTPUBLISH 3 << 4 // Publish message
|
||||||
|
#define MQTTPUBACK 4 << 4 // Publish Acknowledgment
|
||||||
|
#define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1)
|
||||||
|
#define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2)
|
||||||
|
#define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3)
|
||||||
|
#define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request
|
||||||
|
#define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment
|
||||||
|
#define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request
|
||||||
|
#define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment
|
||||||
|
#define MQTTPINGREQ 12 << 4 // PING Request
|
||||||
|
#define MQTTPINGRESP 13 << 4 // PING Response
|
||||||
|
#define MQTTDISCONNECT 14 << 4 // Client is Disconnecting
|
||||||
|
#define MQTTReserved 15 << 4 // Reserved
|
||||||
|
|
||||||
|
#define MQTTQOS0 (0 << 1)
|
||||||
|
#define MQTTQOS1 (1 << 1)
|
||||||
|
#define MQTTQOS2 (2 << 1)
|
||||||
|
|
||||||
|
class PubSubClient {
|
||||||
|
private:
|
||||||
|
Client* _client;
|
||||||
|
uint8_t buffer[MQTT_MAX_PACKET_SIZE];
|
||||||
|
uint16_t nextMsgId;
|
||||||
|
unsigned long lastOutActivity;
|
||||||
|
unsigned long lastInActivity;
|
||||||
|
bool pingOutstanding;
|
||||||
|
void (*callback)(char*,uint8_t*,unsigned int);
|
||||||
|
uint16_t readPacket();
|
||||||
|
uint8_t readByte();
|
||||||
|
boolean write(uint8_t header, uint8_t* buf, uint16_t length);
|
||||||
|
uint16_t writeString(char* string, uint8_t* buf, uint16_t pos);
|
||||||
|
uint8_t *ip;
|
||||||
|
char* domain;
|
||||||
|
uint16_t port;
|
||||||
|
public:
|
||||||
|
PubSubClient(Client& client);
|
||||||
|
PubSubClient(uint8_t *, uint16_t, void(*)(char*,uint8_t*,unsigned int),Client& client);
|
||||||
|
PubSubClient(char*, uint16_t, void(*)(char*,uint8_t*,unsigned int),Client& client);
|
||||||
|
boolean connect(char *);
|
||||||
|
boolean connect(char *, char *, char *);
|
||||||
|
boolean connect(char *, char *, uint8_t, uint8_t, char *);
|
||||||
|
boolean connect(char *, char *, char *, char *, uint8_t, uint8_t, char*);
|
||||||
|
void disconnect();
|
||||||
|
boolean publish(char *, char *);
|
||||||
|
boolean publish(char *, uint8_t *, unsigned int);
|
||||||
|
boolean publish(char *, uint8_t *, unsigned int, boolean);
|
||||||
|
boolean publish_P(char *, uint8_t PROGMEM *, unsigned int, boolean);
|
||||||
|
boolean subscribe(char *);
|
||||||
|
boolean loop();
|
||||||
|
boolean connected();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -13,7 +13,7 @@
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
VOLTAGE,
|
VOLTAGE,
|
||||||
FREQUENCY,
|
COSPHI,
|
||||||
CURRENT,
|
CURRENT,
|
||||||
POWER,
|
POWER,
|
||||||
ENERGY,
|
ENERGY,
|
||||||
@ -25,46 +25,42 @@ Packet packets[TOTAL_NO_OF_PACKETS];
|
|||||||
|
|
||||||
// Mudbus *modbusSlave;
|
// Mudbus *modbusSlave;
|
||||||
|
|
||||||
uint16_t voltage[2];
|
uint16_t voltage;
|
||||||
uint16_t frequency[2];
|
uint16_t cosphi;
|
||||||
uint16_t current[2];
|
uint16_t current;
|
||||||
uint16_t power[2];
|
uint16_t power;
|
||||||
uint16_t energy[2];
|
uint16_t energy[2];
|
||||||
|
|
||||||
float startEnergy = 0;
|
float startEnergy = 0;
|
||||||
|
|
||||||
float convF(uint16_t in[2]) {
|
|
||||||
union {
|
float getVoltage() { return (float)voltage; }
|
||||||
struct {
|
float getCurrent() { return (float)current * 0.1; }
|
||||||
uint16_t a;
|
float getCosPhi() { return (float)cosphi * 0.01; }
|
||||||
uint16_t b;
|
float getPower() { return (float)power * 0.01; }
|
||||||
} s;
|
|
||||||
float f;
|
float getEnergy() {
|
||||||
} U;
|
uint32_t v = ((uint32_t)energy[1]) + (((uint32_t)energy[0]) << 16);
|
||||||
U.s.a = in[1];
|
float vv = ((float)v) * 0.01;
|
||||||
U.s.b = in[0];
|
return vv;
|
||||||
return U.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float getVoltage() { return convF(voltage); }
|
float getNewEnergy() { return getEnergy() - startEnergy; }
|
||||||
float getCurrent() { return convF(current); }
|
|
||||||
float getFrequency() { return convF(frequency); }
|
|
||||||
float getPower() { return convF(power); }
|
|
||||||
float getEnergy() { return convF(energy); }
|
|
||||||
float getNewEnergy() { return convF(energy) - startEnergy; }
|
|
||||||
|
|
||||||
|
|
||||||
// void modbusAppBegin(Mudbus *mb) {
|
// void modbusAppBegin(Mudbus *mb) {
|
||||||
void modbusAppBegin() {
|
void modbusAppBegin() {
|
||||||
pinMode(ZEROING_PIN, INPUT_PULLUP);
|
|
||||||
// modbusSlave = mb;
|
// modbusSlave = mb;
|
||||||
|
|
||||||
|
|
||||||
modbus_construct(&packets[VOLTAGE], 1, READ_HOLDING_REGISTERS, 0x2000, 2, voltage);
|
|
||||||
modbus_construct(&packets[FREQUENCY], 1, READ_HOLDING_REGISTERS, 0x2020, 2, frequency);
|
|
||||||
modbus_construct(&packets[CURRENT], 1, READ_HOLDING_REGISTERS, 0x2060, 2, current);
|
modbus_construct(&packets[VOLTAGE], MODBUS_ADDRESS, READ_HOLDING_REGISTERS, 35, 1, &voltage);
|
||||||
modbus_construct(&packets[POWER], 1, READ_HOLDING_REGISTERS, 0x2080, 2, power);
|
modbus_construct(&packets[COSPHI], MODBUS_ADDRESS, READ_HOLDING_REGISTERS, 39, 1, &cosphi);
|
||||||
modbus_construct(&packets[ENERGY], 1, READ_HOLDING_REGISTERS, 0x3000, 2, energy);
|
modbus_construct(&packets[CURRENT], MODBUS_ADDRESS, READ_HOLDING_REGISTERS, 36, 1, ¤t);
|
||||||
|
modbus_construct(&packets[POWER], MODBUS_ADDRESS, READ_HOLDING_REGISTERS, 37, 1, &power);
|
||||||
|
modbus_construct(&packets[ENERGY], MODBUS_ADDRESS, READ_HOLDING_REGISTERS, 27, 2, energy);
|
||||||
|
// modbus_construct(&packets[POWER], MODBUS_ADDRESS, READ_HOLDING_REGISTERS, 1, 1, &power);
|
||||||
|
|
||||||
|
|
||||||
modbus_configure(&Serial2, MODBUS_BAUD, SERIAL_8N2, MODBUS_TIMEOUT,
|
modbus_configure(&Serial2, MODBUS_BAUD, SERIAL_8N2, MODBUS_TIMEOUT,
|
||||||
@ -75,7 +71,7 @@ void modbusAppExec() {
|
|||||||
modbus_update();
|
modbus_update();
|
||||||
|
|
||||||
float nEnergy = getEnergy();
|
float nEnergy = getEnergy();
|
||||||
if (((0 == startEnergy) && (0 != nEnergy)) || (digitalRead(ZEROING_PIN) == 0)) {
|
if ((0 == startEnergy) && (0 != nEnergy)) {
|
||||||
startEnergy = nEnergy;
|
startEnergy = nEnergy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,13 +14,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const uint32_t MODBUS_BAUD = 1200;
|
const uint32_t MODBUS_BAUD = 9600;
|
||||||
const uint16_t MODBUS_TIMEOUT = 10000;
|
const uint16_t MODBUS_TIMEOUT = 10000;
|
||||||
const uint16_t MODBUS_SCANRATE = 1000;
|
const uint16_t MODBUS_SCANRATE = 1000;
|
||||||
const uint8_t MODBUS_RETRY_COUNT = 25;
|
const uint8_t MODBUS_RETRY_COUNT = 25;
|
||||||
const uint8_t MODBUS_TX_ENABLE_PIN = 2;
|
const uint8_t MODBUS_TX_ENABLE_PIN = 2;
|
||||||
const uint8_t ZEROING_PIN = 3;
|
const uint8_t MODBUS_ADDRESS = 1;
|
||||||
|
|
||||||
|
|
||||||
// void modbusAppBegin(Mudbus *mb);
|
// void modbusAppBegin(Mudbus *mb);
|
||||||
void modbusAppBegin();
|
void modbusAppBegin();
|
||||||
@ -28,7 +27,7 @@ void modbusAppExec();
|
|||||||
|
|
||||||
float getVoltage();
|
float getVoltage();
|
||||||
float getCurrent();
|
float getCurrent();
|
||||||
float getFrequency();
|
float getCosPhi();
|
||||||
float getPower();
|
float getPower();
|
||||||
float getEnergy();
|
float getEnergy();
|
||||||
float getNewEnergy();
|
float getNewEnergy();
|
||||||
|
@ -201,12 +201,15 @@ void waiting_for_turnaround()
|
|||||||
// get the serial data from the buffer
|
// get the serial data from the buffer
|
||||||
void waiting_for_reply()
|
void waiting_for_reply()
|
||||||
{
|
{
|
||||||
|
// Serial.println("A0");
|
||||||
if ((*ModbusPort).available()) // is there something to check?
|
if ((*ModbusPort).available()) // is there something to check?
|
||||||
{
|
{
|
||||||
|
//Serial.println("A1");
|
||||||
unsigned char overflowFlag = 0;
|
unsigned char overflowFlag = 0;
|
||||||
buffer = 0;
|
buffer = 0;
|
||||||
while ((*ModbusPort).available())
|
while ((*ModbusPort).available())
|
||||||
{
|
{
|
||||||
|
//Serial.println("A2");
|
||||||
// The maximum number of bytes is limited to the serial buffer size
|
// The maximum number of bytes is limited to the serial buffer size
|
||||||
// of BUFFER_SIZE. If more bytes is received than the BUFFER_SIZE the
|
// of BUFFER_SIZE. If more bytes is received than the BUFFER_SIZE the
|
||||||
// overflow flag will be set and the serial buffer will be read until
|
// overflow flag will be set and the serial buffer will be read until
|
||||||
@ -220,7 +223,7 @@ void waiting_for_reply()
|
|||||||
overflowFlag = 1;
|
overflowFlag = 1;
|
||||||
|
|
||||||
frame[buffer] = (*ModbusPort).read();
|
frame[buffer] = (*ModbusPort).read();
|
||||||
// Serial.print("R: "); Serial.println(frame[buffer], 16);
|
//Serial.print("R: "); Serial.println(frame[buffer], 16);
|
||||||
buffer++;
|
buffer++;
|
||||||
}
|
}
|
||||||
// This is not 100% correct but it will suffice.
|
// This is not 100% correct but it will suffice.
|
||||||
@ -504,7 +507,7 @@ void sendPacket(unsigned char bufferSize)
|
|||||||
digitalWrite(TxEnablePin, HIGH);
|
digitalWrite(TxEnablePin, HIGH);
|
||||||
|
|
||||||
for (unsigned char i = 0; i < bufferSize; i++) {
|
for (unsigned char i = 0; i < bufferSize; i++) {
|
||||||
// Serial.print("S: "); Serial.println(frame[i],16);
|
//Serial.print("S: "); Serial.println(frame[i],16);
|
||||||
(*ModbusPort).write(frame[i]);
|
(*ModbusPort).write(frame[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +161,8 @@ void WiFiClient::stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WiFiClient::connected() {
|
uint8_t WiFiClient::connected() {
|
||||||
|
// Serial.print("sock: "); Serial.println(_sock);
|
||||||
|
// Serial.print("status: "); Serial.println(status());
|
||||||
|
|
||||||
if (_sock == 255) {
|
if (_sock == 255) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include "WiModbusGateway.h"
|
||||||
|
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <WiFiUDP.h>
|
#include <WiFiUDP.h>
|
||||||
@ -8,26 +10,43 @@
|
|||||||
#include "ModbusApp.h"
|
#include "ModbusApp.h"
|
||||||
#include "PString.h"
|
#include "PString.h"
|
||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
|
#include "PubSubClient.h"
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t WIFI_ENABLE_PIN = 3;
|
||||||
|
|
||||||
|
|
||||||
LiquidCrystal lcd = LiquidCrystal(A0, A1, A2, A3, A4, A5);
|
LiquidCrystal lcd = LiquidCrystal(A0, A1, A2, A3, A4, A5);
|
||||||
|
|
||||||
// Mudbus Mb;
|
// Mudbus Mb;
|
||||||
WiFiUDP udpSock;
|
// WiFiUDP udpSock;
|
||||||
|
WiFiClient wifiClient;
|
||||||
|
//byte server[] = { 192, 168, 87, 100 };
|
||||||
|
//byte server[] = { 172, 16, 2, 16 };
|
||||||
|
char server[] = "mqttbroker";
|
||||||
|
PubSubClient client(server, 1883, callback, wifiClient);
|
||||||
|
uint8_t disconnectState = 0;
|
||||||
|
uint32_t disconnectTime = 0;
|
||||||
|
|
||||||
|
|
||||||
//char ssid[] = "Kinderland"; // your network SSID (name)
|
// char ssid[] = "Kinderland"; // your network SSID (name)
|
||||||
//char pass[] = "test1234"; // your network password
|
// char pass[] = "test1234"; // your network password
|
||||||
char ssid[] = "MessWLAN";
|
char ssid[] = "MessWLAN";
|
||||||
char pass[] = "UNVmpwbr6heQnMQ7ykXT";
|
char pass[] = "UNVmpwbr6heQnMQ7ykXT";
|
||||||
|
|
||||||
Metro tick = Metro(10000);
|
Metro minute = Metro(60000);
|
||||||
Metro second = Metro(1000);
|
Metro second = Metro(1000);
|
||||||
uint32_t uptime;
|
uint32_t uptime;
|
||||||
|
|
||||||
|
static bool wifiEnabled = false;
|
||||||
|
|
||||||
|
|
||||||
|
void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
|
// handle message arrived
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void printWifiStatus() {
|
void printWifiStatus() {
|
||||||
// print the SSID of the network you're attached to:
|
// print the SSID of the network you're attached to:
|
||||||
Serial.print("SSID: ");
|
Serial.print("SSID: ");
|
||||||
@ -49,6 +68,11 @@ void printWifiStatus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
pinMode(WIFI_ENABLE_PIN, INPUT_PULLUP);
|
||||||
|
delay(500);
|
||||||
|
wifiEnabled = (digitalRead(WIFI_ENABLE_PIN) != 0);
|
||||||
|
|
||||||
|
|
||||||
Serial.begin(57600);
|
Serial.begin(57600);
|
||||||
while (!Serial) {
|
while (!Serial) {
|
||||||
; // wait for serial port to connect. Needed for Leonardo only
|
; // wait for serial port to connect. Needed for Leonardo only
|
||||||
@ -62,46 +86,62 @@ void setup() {
|
|||||||
lcd.print("Starting ...");
|
lcd.print("Starting ...");
|
||||||
|
|
||||||
|
|
||||||
|
if (wifiEnabled) {
|
||||||
|
// check for the presence of the shield:
|
||||||
|
if (WiFi.status() == WL_NO_SHIELD) {
|
||||||
|
Serial.println("WiFi shield not present");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("WiFi shield not present");
|
||||||
|
// don't continue:
|
||||||
|
while(true);
|
||||||
|
}
|
||||||
|
|
||||||
// check for the presence of the shield:
|
int status = WL_IDLE_STATUS;
|
||||||
if (WiFi.status() == WL_NO_SHIELD) {
|
while ( status != WL_CONNECTED) {
|
||||||
Serial.println("WiFi shield not present");
|
Serial.print("Attempting to connect to SSID: ");
|
||||||
lcd.setCursor(0, 1);
|
Serial.println(ssid);
|
||||||
lcd.print("WiFi shield not present");
|
lcd.setCursor(0, 1);
|
||||||
// don't continue:
|
lcd.print("Trying: ");
|
||||||
while(true);
|
lcd.print(ssid);
|
||||||
|
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
|
||||||
|
status = WiFi.begin(ssid, pass);
|
||||||
|
|
||||||
|
// wait 10 seconds for connection:
|
||||||
|
delay(10000);
|
||||||
|
}
|
||||||
|
Serial.println("Connected.");
|
||||||
|
lcd.setCursor(0, 2);
|
||||||
|
lcd.print("Connected.");
|
||||||
|
|
||||||
|
printWifiStatus();
|
||||||
|
|
||||||
|
// if (! client.connect("WiFiPowerMeter")) {
|
||||||
|
// Serial.println("MQTT broker not found");
|
||||||
|
// lcd.home();
|
||||||
|
// lcd.clear();
|
||||||
|
// lcd.print("MQTT broker not found");
|
||||||
|
// while (true);
|
||||||
|
// } else {
|
||||||
|
// lcd.print(" *");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = WL_IDLE_STATUS;
|
delay(1000);
|
||||||
while ( status != WL_CONNECTED) {
|
|
||||||
Serial.print("Attempting to connect to SSID: ");
|
|
||||||
Serial.println(ssid);
|
|
||||||
lcd.setCursor(0, 1);
|
|
||||||
lcd.print("Trying: ");
|
|
||||||
lcd.print(ssid);
|
|
||||||
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
|
|
||||||
status = WiFi.begin(ssid, pass);
|
|
||||||
|
|
||||||
// wait 10 seconds for connection:
|
|
||||||
delay(10000);
|
|
||||||
}
|
|
||||||
Serial.println("Connected.");
|
|
||||||
lcd.setCursor(0, 2);
|
|
||||||
lcd.print("Connected.");
|
|
||||||
|
|
||||||
printWifiStatus();
|
|
||||||
|
|
||||||
|
|
||||||
delay(10000);
|
|
||||||
lcd.home();
|
lcd.home();
|
||||||
lcd.clear();
|
lcd.clear();
|
||||||
|
|
||||||
|
disconnectState = 3;
|
||||||
|
disconnectTime = millis();
|
||||||
|
|
||||||
|
|
||||||
// uptime = (uint32_t*) &(Mb.R[121]); // uptime
|
// uptime = (uint32_t*) &(Mb.R[121]); // uptime
|
||||||
uptime = 0;
|
uptime = 0;
|
||||||
|
|
||||||
// Mb.R[123] = 0xdead; // magic
|
// Mb.R[123] = 0xdead; // magic
|
||||||
// Mb.R[124] = 0xbeef;
|
// Mb.R[124] = 0xbeef;
|
||||||
|
|
||||||
|
wdt_enable(WDTO_8S);
|
||||||
|
|
||||||
|
|
||||||
// modbusAppBegin(&Mb);
|
// modbusAppBegin(&Mb);
|
||||||
modbusAppBegin();
|
modbusAppBegin();
|
||||||
@ -110,10 +150,12 @@ void setup() {
|
|||||||
|
|
||||||
void updateDisplay() {
|
void updateDisplay() {
|
||||||
static uint32_t lastUptime = 0;
|
static uint32_t lastUptime = 0;
|
||||||
|
static uint8_t lastDisconnectState = 0;
|
||||||
|
|
||||||
|
|
||||||
if (uptime != lastUptime) {
|
if ((disconnectState != lastDisconnectState) || (uptime != lastUptime)) {
|
||||||
lastUptime = uptime;
|
lastUptime = uptime;
|
||||||
|
lastDisconnectState = disconnectState;
|
||||||
lcd.home(); lcd.clear();
|
lcd.home(); lcd.clear();
|
||||||
|
|
||||||
uint32_t days = uptime / 86400;
|
uint32_t days = uptime / 86400;
|
||||||
@ -123,87 +165,111 @@ void updateDisplay() {
|
|||||||
uint32_t minutes = rem / 60;
|
uint32_t minutes = rem / 60;
|
||||||
uint32_t seconds = rem % 60;
|
uint32_t seconds = rem % 60;
|
||||||
lcd.setCursor(0,0);
|
lcd.setCursor(0,0);
|
||||||
lcd.print(days); lcd.print("d "); lcd.print(hours); lcd.print(":");
|
lcd.print(days); lcd.print("/"); lcd.print(hours); lcd.print(":");
|
||||||
lcd.print(minutes); lcd.print(":"); lcd.print(seconds); lcd.print(" ");
|
lcd.print(minutes); lcd.print(":"); lcd.print(seconds); lcd.print(" ");
|
||||||
|
|
||||||
long rssi = WiFi.RSSI();
|
if (wifiEnabled) {
|
||||||
lcd.print(rssi); lcd.print(" ");
|
long rssi = WiFi.RSSI();
|
||||||
uint8_t wifiStatus = WiFi.status();
|
lcd.print(rssi); lcd.print(" ");
|
||||||
lcd.print(wifiStatus);
|
uint8_t wifiStatus = WiFi.status();
|
||||||
|
lcd.print(wifiStatus);
|
||||||
|
lcd.print(disconnectState);
|
||||||
|
} else {
|
||||||
|
lcd.print("no wifi");
|
||||||
|
}
|
||||||
|
|
||||||
lcd.setCursor(0, 1);
|
lcd.setCursor(0, 1);
|
||||||
lcd.print(getVoltage()); lcd.print("V");
|
lcd.print(getVoltage()); lcd.print("V");
|
||||||
lcd.setCursor(10, 1);
|
lcd.setCursor(10, 1);
|
||||||
lcd.print(getCurrent()); lcd.print("A");
|
lcd.print(getCurrent()); lcd.print("A");
|
||||||
lcd.setCursor(0, 2);
|
lcd.setCursor(0, 2);
|
||||||
lcd.print(getFrequency()); lcd.print("Hz");
|
lcd.print(getCosPhi()); lcd.print("");
|
||||||
lcd.setCursor(10, 2);
|
lcd.setCursor(10, 2);
|
||||||
lcd.print(getPower()); lcd.print("W");
|
lcd.print(getPower()); lcd.print("kW");
|
||||||
lcd.setCursor(0, 3);
|
lcd.setCursor(0, 3);
|
||||||
lcd.print(getEnergy()); lcd.print(" "); lcd.print(getNewEnergy());
|
lcd.print(getEnergy()); lcd.print(" "); lcd.print(getNewEnergy()); lcd.print(" ");
|
||||||
lcd.setCursor(17, 3);
|
|
||||||
lcd.print("kWh");
|
lcd.print("kWh");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
wdt_reset();
|
||||||
|
|
||||||
|
updateDisplay();
|
||||||
|
|
||||||
modbusAppExec();
|
modbusAppExec();
|
||||||
// Mb.Run();
|
// Mb.Run();
|
||||||
|
|
||||||
|
if (wifiEnabled) {
|
||||||
|
if ((disconnectState == 0) && (! client.loop())) {
|
||||||
|
disconnectState = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (disconnectState) {
|
||||||
|
case 0:
|
||||||
|
// Serial.println("discState 0");
|
||||||
|
// everything fine
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Serial.println("discState 1");
|
||||||
|
client.disconnect();
|
||||||
|
disconnectTime = millis();
|
||||||
|
disconnectState = 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Serial.println("discState 3");
|
||||||
|
if (disconnectTime + 2000 < millis()) {
|
||||||
|
disconnectState = 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Serial.println("discState 3");
|
||||||
|
if (client.connect("WiFiPowerMeter")) {
|
||||||
|
disconnectTime = millis();
|
||||||
|
disconnectState = 0;
|
||||||
|
} else {
|
||||||
|
disconnectState = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
disconnectState = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minute.check() == 1) {
|
||||||
|
char strbuf[256];
|
||||||
|
memset(strbuf, sizeof(strbuf), 0);
|
||||||
|
PString buf = PString(strbuf, sizeof(strbuf));
|
||||||
|
buf << "{ \"metadata\": { \"device\": \"WiFiPowerMeter\" }, " <<
|
||||||
|
"\"data\": {" <<
|
||||||
|
"\"voltage\": " << getVoltage() << ", " <<
|
||||||
|
"\"current\": " << getCurrent() << ", " <<
|
||||||
|
"\"cosphi\": " << getCosPhi() << ", " <<
|
||||||
|
"\"power\": " << getPower() << ", " <<
|
||||||
|
"\"energy\": " << getEnergy() << ", " <<
|
||||||
|
"\"newEnergy\": " << getNewEnergy() << ", " <<
|
||||||
|
"\"uptime\": " << uptime <<
|
||||||
|
"}" <<
|
||||||
|
"}" << endl;
|
||||||
|
if (disconnectState == 0) {
|
||||||
|
client.publish("IoT/WiFiPowerMeter/Measurement", strbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (second.check() == 1) {
|
if (second.check() == 1) {
|
||||||
uptime++;
|
uptime++;
|
||||||
|
|
||||||
char strbuf[256];
|
|
||||||
memset(strbuf, sizeof(strbuf), 0);
|
|
||||||
PString buf = PString(strbuf, sizeof(strbuf));
|
|
||||||
|
|
||||||
udpSock.beginPacket("172.16.2.16", 9999);
|
|
||||||
|
|
||||||
buf << "{ \"metadata\": { \"table\": \"WiFiPowerMeter\" }, \"data\": {";
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "\"voltage\": " << getVoltage() << ", ";
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "\"current\": " << getCurrent() << ", ";
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "\"frequency\": " << getFrequency() << ", ";
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "\"power\": " << getPower() << ", ";
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "\"energy\": " << getEnergy() << ", ";
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "\"uptime\": " << uptime;
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "}";
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
buf.begin();
|
|
||||||
buf << "}" << endl;
|
|
||||||
udpSock.write(strbuf, buf.length());
|
|
||||||
|
|
||||||
udpSock.endPacket();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tick.check() == 1) {
|
|
||||||
Serial.println("tick");
|
Serial.println("tick");
|
||||||
|
|
||||||
|
if (wifiEnabled) {
|
||||||
|
String msg = String("{ \"metadata\": { \"device\": \"WiFiPowerMeter\" }, \"data\": { \"uptime\": ") + uptime + String("}}");
|
||||||
|
if (disconnectState == 0) {
|
||||||
|
client.publish("IoT/WiFiPowerMeter/Heartbeat", (char*)msg.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDisplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ void setup();
|
|||||||
|
|
||||||
//add your function definitions for the project ModbusGateway here
|
//add your function definitions for the project ModbusGateway here
|
||||||
|
|
||||||
|
void callback(char* topic, byte* payload, unsigned int length);
|
||||||
|
|
||||||
|
|
||||||
//Do not add code below this line
|
//Do not add code below this line
|
||||||
|
Reference in New Issue
Block a user