184 lines
6.0 KiB
C++
184 lines
6.0 KiB
C++
#define VERSION "1.2"
|
|
|
|
#include <mbed.h>
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <millis.h>
|
|
#include "IO_Ports.h"
|
|
#include "MQTT_Com.h"
|
|
#include "WIZnetInterface.h"
|
|
#include "DS18B20Sensor.h"
|
|
#include "TEnergyMonitor/TEnergyMonitor.h"
|
|
//#include "MAX6675.h"
|
|
|
|
#define IP "10.0.2.251"
|
|
#define NETMASK "255.255.255.0"
|
|
#define GATEWAY "10.0.2.1"
|
|
#define RECEIVE_TOPIC "emonhub/etcontroller/send"
|
|
#define SEND_TOPIC "emonhub/etcontroller/receive"
|
|
|
|
// General Functions Prototypes
|
|
void sendMessage(char*topic, char* msg);
|
|
void sendPoll(void);
|
|
void readCurrent(void);
|
|
void onMessage(MQTT::MessageData &msgMQTT);
|
|
void initEth(void);
|
|
|
|
/////////////// ETHERNET ///////////////////////////
|
|
extern int connack_rc;
|
|
uint8_t MAC[6]={0x58,0x72,0x2D,0xBF,0xB3,0x88};
|
|
SPI spi(MOSI, MISO, SCLK);
|
|
MQTTEthernet ipstack(MAC, IP, NETMASK, GATEWAY, &spi, CS, RST);
|
|
MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
|
|
/////////////// WIFI ///////////////////////////
|
|
|
|
/////////////// SYSTEM /////////////////////////
|
|
Serial pc(SERIAL_TX, SERIAL_RX);
|
|
DigitalOut myLed(LED1);
|
|
Ticker pollTimer, currentTimer;
|
|
BusOut relayOut(DO0,DO1,DO2,DO3,DO4,DO5,DO6,DO7);
|
|
char type,command;
|
|
int relayStatus = 0, relayCommand = 0, lastPower = 0;
|
|
|
|
/////////////// SYSTEM /////////////////////////
|
|
|
|
/////////////// GLOBAL VARS /////////////////////
|
|
char inMessage[MQTT_MAX_PAYLOAD_SIZE],outMessage[MQTT_MAX_PAYLOAD_SIZE],buf1[8],buf2[8],buf3[8];
|
|
bool newMessage=false, poll=false, rcurrent=true, DEBUG=true;
|
|
unsigned int i=0;
|
|
unsigned int pLevels[]={3500,0,2000,2500,3000};
|
|
/////////////// GLOBAL VARS /////////////////////
|
|
|
|
/////////////// SENSORS /////////////
|
|
DS18B20Sensor TempSens(D8);
|
|
TEnergyMonitor ct1(&pc);
|
|
/////////////// SENSORS /////////////
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
///////////////////////// MAIN //////////////////////////////
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
int main() {
|
|
millisStart();
|
|
pc.printf("%c[2J \tE&T Soft. Heatpump Power Controller and Heating System Monitoring V%s \n",27,VERSION);
|
|
myLed=1;
|
|
wait(2);
|
|
initEth(); // Enables Network Connection to MQTT Server
|
|
pc.printf("Subscribed to: %s, %d \r\n", RECEIVE_TOPIC, client.subscribe(RECEIVE_TOPIC, MQTT::QOS1, onMessage));
|
|
pollTimer.attach(&sendPoll, 5);
|
|
currentTimer.attach(&readCurrent, 5);
|
|
TempSens.search();
|
|
relayOut=255;
|
|
ct1.current(A0,40);
|
|
//////////////////////////////////////////////////////////////////
|
|
///////////////////////// MAIN LOOP //////////////////////////////
|
|
//////////////////////////////////////////////////////////////////
|
|
while (true){
|
|
client.yield(10);
|
|
myLed=!myLed;
|
|
if (newMessage) {
|
|
newMessage=false;
|
|
relayStatus = ~relayOut.read();
|
|
int rv = sscanf(inMessage,"%c:%d",&type,&command);
|
|
//pc.printf("sscanf:%d - %c,%d\n", rv,type,command);
|
|
if (rv <= 1 || rv == EOF)
|
|
sprintf(outMessage,"NAK");
|
|
else {
|
|
switch (type) {
|
|
case 'P':
|
|
if(command >= 1 && command <= 4) {
|
|
relayCommand = (relayStatus & 0x0070) | (1 << (command-1));
|
|
}
|
|
else if (command == 0) {
|
|
relayCommand = (relayStatus & 0x0070);
|
|
}
|
|
//lastPower=pLevels[command];
|
|
sprintf(outMessage,"RL_O:%02X",relayCommand);
|
|
relayOut=~relayCommand;
|
|
break;
|
|
|
|
case 'R':
|
|
if(command>=0 && command<=7){
|
|
relayCommand = (relayStatus & 0x000F) | (command << 4);
|
|
sprintf(outMessage,"RL_O:%02X",relayCommand);
|
|
relayOut=~relayCommand;
|
|
}
|
|
break;
|
|
|
|
case 'S':
|
|
sprintf(outMessage,"RL_O:%02X",relayCommand);
|
|
break;
|
|
|
|
case 'T':
|
|
TempSens.startReading(true);
|
|
TempSens.getReading(buf1,0);
|
|
TempSens.getReading(buf2,1);
|
|
TempSens.getReading(buf3,2);
|
|
sprintf(outMessage,"WT_T:%s;SL_T:%s;HT_T:%s",buf2,buf3,buf1);
|
|
break;
|
|
|
|
case 'H':
|
|
sprintf(outMessage,"HP_W:%d",lastPower);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
sendMessage(SEND_TOPIC,outMessage);
|
|
}
|
|
if (poll){
|
|
poll=false;
|
|
sprintf(outMessage,"POLL [%d]",i++);
|
|
sendMessage(SEND_TOPIC, outMessage);
|
|
client.yield(10);
|
|
}
|
|
if (rcurrent){
|
|
rcurrent=false;
|
|
lastPower=(int)((ct1.calcIrms(2)-0.08)*235);
|
|
if(DEBUG) pc.printf("current:%1.3f, power:%d\n",ct1.calcIrms(2)-0.08,lastPower);
|
|
}
|
|
wait(1);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
////////////////////// GENERAL FUNCTS ////////////////////////////
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
////////////////////// ETHERNET FUNCTIONS ////////////////////////
|
|
//////////////////////////////////////////////////////////////////
|
|
void onMessage(MQTT::MessageData &msgMQTT) {
|
|
strncpy(inMessage,(char*)msgMQTT.message.payload,(uint)msgMQTT.message.payloadlen);
|
|
inMessage[(uint)msgMQTT.message.payloadlen]='\0';
|
|
newMessage=true;
|
|
if (DEBUG) pc.printf("Received: %s\n",inMessage);
|
|
}
|
|
|
|
void sendMessage(char*topic,char* msg){
|
|
if (DEBUG) pc.printf("Sent: %s\n", msg);
|
|
publish(&client, &ipstack, topic, msg);
|
|
}
|
|
|
|
void sendPoll(void){
|
|
poll=true;
|
|
}
|
|
|
|
void readCurrent(void){
|
|
rcurrent=true;
|
|
}
|
|
|
|
void initEth (void){
|
|
pc.printf("\nConnecting to ETH\n");
|
|
attemptConnect(&client, &ipstack);
|
|
if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD){
|
|
while (true){
|
|
wait(1.0); // Permanent failures - don't retry
|
|
pc.printf("\nMQTT_NOT_AUTHORIZED or BAD_USERNAME_OR_PASSWORD\n");
|
|
}
|
|
}
|
|
}
|