As I said my skytch is 6 files, a little bit to much to publish, and I don't know how to push a zip files here, anyway if you want it her it is:
ECSnowifi.ino
#include "global.h"
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
#endif // __arm__
void setup() {
// put your setup code here, to run once:
Serial.begin(57600);
Serial.println(F("Controle solaire ECS"));
// Set RGB LED pin modes to output
WiFiDrv::pinMode(25, OUTPUT);
WiFiDrv::pinMode(26, OUTPUT);
WiFiDrv::pinMode(27, OUTPUT);
// Set RGB LED color levels to zero for off, the max value is 128
WiFiDrv::analogWrite(25, 0); // GREEN
WiFiDrv::analogWrite(26, 0); // RED
WiFiDrv::analogWrite(27, 0); // BLUE
initLCD();
// display information text
lcd.setCursor(0, 0);
lcd.print(F("Init Wifi..."));
setColor( 255,0,0); // red until wifi is OK
initWifi();
lcd.setCursor(0, 1);
lcd.print(F("Init vBus..."));
// start the vBus.net
initVbus();
validData=false;
lastPoolTimer = millis();
lcd.setCursor(0, 2);
lcd.print(F("Init PIN"));
// setup Transfert pump to output, and off
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(TRANSFERTPUMP_PIN, OUTPUT);
digitalWrite(TRANSFERTPUMP_PIN, LOW);
ecs_in_temp=0.0;
pac_out_temp=0.0;
pac_top_temp=0.0;
ecs_in.begin( MAX31865_2WIRE );
pac_top.begin( MAX31865_2WIRE );
pac_out.begin( MAX31865_2WIRE );
// display information text
lcd.setCursor(0, 0);
lcd.print(ECS_IN_TEXT);
lcd.setCursor(0, 1);
lcd.print(PAC_TOP_TEXT);
lcd.setCursor(0, 2);
lcd.print(PAC_OUT_TEXT);
setColor( 0,255,0);
}
void loop() {
// read the temperature
if( Serial1.available() ) {
if( readVbusValue() ) {
validData=true;
}
} else {
Serial.println(F("No value on vBus"));
}
validData = true;
// MAX31865
Serial.println(F("Mesure MAX31865"));
mesureValue();
// display value all the time
Serial.println(F("Display Value"));
displayData();
if( ( millis() - lastPoolTimer >= 60000 ) && validData ) {
// if ok send it
Serial.println(F("ok send it"));
lastPoolTimer = millis();
validData=false;
lcd.setCursor(19, 0);
lcd.print(F("*"));
sendData();
Serial.println(F("ok sended"));
// check if we have to turn the pompe on or off
if( ecs_high_temp >= TEMP_POMPE_ON && (pac_top_temp < ecs_high_temp || pac_top_temp < TEMP_MAX_PAC ) ) {
pompeStatus = 1;
digitalWrite(TRANSFERTPUMP_PIN, HIGH);
digitalWrite(LED_BUILTIN, HIGH);
} else {
pompeStatus = 0;
digitalWrite(TRANSFERTPUMP_PIN, LOW);
digitalWrite(LED_BUILTIN, LOW);
}
}
delay(2000);
lcd.setCursor(19, 0);
lcd.print(F(" "));
}
global.h
#include <Adafruit_MAX31865.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_pinIO.h> // Arduino pin i/o class header
#include <SPI.h>
#include <WiFiNINA.h>
#include <utility/wifi_drv.h>
char ssid[] = "closecontact"; // your network SSID (name)
char pass[] = "71776572747a75696f70313233"; // your network password (use for WPA, or use as key for WEP)
// wifi setting
int status = WL_IDLE_STATUS;
#define SERVER "192.168.1.16" // Host to contact
#define PORT 80 // 80 = HTTP default port
#define NODE "Solar"
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;
// vBus settings
double ecs_high_temp; // S3
double ecs_low_temp; // S2
double solar_temp; // S1
double solar_ret_temp; // S4
char ecs_high_temp_s[7]; // S3
char ecs_low_temp_s[7]; // S2
char solar_temp_s[7]; // S1
char solar_ret_temp_s[7];
uint8_t PumpSpeed1; // in %
char PumpSpeed2; // in %
char PumpSpeed3; // in %
uint8_t Relay;
char ErrorMask;
char Scheme;
uint32_t HeatQuantity;
char Send_URL[255];
// Settings for the VBus decoding
#define Sync 0xAA // Synchronisation bytes
#define FrameLength 6 // Framelength
#define FrameOffset 10 // Offset start of Frames
#define FrameSeptet 4 // Septet byte in Frame
#define SENSORNOTCONNECTED 8888 // Sometimes this might be 888 instead.
unsigned int Destination_address;
unsigned int Source_address;
unsigned char ProtocolVersion;
unsigned int Command;
unsigned char Framecnt;
unsigned char Septet;
unsigned char Checksum;
unsigned long lastTimeTimer;
unsigned long timerInterval=7000;
// value from single sensor
float ecs_in_temp;
float pac_out_temp;
float pac_top_temp;
char ecs_in_temp_s[7];
char pac_out_temp_s[7];
char pac_top_temp_s[7];
bool pompeStatus;
#define RREF 4300.0
// The 'nominal' 0-degrees-C resistance of the sensor
#define RNOMINAL 1000.0
#define PAC_TOP_PIN A3
#define ECS_IN_PIN A4
#define PAC_OUT_PIN 3
// Use software SPI: CS, DI, DO, CLK
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);
// use hardware SPI, just pass in the CS pin
Adafruit_MAX31865 ecs_in = Adafruit_MAX31865(ECS_IN_PIN);
Adafruit_MAX31865 pac_top = Adafruit_MAX31865(PAC_TOP_PIN);
Adafruit_MAX31865 pac_out = Adafruit_MAX31865(PAC_OUT_PIN);
#define TRANSFERTPUMP_PIN 2
// defaut temp setting
#define TEMP_MAX_PAC 85 // temperature max de la PAC
#define TEMP_POMPE_ON 55 // Temperature de la consigne d'enclenchement de la pompe de circulation
bool all;
bool validData;
unsigned long lastPoolTimer;
// LCD settings
#define ECS_IN_TEXT "ECS in: "
#define PAC_OUT_TEXT "PAC out: "
#define PAC_TOP_TEXT "PAC top: "
// with the arduino pin number it is connected to
#define D4_PIN 4
#define D5_PIN 5
#define D6_PIN 6
#define D7_PIN 7
#define RS_PIN A0
#define EN_PIN A1
#define BACKLIGHT_PIN A2
hd44780_pinIO lcd(RS_PIN, EN_PIN, D4_PIN, D5_PIN, D6_PIN, D7_PIN, BACKLIGHT_PIN, HIGH);
lcd.ino
void initLCD() {
// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
lcd.setBacklight(125);
// Turn off the cursor:
lcd.noCursor();
}
void displayData() {
lcd.setCursor(strlen(ECS_IN_TEXT), 0);
lcd.print(ecs_in_temp, 1);
lcd.setCursor(strlen(PAC_TOP_TEXT), 1);
lcd.print(pac_top_temp, 1);
lcd.setCursor(strlen(PAC_OUT_TEXT), 2);
lcd.print(pac_out_temp, 1);
}
mesure.ino
void initMesure() {
ecs_in.begin(MAX31865_2WIRE);
pac_top.begin(MAX31865_2WIRE);
pac_out.begin(MAX31865_2WIRE);
}
bool mesureValue() {
bool ret;
ecs_in_temp = ecs_in.temperature(RNOMINAL, RREF)-1.2;
ret = checkError (ecs_in_temp);
delay(100);
pac_out_temp = pac_out.temperature(RNOMINAL, RREF)-1.2;
ret = checkError (pac_out_temp);
delay(100);
pac_top_temp = pac_top.temperature(RNOMINAL, RREF)-1.2;
ret = checkError (pac_top_temp);
delay(100);
}
bool checkError( Adafruit_MAX31865 temp) {
uint8_t fault;
bool ret=false;
fault = temp.readFault();
if (fault)
{
Serial.print(F("Fault 0x"));
Serial.println(fault, HEX);
if (fault & MAX31865_FAULT_HIGHTHRESH) {
Serial.println(F("RTD High Threshold "));
lcd.setCursor(0, 3);
lcd.print(F("RTD High Threshold "));
}
if (fault & MAX31865_FAULT_LOWTHRESH) {
Serial.println(F("RTD Low Threshold "));
lcd.setCursor(0, 3);
lcd.print(F("RTD Low Threshold "));
}
if (fault & MAX31865_FAULT_REFINLOW) {
Serial.println(F("REFIN >0.85 x Bias "));
lcd.setCursor(0, 3);
lcd.print(F("REFIN >0.85 x Bias "));
}
if (fault & MAX31865_FAULT_REFINHIGH) {
Serial.println(F("REFIN <0.85 x Bias o"));
lcd.setCursor(0, 3);
lcd.print(F("REFIN <0.85 x Bias o"));
}
if (fault & MAX31865_FAULT_RTDINLOW) {
Serial.println(F("RTDIN <0.85 x Bias o"));
lcd.setCursor(0, 3);
lcd.print(F("RTDIN <0.85 x Bias o"));
}
if (fault & MAX31865_FAULT_OVUV) {
Serial.println(F("Under/Over voltage "));
lcd.setCursor(0, 3);
lcd.print(F("Under/Over voltage "));
}
temp.clearFault();
delay(2000);
lcd.setCursor(0, 3);
lcd.print(F(" "));
} else ret=true;
return ret;
}
vbus.ino
/*
67. DFA (0x0010) <= SOLTOP DeltaSol S2/S3 (0x7731)
Offset Size Mask Name Factor Unit
0 2 Temperature sensor 1 0.1 °C
2 2 Temperature sensor 2 0.1 °C
Frame 2
4 2 Temperature sensor 3 0.1 °C
6 2 Temperature sensor 4 0.1 °C
Frame 3
8 2 Temperature sensor 5 0.1 °C
10 2 Temperature sensor 6 0.1 °C
Frame 4
12 2 Temperature sensor 7 0.1 °C
14 2 Temperature sensor 8 0.1 °C
Frame 5
16 1 Pump speed R1 1 %
17 1 Pump speed R2 1 %
18 1 Pump speed R3 1 %
19 1 Relay byte 1
Frame 6
20 2 Heat 1 Wh
22 2 Heat 1000 Wh
Frame 7
24 2 Heat 1000000 Wh
26 1 Scheme 1
*/
unsigned char Buffer[80];
volatile unsigned char Bufferlength;
void initVbus(){
Serial1.begin(9600);
Serial.println(F("vBus Serial open"));
solar_temp=0.0; // S1
ecs_low_temp=0.0; // S2
ecs_high_temp=0.0; // S3
solar_ret_temp=0.0; // S4
}
bool readVbusValue() {
char c;
bool start,stop,quit;
start = true;
stop = false;
quit = false;
Bufferlength=0;
lastTimeTimer = 0;
lastTimeTimer = millis();
memset( Buffer,0, sizeof(Buffer));
Serial.println(F("vBus read"));
while ((!stop) and (!quit)) {
if (Serial1.available()) {
c=Serial1.read();
if (c == Sync || c == 0xFFFFFFAA ) {
if (start) {
start=false;
Bufferlength=0;
} else {
if (Bufferlength<20) {
lastTimeTimer = 0;
lastTimeTimer = millis();
Bufferlength=0;
} else
stop=true;
}
}
if ((!start) and (!stop)) {
Buffer[Bufferlength]=c;
Bufferlength++;
}
} // end if mySerial.available
if ((timerInterval > 0) && (millis() - lastTimeTimer > timerInterval ) ) {
quit=true;
}
} // end while loop
lastTimeTimer = 0;
Serial.println( F("Buffer: "));
for( int i=0;i <= Bufferlength; i++ ) {
Serial.print( Buffer[i], HEX);
Serial.print( " " );
}
Serial.println(F("End Buffer") );
if (!quit) {
Destination_address = Buffer[2] << 8;
Destination_address |= Buffer[1];
Source_address = Buffer[4] << 8;
Source_address |= Buffer[3];
ProtocolVersion = (Buffer[5]>>4) + (Buffer[5] &(1<<15));
Command = Buffer[7] << 8;
Command |= Buffer[6];
Framecnt = Buffer[8];
Checksum = Buffer[9]; //TODO check if Checksum is OK
Serial.println(F("---------------"));
Serial.print(F("Destination: "));
Serial.println(Destination_address, HEX);
Serial.print(F("Source: "));
Serial.println(Source_address, HEX);
Serial.print(F("Protocol Version: "));
Serial.println(ProtocolVersion);
Serial.print(F("Command: "));
Serial.println(Command, HEX);
Serial.print(F("Framecount: "));
Serial.println(Framecnt);
Serial.print(F("Checksum: "));
Serial.println(Checksum);
Serial.print(F("Bufferlength: "));
Serial.println(Bufferlength);
Serial.println(F("---------------"));
/*
15:38:33.340 -> Destination: 10
15:38:33.340 -> Source: 7731
15:38:33.340 -> Protocol Version: 1
15:38:33.340 -> Command: 100
15:38:33.340 -> Framecount: 7
15:38:33.378 -> Checksum: 47
15:38:33.378 -> Bufferlength: 52 Sometime 38 why
*/
// Only analyse Commands 0x100 = Packet Contains data for slave
// with correct length = 10 bytes for HEADER and 6 Bytes for each frame
// Buffer length has to be 52 to be correct (7*6=42 + 10=52)
// if ((Command==0x0100) and (Bufferlength==10+Framecnt*6)) {
if ( (Command==0x0100) ) {
//Only decode the data from the correct source address
//(There might be other VBus devices on the same bus).
decodeVbusFrame(Buffer);
Serial.println(F("------Values------"));
Serial.print(F("Solar : "));
Serial.println(solar_temp);
Serial.print(F("ECS Low: "));
Serial.println(ecs_low_temp);
Serial.print(F("ECS High: "));
Serial.println(ecs_high_temp);
Serial.print(F("Solar return: "));
Serial.println(solar_ret_temp);
Serial.print(F("Pump speed1: "));
Serial.println(PumpSpeed1, HEX);
Serial.print(F("Pump speed2: "));
Serial.println(PumpSpeed2, HEX);
Serial.print(F("Pump speed3: "));
Serial.println(PumpSpeed3, HEX);
Serial.print(F("Relay: "));
Serial.println(Relay, HEX);
Serial.print(F("Heat: "));
Serial.println(HeatQuantity);
Serial.print(F("Scheme: "));
Serial.println(Scheme, HEX);
/*
14:56:55.174 -> Pump speed1: 64
14:56:55.174 -> Pump speed2: 64
14:56:55.174 -> Pump speed3: 0
14:56:55.174 -> Relay: 6
32'390,643
afficher 32 390 KWH
*/
} else {
Serial.println(F("Error vBus "));
return false;
}
}
return true;
}
void decodeVbusFrame( unsigned char *frame ){
int FO;
// Serial.println(F("Now decoding for 0x7731"));
FO=FrameOffset;
Septet=frame[FO+FrameSeptet];
InjectSeptet(frame,FO,4);
solar_temp = CalcTemp(frame[FO+1], frame[FO]);
ecs_low_temp = CalcTemp(frame[FO+3], frame[FO+2]);
/*
18:50:22.981 -> Solar : 7.80
18:50:22.981 -> ECS Low: 26.30
*/
//******************* Frame 2 *******************
FO=FrameOffset+FrameLength;
Septet=Buffer[FO+FrameSeptet];
InjectSeptet(frame,FO,4);
ecs_high_temp = CalcTemp(frame[FO+1], frame[FO]);
solar_ret_temp = CalcTemp(frame[FO+3], frame[FO+2]);
/*
18:50:22.981 -> ECS High: 44.80
18:50:22.981 -> Solar return: 21.10
*/
//******************* Frame 3 *******************
FO=FrameOffset+FrameLength+2;
Septet=Buffer[FO+FrameSeptet];
InjectSeptet(frame,FO,4);
/*
Serial.print("Temp5 : ");
Serial.println(CalcTemp(frame[FO+1], frame[FO]));
Serial.print("Temp6 : ");
Serial.println(CalcTemp(frame[FO+3], frame[FO+2]));
*/
//******************* Frame 4 *******************
FO=FrameOffset+FrameLength+3;
Septet=Buffer[FO+FrameSeptet];
InjectSeptet(frame,FO,4);
/*
Serial.print("Temp7 : ");
Serial.println(CalcTemp(frame[FO+1], frame[FO]));
Serial.print("Temp8 : ");
Serial.println(CalcTemp(frame[FO+3], frame[FO+2]));
*/
//******************* Frame 5 *******************
FO=FrameOffset+FrameLength*4;
Septet=Buffer[FO+FrameSeptet];
InjectSeptet(frame,FO,4);
PumpSpeed1 = (frame[FO] & 0X7F);
PumpSpeed2 = (frame[FO+1] & 0X7F);
PumpSpeed3 = (frame[FO+2] & 0X7F);
Relay = frame[FO+3];
if( Relay == 6 ) Relay = 1; // 2 chauffage bas
/*
Serial.println( F("Frame 5"));
Serial.println( frame[FO], HEX);
Serial.println( frame[FO+1], HEX);
Serial.println( frame[FO+2], HEX);
Serial.println( frame[FO+3], HEX);
*/
/*
18:50:29.213 -> 0
18:50:29.213 -> 0
18:50:29.213 -> 0
18:50:29.213 -> 0
*/
//******************* Frame 6 *******************
FO=FrameOffset+FrameLength*5;
Septet=Buffer[FO+FrameSeptet];
InjectSeptet(frame,FO,4);
HeatQuantity=(frame[FO+1] << 8 | frame[FO])+(frame[FO+3] << 8| frame[FO+2])*1000;
Serial.println( F("Frame 6"));
Serial.println( frame[FO+1], HEX);
Serial.println( frame[FO+2], HEX);
Serial.println( frame[FO+3], HEX);
/*
18:50:29.213 -> D5
18:50:29.213 -> 0
18:50:29.213 -> 6
18:50:29.213 -> 1
*/
//******************* Frame 7 *******************
FO=FrameOffset+FrameLength*6;
Septet=Buffer[FO+FrameSeptet];
InjectSeptet(frame,FO,4);
HeatQuantity=HeatQuantity+(frame[FO+1] << 8 | frame[FO])*1000000;
Scheme = frame[FO+2];
Serial.println( F("Frame 7"));
Serial.println( frame[FO], HEX);
Serial.println( frame[FO+1], HEX);
Serial.println( frame[FO+2], HEX);
/*
* 32'390,643
afficher 32 390 KWH
18:50:29.213 -> 20
18:50:29.213 -> 0
18:50:29.213 -> 3
*/
}
// The following is needed for decoding the data
void InjectSeptet(unsigned char *Buffer, int Offset, int Length) {
for (unsigned int i = 0; i < Length; i++) {
if (Septet & (1 << i)) {
Buffer [Offset + i] |= 0x80;
}
}
}
// This function converts 2 data bytes to a temperature value.
float CalcTemp(int Byte1, int Byte2) {
int v;
v = Byte1 << 8 | Byte2; //bit shift 8 to left, bitwise OR
if (Byte1 == 0x00){
v= v & 0xFF;
}
if (Byte1 == 0xFF)
v = v - 0x10000;
if (v==SENSORNOTCONNECTED)
v=0;
return (float)((float) v * 0.1);
}
wifi.ino
void initWifi(){
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println(F("Communication with WiFi module failed!"));
// don't continue
while (true);
}
// Print firmware version on the module
String fv = WiFi.firmwareVersion();
Serial.print("Firmware version installed: ");
Serial.println(fv);
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println(F("Please upgrade the firmware"));
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print(F("Attempting to connect to SSID: "));
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 5 seconds for connection:
delay(5000);
}
Serial.println(F("Connected to WiFi"));
setColor( 0,0,255); // red until wifi is OK
printWifiStatus();
setColor( 0,255,0);
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print(F("SSID: "));
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print(F("IP Address: "));
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print(F("signal strength (RSSI):"));
Serial.print(rssi);
Serial.println(" dBm");
}
void sendData(){
Serial.println(F("\nStarting connection to server..."));
if ( WiFi.status() != WL_CONNECTED ) {
setColor( 255,0,0); // red until wifi is OK
Serial.println(WiFi.status());
initWifi();
}
// if you get a connection, report back via serial:
if (client.connected()) {
Serial.println(F("Client connected to server"));
}
if (client.connect(SERVER, PORT)) {
Serial.println(F("connected to server"));
// Make a HTTP request:
dtostrf(ecs_high_temp,3,1,ecs_high_temp_s);
dtostrf(ecs_low_temp,3,1,ecs_low_temp_s);
dtostrf(ecs_low_temp,3,1,ecs_low_temp_s);
dtostrf(solar_temp,3,1,solar_temp_s);
dtostrf(solar_ret_temp,3,1,solar_ret_temp_s);
dtostrf(ecs_in_temp,3,1,ecs_in_temp_s);
dtostrf(pac_top_temp,3,1,pac_top_temp_s);
dtostrf(pac_out_temp,3,1,pac_out_temp_s);
sprintf(Send_URL, "GET /input/post?node=%s&json={ecs_high:%s,ecs_low:%s,solar_temp:%s,solar_ret:%s,HeatQuantity:%lu,PumpSpeed:%u,Relay:%u,ecs_in:%s,pac_top:%s,pac_out:%s,pompeStatus:%d}&apikey=29ceaa8fdad3f5268a2c1f7fd730ce2c HTTP/1.1\r\nHost:192.168.1.16\r\n\r\n",
NODE, ecs_high_temp_s,ecs_low_temp_s,solar_temp_s,solar_ret_temp_s,(HeatQuantity/1000),PumpSpeed1,Relay,ecs_in_temp_s,pac_top_temp_s,pac_out_temp_s,pompeStatus);
client.println(Send_URL);
Serial.println(Send_URL);
delay(2000);
while (client.available()) {
char c = client.read();
Serial.write(c);
}
client.stop();
}
}
void wifiLowPower( bool lowPower) {
if( lowPower) {
setColor( 0,0,255); // blue until wifi is down
Serial.println(F("WiFi lowPowerMode"));
WiFi.lowPowerMode();
} else {
setColor( 0,255,0); // blue until wifi is down
Serial.println(F("WiFi nolowPowerMode"));
WiFi.noLowPowerMode();
}
}
// set the RGB led
void setColor( uint8_t red, uint8_t green, uint8_t blue ) {
WiFiDrv::analogWrite(25, green/20); // GREEN
WiFiDrv::analogWrite(26, red/20); // RED
WiFiDrv::analogWrite(27, blue/20); // BLUE
}