John Wood
Published © GPL3+

Caravan/Home Automation

Automate my caravan lights, pumps, solar system water tanks and self-leveling system with remote access.

IntermediateWork in progress10,776
Caravan/Home Automation

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
Used to collect serial data from Tri-Metric and send over TCP
×1
Raspberry Pi 2 Model B
Raspberry Pi 2 Model B
Poles Modbus sores to MySQL database and displays data graphically all using php.
×1

Story

Read more

Code

Sensors

C/C++
Has gas, temp, humidity, pressure sensors, relays and capacitive touch buttons. Send over Modbus TCP.
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------

                                                           Integrated Networking Systems Home Automation Project
                                                                           MEGA-SENSORS.ino V1.0

                      This project is to be able to remotly control lights, water pumps, solidnoids, air conditioner, and monitor water levels, GAS Sensors,
                      Light Sensors, PIR Sensors, Temperature and Humidity Sensors, Bearometric Pressure Sensor, RTC, with a 20x4 LCD to display some basic 
                      sensor information and control air conditioner, and sends all information over modbus tcp/ip for remote processing on Raspberry Pi2.

                                                                                            Home Automation Project by Integrated Networking Systems Pty Ltd
                                                                                                          Coded by John Wood and Paul Alting van Geusau 2015
 
--------------------------------------------------------------------------- Header Files -----------------------------------------------------------------------
                                                                                                                                                              */
#include "Ethernet.h"
#include "SPI.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include "RTClib.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
#include "DHT.h"
#include "Mudbus.h"                                                                       // https://gitorious.org/mudbus

/*------------------------------------------------------------------------- Define I2C Address: ----------------------------------------------------------------
                                                                                                                                                              */
#define         LCD_ADDRESS             0x27                                              // address for LCD1:
#define         AT24C32_ADDRESS         0x57                                              // RTC On-board 32k byte EEPROM; 128 pages of 32 bytes each
#define         DS1307_ADDRESS          0x68                                              // RTC (Real Time Clock)
#define         BMP085_ADDRESS          0x77                                              // BMP180 

/*------------------------------------------------------------------------- Digital Pin Definition -------------------------------------------------------------
                                                                                                                                                              */
//#define       RX0                     0                                                 // Serial Rx0 Port - USB
//#define       TX0                     1                                                 // Serial Tx0 Port - USB
/*------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define         DHTPIN                  2                                                 // PWM - what pin 1st DHT22 sensor connected to
#define         DHT1PIN                 3                                                 // PWM - what pin 2nd DHT22 sensor connected to
//#define       SSSDCARD                4                                                 // PWM - SS for SD Card on Ethernet Shield
#define         DHT2PIN                 5                                                 // PWM - what pin 3rd DHT22 sensor connected to
//#define                               6                                                 // PWM - 
//#define                               7                                                 // PWM - 
//#define                               8                                                 // PWM - 
//#define                               9                                                 // PWM - (Reserve for latter use) 
//#define       SSETHERNET              10                                                // PWM - SS for Ethernet Sheild
//#define                               11                                                // PWM - (Reserve for latter use)
//#define                               12                                                // PWM - (Reserve for latter use)
//#define                               13                                                // PWM - (Reserve for latter use)
/*------------------------------------------------------------------------------------------------------------------------------------------------------------*/
//#define       TX3                     14                                                // Serial Tx3 Port - 
//#define       RX3                     15                                                // Serial Rx3 Port - 
//#define       TX2                     16                                                // Serial Tx2 Port - xBee Bluetooth
//#define       RX2                     17                                                // Serial Rx2 Port - xBee Bluetooth
//#define       TX1                     18                                                // Serial Tx1 Port - 
//#define       RX1                     19                                                // Serial Rx1 Port - 
/*------------------------------------------------------------------------------------------------------------------------------------------------------------*/
//#define       SDA                     20                                                // SDA - I2C Bus
//#define       SCL                     21                                                // SDL - I2C Bus
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                              Relays
               Bedroom Light Relays                                                                                                                           */
#define        BedMainLightRly          22                                                // RELAY BLOCK 3-1 - Main Bedroom Light
#define        BedReadLight1Rly         23                                                // RELAY BLOCK 3-2 - Main Bedroom Reading Light
#define        BedReadLight2Rly         24                                                // RELAY BLOCK 3-3 - Main Bedroom Reading Light
#define        Bed2LightRly             25                                                // RELAY BLOCK 3-4 - Zachary's Bed Light
/*             Outside Light Relay                                                                                                                            */
#define        ExternalLightRly         26                                                // RELAY BLOCK 4-1 - Outside light
/*             Bathroom Light Relay                                                                                                                           */
#define        BathLightRly             27                                                // RELAY BLOCK 4-2 - Main Bathroom Light
/*             Office Light Relay                                                                                                                             */
#define        OfficeLightRly           28                                                // RELAY BLOCK 4-3 - Main Office Light
/*             Main Living Area Light Relay                                                                                                                   */
#define        MainLightRly             29                                                // RELAY BLOCK 4-4 - Main Living Area Lights
/*             Auto Night Light Relays                                                                                                                        */
#define        NightLightRly            30                                                // RELAY BLOCK 5-1 - Realy controlling 5V auto night light via PIR/LDR
#define        NightLight2Rly           31                                                // RELAY BLOCK 5-2 - Relay controlling bathroom 12v exhaust FAN
/*             Exhaust FAN Relays                                                                                                                             */
#define        KitchenFANRly            32                                                // RELAY BLOCK 5-3 - Relay controlling kitchen 12v exhaust FAN
#define        BathFANRly               33                                                // RELAY BLOCK 5-4 - Realy controlling 5V auto night light via PIR/LDR

/*                                                    Capacitive Touch Buttons
              Master Bedroom Light Switches                                                                                                                   */
#define       BedMainLightSw1           34                                                // Pin 34 CAP TOUCH - Main Bedroom light switch near door
#define       BedMainLightSw2           35                                                // Pin 35 CAP TOUCH - Main bedroom light switch near bed
#define       BedReadLightSw1           36                                                // Pin 36 CAP TOUCH - Main bed reading light switch
#define       BedReadLightSw2           37                                                // Pin 37 CAP TOUCH - Main bed reading light switch
/*            Zachary's Bedroom Light Switches                                                                                                                */
#define       Bed2LightSw1              38                                                // Pin 38 CAP TOUCH - Zachary's bed light switch near door
#define       Bed2LightSw2              39                                                // Pin 39 CAP TOUCH - Zachary's bed light switch near bed
/*            Outside Light Switches                                                                                                                          */
#define       RearExternalLightSw       40                                                // Pin 40 CAP TOUCH - Outside light switch near rear door
#define       FontExternalLightSw       41                                                // Pin 41 CAP TOUCH - Outside light switch near front door
/*            Bathroom Light Switch                                                                                                                           */
#define       BathLightSw               42                                                // Pin 42 CAP TOUCH - Bathroom light switch
/*            Office Light Switch                                                                                                                             */
#define       OfficeLightSw             43                                                // Pin 43 CAP TOUCH - Office light switch
/*            Main Living Area Light Switch                                                                                                                   */
#define       MainLightSw               44                                                // Pin 44 CAP TOUCH - Main living area light switch
/*            Exhaust FAN Switches                                                                                                                            */
#define       BathExhaustFanSw          45                                                // Pin 45 CAP TOUCH - Bathroom exhaust fan manual switch
#define       KitExhaustFanSw           46                                                // Pin 46 CAP TOUCH - Kitchen exhaust fan manual switch
//#define                               47                                                // Pin 47 CAP TOUCH - 
//#define                               48                                                // Pin 48 CAP TOUCH - 
//#define                               49                                                // Pin 49 CAP TOUCH - 
/*------------------------------------------------------------------------------------------------------------------------------------------------------------*/
//#define       MISO                    50                                                // MISO
//#define       MOSI                    51                                                // MOSI
//#define       SCK                     52                                                // SCK
//#define       HARDWARESS              53                                                // Hardware SS

/*------------------------------------------------------------------------- Analogue Pin Definition ------------------------------------------------------------
                Name                    Pin                                               Comments
                                                                                                                                                              
                Bathroom Night Light                                                                                                                          */
#define         LDRPIN                  A0                                                // Light/Dark sensor for night light
//                                      A1                                                // Used unknown what for
#define         PIRPIN                  A2                                                // Passive IR Sensor - turns night light on/off
/*              Main Living Area Night Light                                                                                                                  */
#define         LDR2PIN                 A3                                                // Light/Dark sensor for night light 2
#define         PIR1PIN                 A4                                                // Passive IR Sensor - turns night light on/off
#define         PIR2PIN                 A5                                                // Passive IR Sensor - turns night light on/off
/*              Bathroom GAS Sensors                                                                                                                          */
#define         BATHGAS01PIN            A6                                                // LPG GAS MQ-5 Sensor 01 - Bathroom
#define         BATHGAS02PIN            A7                                                // CARBON MONOXIDE GAS MQ-135 GAS Sensor 02 - Bathroom
/*              Kitchen GAS Sensors                                                                                                                           */
#define         KITGAS01PIN             A8                                                // LPG GAS MQ-5 Sensor 01 - Kitchen
#define         KITGAS02PIN             A9                                                // SMOKE GAS Sensor MQ-7 02 - Kitchen
#define         KITGAS03PIN             A10                                               // CARBON MONOXIDE GAS MQ-135 Sensor 03 - Kitchen
//#define                               A11
//#define                               A12
//#define                               A13
//#define                               A14
//#define                               A15
 
/*------------------------------------------------------------------------- Global Variables -------------------------------------------------------------------
                Type                    Variable Name           Value                     Comments
                
                                        Timming Variables                                                                                                     */
                uint32_t                lastSensorScan               =   0;               // accumalitive sensor timer value:
const           uint32_t                periodSensorScan             =   2500;            // sensor timer period pre-set:
                uint32_t                lastLCDScan                  =   0;               // accumalitive LCD write timer value:
const           uint32_t                periodLCDScan                =   250;             // LCD write timer period pre-set:
                uint32_t                lastCAPScan                  =   0;               // accumalitive Capacitive Touch Button timer value:
const           uint32_t                periodCAPScan                =   50;              // Capacitive Touch Button timer period pre-set:
                
/*                                      BMP180 Sensor Variables                                                                                               */
                float                   bmpPressure;                                      // Stores bearometric pressure from BMP180 sensor
                float                   bmpTemperature;                                   // Stores temperature from BMP180 sensor
                float                   bmpAltitude;                                      // Stores calculated altitude from BMP180 sensor
                float                   seaLevelPressure             =   1031.3;          // Enter your local mean sea level pressure for altitude calculation
                
/*                                      DHT22 Sensor Variables                                                                                                */
                float                   dht22Temperature;                                 // Stores temperature from 1st DHT22 sensor
                float                   dht22Temperature2;                                // Stores temperature from 2nd DHT22 sensor
                float                   dht22Temperature3;                                // Stores temperature from 3rd DHT22 sensor
                float                   dht22Humidity;                                    // Stores humidity from 1st DHT22 sensor
                float                   dht22Humidity2;                                   // Stores humidity from 2nd DHT22 sensor
                float                   dht22Humidity3;                                   // Stores humidity from 3rd DHT22 sensor
                float                   AverageTemp;                                      // Stores calculated average temperature from the 3 DHT22 sensors
                float                   AverageHumidity;                                  // Stores calculated average humidity from the 2 DHT22 sensors
                
/*                                      Modbus Read/Write Variables                                                                                           */
                uint16_t                packBitsRead                 =   0;               // 16 bit field to hold bits to be read in via Modbus:
                uint16_t                packBitsWrite                =   0;               // 16 bit field to hold bits to be written out via Modbus:
                uint16_t                ScaledAverageTemp;                                // average Temp of DHT, DHT1 and DHT2 temperatures (scaled * 100):
                uint16_t                ScaledAverageRH;                                  // average RH of DHT, DHT1 and DHT2 humidities (scaled * 100):
                uint16_t                ScaledbmpPressure;                                // Bearometric Pressure (scaled * 100)
                uint16_t                ScaledbmpTemperature;                             // BMP Temperature Sensor (scaled * 100)
                uint16_t                ScaledbmpAltitude;                                // BMP calculated Altitude (scaled * 100)

/*                                      Passive Infa-Red Motion Sensor State Variables                                                                        */
                boolean                 PIRPINState                  =   false;           // stores the current state of the PIR sensor
                boolean                 PIR1PINState                 =   false;           // stores the current state of the PIR sensor
                boolean                 PIR2PINState                 =   false;           // stores the current state of the PIR sensor
                
/*                                      Light Dependant Resister (Light/Dark Sensor Variables)                                                                */
                int                     LDRState                     =   0;               // stores the analgue value of the LDR sensoe reading  
                int                     LDR2State                    =   0;               // stores the analgue value of the LDR sensoe reading 
                int                     LDRbrightness                =   600;             // How dark to turn on night light higher=darker max=850?
                int                     LDR2brightness               =   700;             // How dark to turn on night light higher=darker max=850?

/*                                      GAS Sensor Variables                                                                                                  */
                int                     BathGasSensor1               =   0;               // Sensors current value
                int                     BathGas1Preset               =   450;             // Sensor preset value to trigger event
                int                     BathGasSensor2               =   0;               // Sensors current value
                int                     BathGas2Preset               =   450;             // Sensor preset value to trigger event
                int                     KitGasSensor1                =   0;               // Sensors current value
                int                     KitGas1Preset                =   450;             // Sensor preset value to trigger event
                int                     KitGasSensor2                =   0;               // Sensors current value
                int                     KitGas2Preset                =   450;             // Sensor preset value to trigger event
                int                     KitGasSensor3                =   0;               // Sensors current value
                int                     KitGas3Preset                =   450;             // Sensor preset value to trigger event
                boolean                 BathGas1Detected             =   false;           // Sensor state for modbus
                boolean                 BathGas2Detected             =   false;           // Sensor state for modbus
                boolean                 KitGas1Detected              =   false;           // Sensor state for modbus
                boolean                 KitGas2Detected              =   false;           // Sensor state for modbus
                boolean                 KitGas3Detected              =   false;           // Sensor state for modbus
                
/*                                      Relay State Variables                                                                                                 */
                boolean                 BedMainLightRlyState         =   false;           // stores the current on/off state of main bedroom light relay
                boolean                 BedReadLight1RlyState        =   false;           // stores the current on/off state of bed nightlight 1 light relay
                boolean                 BedReadLight2RlyState        =   false;           // stores the current on/off state of bed nightlight 2 light relay
                boolean                 Bed2LightRlyState            =   false;           // stores the current on/off state of bed 2 light relay
                boolean                 ExternalLightRlyState        =   false;           // stores the current on/off state of external light relay
                boolean                 BathLightRlyState            =   false;           // stores the current on/off state of bathroom light relay
                boolean                 OfficeLightRlyState          =   false;           // stores the current on/off state of office light relay
                boolean                 MainLightRlyState            =   false;           // stores the current on/off state of living area light relay
                boolean                 NightLightState              =   false;           // stores the current on/off state of night light relay
                boolean                 NightLight2State             =   false;           // stores the current on/off state of night light 2 relay
                boolean                 BathFanRlyState              =   false;           // stores the current on/off state of bathroom exhaust fan relay
                boolean                 KitFanRlyState               =   false;           // stores the current on/off state of kitchen exhaust fan relay
                
/*                                      Capacitive Touch Button States                                                                                        */
                boolean                 BedMainLightSw1St            =   false;           // CAP TOUCH BUTTON STATE - Main Bedroom light switch near door
                boolean                 BedMainLightSw1PSt           =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 BedMainLightSw2St            =   false;           // CAP TOUCH BUTTON STATE - Main bedroom light switch near bed
                boolean                 BedMainLightSw2PSt           =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 BedReadLightSw1St            =   false;           // CAP TOUCH BUTTON STATE - Main bed reading light switch
                boolean                 BedReadLightSw1PSt           =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 BedReadLightSw2St            =   false;           // CAP TOUCH BUTTON STATE - Main bed reading light switch
                boolean                 BedReadLightSw2PSt           =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 Bed2LightSw1St               =   false;           // CAP TOUCH BUTTON STATE - Zachary's bed light switch near door
                boolean                 Bed2LightSw1PSt              =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 Bed2LightSw2St               =   false;           // CAP TOUCH BUTTON STATE - Zachary's bed light switch near bed
                boolean                 Bed2LightSw2PSt              =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 RearExternalLightSwSt        =   false;           // CAP TOUCH BUTTON STATE - Outside light switch near rear door
                boolean                 RearExternalLightSwPSt       =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 FontExternalLightSwSt        =   false;           // CAP TOUCH BUTTON STATE - Outside light switch near front door
                boolean                 FontExternalLightSwPSt       =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 BathLightSwSt                =   false;           // CAP TOUCH BUTTON STATE - Bathroom light switch
                boolean                 BathLightSwPSt               =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 OfficeLightSwSt              =   false;           // CAP TOUCH BUTTON STATE - Office light switch
                boolean                 OfficeLightSwPSt             =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 MainLightSwSt                =   false;           // CAP TOUCH BUTTON STATE - Main living area light switch
                boolean                 MainLightSwPSt               =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 BathExhaustFanSwSt           =   false;           // CAP TOUCH BUTTON STATE - Bathroom exhaust fan manual switch
                boolean                 BathExhaustFanSwPSt          =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 
                boolean                 KitExhaustFanSwSt            =   false;           // CAP TOUCH BUTTON STATE -  Kitchen exhaust fan manual switch
                boolean                 KitExhaustFanSwPSt           =   false;           // CAP TOUCH BUTTON PREVIOUS STATE - 

/*                                      Capacitive Touch Button Timming Variables                                                                             */
                long                    time                         =   0;
                int                     debounce                     =   500;

                String                  sensorError                  =   "";

/*                                      Ethernet Variables                                                                                                    */
                uint8_t                 mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF};    // MAC address, default is {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}:
                IPAddress               ip(192,168,88,177);                               // Sets IP address of ethernet card
                IPAddress               gateway(192,168,88, 1);                           // Sets gateway address of ethernet card
                IPAddress               subnet(255, 255, 255, 0);                         // Sets subnet address of ethernet card
                IPAddress               dnServer(192,168,88,1);                           // Sets DNS server address of ethernet card
                                
/*------------------------------------------------------------------------- Initialise Hardware ----------------------------------------------------------------
                                                                                                                                                              */
                RTC_DS1307              rtc;
                LiquidCrystal_I2C       lcd(LCD_ADDRESS,2,1,0,4,5,6,7,3,POSITIVE);        // LCD 20.04 time, temperature, humidity and barometric pressure: 
                Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
                #define                 DHTTYPE           DHT22                           // DHT 22  (AM2302)
                DHT                     dht(DHTPIN, DHTTYPE);
                DHT                     dht1(DHT1PIN, DHTTYPE);
                DHT                     dht2(DHT2PIN, DHTTYPE);
                Mudbus                  Mb;                                               // modbus

/*--------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------- Setup ------------------------------------------------------------------------------
                                                                                                                                                              */
void setup() {
  Serial.begin(9600);
  Serial2.begin(9600);                                                                    // Start xBee COM Port
  Serial.println("   Integrated Networking Systems Pty Ltd");                             // Output a friendly message to Serial Monitor
  Serial.println("         Home Automation Project");
  Serial.println("Coded by John Wood and Paul Alting van Geusau");
  Serial.println("                    2015\n\n");

  Serial3.println("   Integrated Networking Systems Pty Ltd");                             // Output a friendly message to Serial Monitor
  Serial3.println("         Home Automation Project");
  Serial3.println("Coded by John Wood and Paul Alting van Geusau");
  Serial3.println("                    2015\n\n");
  
  rtc.begin();                                                                            // Start the Real Time Clock
  Wire.begin();
  dht.begin();                                                                            // Start 1st DHT22 Sensor
  dht1.begin();                                                                           // Start 2nd DHT22 Sensor
  dht2.begin();                                                                           // Start 3rd DHT22 Sensor
  lcd.begin(20,4);                                                                        // Start LCD Display with 20 Characters 4 lines
  
  // Analgue Pins
  pinMode(PIRPIN, INPUT);                                                                 // Set PIR0 Pin as Input
  pinMode(PIR1PIN, INPUT);                                                                // Set PIR1 Pin as Input
  pinMode(PIR2PIN, INPUT);                                                                // Set PIR2 Pin as Input
  pinMode(LDRPIN, INPUT);                                                                 // Set LDR Pin as Input
  pinMode(LDR2PIN, INPUT);                                                                // Set LDR2 Pin as Input
  pinMode(BATHGAS01PIN, INPUT);                                                           // Set Bathroom GAS Sensor 1 Pin as INPUT
  pinMode(BATHGAS02PIN, INPUT);                                                           // Set Bathroom GAS Sensor 2 Pin as INPUT
  pinMode(KITGAS01PIN, INPUT);                                                            // Set Kitchen GAS Sensor 1 Pin as INPUT
  pinMode(KITGAS02PIN, INPUT);                                                            // Set Kitchen GAS Sensor 2 Pin as INPUT
  pinMode(KITGAS03PIN, INPUT);                                                            // Set Kitchen GAS Sensor 3 Pin as INPUT
  
  // Digital Pins
  // Relays
  pinMode(BedMainLightRly, OUTPUT);                                                       // RELAY BLOCK 3-1 - Set Main Bedroom Light Relay as output
  pinMode(BedReadLight1Rly, OUTPUT);                                                      // RELAY BLOCK 3-2 - Set Bedroom Reading Light Relay as output
  pinMode(BedReadLight2Rly, OUTPUT);                                                      // RELAY BLOCK 3-3 - Set Bedroom Reading Light Relay as output
  pinMode(Bed2LightRly, OUTPUT);                                                          // RELAY BLOCK 3-4 - Set Zachary's Bed Light Relay as output
  pinMode(ExternalLightRly, OUTPUT);                                                      // RELAY BLOCK 4-1 - Set Outside Light Relay as output
  pinMode(BathLightRly, OUTPUT);                                                          // RELAY BLOCK 4-2 - Set Bathroom Light Relay as output
  pinMode(OfficeLightRly, OUTPUT);                                                        // RELAY BLOCK 4-3 - Set Office Light Relay as output
  pinMode(MainLightRly, OUTPUT);                                                          // RELAY BLOCK 4-4 - Set Main Living Area Light Relay as output
  pinMode(NightLightRly, OUTPUT);                                                         // RELAY BLOCK 5-1 - Set Night Light Relay as output
  pinMode(BathFANRly, OUTPUT);                                                            // RELAY BLOCK 5-2 - Set Bathroom Exhaust FAN Relay as output
  pinMode(KitchenFANRly, OUTPUT);                                                         // RELAY BLOCK 5-3 - Set Kitchen Exhaust FAN as output
  pinMode(NightLight2Rly, OUTPUT);                                                        // RELAY BLOCK 5-4 - Set Night Light 2 Relay as output

  digitalWrite(BathLightRly, true);
  
  // Capacitive Touch Buttons
  pinMode(BedMainLightSw1, INPUT);                                                        // CAP TOUCH - 
  pinMode(BedMainLightSw2, INPUT);                                                        // CAP TOUCH - 
  pinMode(BedReadLightSw1, INPUT);                                                        // CAP TOUCH - 
  pinMode(BedReadLightSw2, INPUT);                                                        // CAP TOUCH - 
  pinMode(Bed2LightSw1, INPUT);                                                           // CAP TOUCH - 
  pinMode(Bed2LightSw2, INPUT);                                                           // CAP TOUCH - 
  pinMode(RearExternalLightSw, INPUT);                                                    // CAP TOUCH - 
  pinMode(FontExternalLightSw, INPUT);                                                    // CAP TOUCH - 
  pinMode(BathLightSw, INPUT);                                                            // CAP TOUCH - 
  pinMode(OfficeLightSw, INPUT);                                                          // CAP TOUCH - 
  pinMode(MainLightSw, INPUT);                                                            // CAP TOUCH - 
  pinMode(BathExhaustFanSw, INPUT);                                                       // CAP TOUCH - 
  pinMode(KitExhaustFanSw, INPUT);                                                        // CAP TOUCH - 

  Ethernet.begin(mac, ip, dnServer, gateway, subnet);                                     // initialise the ethernet interface:
  Serial.println("Ethernet Initisalised! ");
  Serial.print("Ethernet IP:  ");
  Serial.println(Ethernet.localIP());
  
  if (!rtc.isrunning()) {                                                                 // Check if the RTC is running.
    Serial.println("RTC is NOT running");
  } else {
    Serial.println("RTC Inisalised");
  }
  
  DateTime now = rtc.now();                                                               // This section grabs the current datetime and compares it to
  DateTime compiled = DateTime(__DATE__, __TIME__);                                       // the compilation time.  If necessary, the RTC is updated.
  if (now.unixtime() < compiled.unixtime()) {
    Serial.println("RTC is older than compile time! Updating");
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }
  
  if(!bmp.begin())                                                                        // Initialise the BP180 sensor
  {
    Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
    while(1);
  } else {
    Serial.println("BMP180 Inisalised");
  }

  if (isnan(dht22Humidity) || isnan(dht22Temperature)) {                                  // Check DHT sensor if any reads failed and exit early (to try again).
    Serial.println("DHT22 Sensor 1 has failed to Inisalise! ");
  } else {
    Serial.println("DHT22 Sensor 1 Inisalised! ");
  }
  if (isnan(dht22Humidity2) || isnan(dht22Temperature2)) {                                // Check DHT sensor if any reads failed and exit early (to try again).
    Serial.println("DHT22 Sensor 2 has failed to Inisalise! ");
  } else {
    Serial.println("DHT22 Sensor 2 Inisalised! ");
  }
  if (isnan(dht22Humidity3) || isnan(dht22Temperature3)) {                                // Check DHT sensor if any reads failed and exit early (to try again).
    Serial.println("DHT22 Sensor 3 has failed to Inisalise! ");
  } else {
    Serial.println("DHT22 Sensor 3 Inisalised! ");
  }
   
}

/*------------------------------------------------------------------------- Loop -----------------------------------------------------------------------------*/

void loop() {
  
  if (millis() - lastSensorScan >= periodSensorScan) {                                    // Run this every 2500ms as set in periodSensorScan
    
    getBMP180Readings();
    getDHT22Readings();
    
    getGASSensors();
    
    lastSensorScan = millis();
  }
  
  modbus();                                                                               // modbus runs without timming - full speed

  if (millis() - lastCAPScan >= periodCAPScan) {                                          // Run this every 
    capacitivetouch();
    lastCAPScan = millis();
  }
  
  if (millis() - lastLCDScan >= periodLCDScan) {                                          // Run this every 250ms as set in periodLCDScan
    writeLCD();
    
    pir();
    lastLCDScan = millis();
  }

    
}

/*--------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------- FUNCTIONS --------------------------------------------------------------------------

--------------------------------------------------------------------------- writeLCD ---------------------------------------------------------------------------

                                                                Displays the data from some sensors
                                                                                                                                                              */
void writeLCD() {
  
  DateTime now = rtc.now();
  
  lcd.setCursor(0,0);
  lcd.print("Time:");
  lcd.setCursor(8,0);
  lcd.print(now.hour(), DEC);
  lcd.print("Hrs ");
  lcd.print(now.minute(), DEC);
  lcd.print("Mins ");
  
  lcd.setCursor(0,1);
  lcd.print("Temperature: ");
  lcd.print(AverageTemp);
  lcd.print((char)223);
  lcd.print("C");
  
  lcd.setCursor(0,2);
  lcd.print("Humidity: ");
  lcd.print(AverageHumidity);
  lcd.print("%");
  
  lcd.setCursor(0,3);
  lcd.print("Pressure: ");
  lcd.print(bmpPressure);
  lcd.print("hPa");
  
}

/*------------------------------------------------------------------------- capaciticetouch --------------------------------------------------------------------

                                                               Process capacitive touch buttons presses
                                                                                                                                                              */
void capacitivetouch() {

  if ((digitalRead(BathLightSw)) && BathLightSwPSt && millis() - time > debounce) {       // check if switch pressed and light is on:
    BathLightSwPSt = false;
    digitalWrite(BathLightRly, true);                                                    // turn light off:
    Serial2.println("Bath Light current Switch state: off");
    BathLightRlyState = false;
  } else if (digitalRead(BathLightSw) && !BathLightSwPSt) {                               // check if switch is pressed and light is off:
    BathLightSwPSt = true;
    digitalWrite(BathLightRly, false);                                                     // turn light on:
    Serial2.println("Bath Light current Switch state: on");
    BathLightRlyState = true;
    time = millis();
  }
}


/*------------------------------------------------------------------------- getBMP180Readings ------------------------------------------------------------------

    Gets the bearametric pressure and temperature then calcultes the altitude. I use the DHT22 sensor for temperature for calculation as its more accurate
                                                                                                                                                              */
void getBMP180Readings() {                                                                // Get the Pressure, Temperature and calculate Altitude
  
  sensors_event_t event;                                                                  // Get a new sensor event
  bmp.getEvent(&event);
                                                          
  if (event.pressure)                                                                     // Display the results (barometric pressure is measure in hPa)
  {
    bmpPressure = (event.pressure);                                                       // Display atmospheric pressue in hPa
    bmp.getTemperature(&bmpTemperature);                                                  // First we get the current temperature from the BMP085
 
                                                                                          // Then convert the atmospheric pressure, SLP and temp to altitude
    bmpAltitude =  (bmp.pressureToAltitude(seaLevelPressure,                              // Update this next line with the current SLP for better results
                                           event.pressure,                                // SENSORS_PRESSURE_SEALEVELHPA                              
                                           AverageTemp));                                 // Use DHT22 Temp sensor for acuracy

  }
  else
  {
    Serial.println("BMP180 Sensor error! ");
  }
  
  ScaledbmpPressure = (bmpPressure * 10);                                                // Bearometric Pressure (scaled * 100)
  ScaledbmpTemperature = (bmpTemperature * 100);                                          // BMP Temperature Sensor (scaled * 100)
  ScaledbmpAltitude = (bmpAltitude * 10);                                                // BMP Sensor Calculated Altitude (scaled * 100)
  
  
}

/*------------------------------------------------------------------------- getDHT22Readings -------------------------------------------------------------------

                           Gets the temperature and humidity from 3 DHT22 sensors the calculates the average temperature and humdity
                                                                                                                                                              */
void getDHT22Readings() {
  
  dht22Temperature = dht.readTemperature();                                               // get temperature from 1st DHT22 sensor
  dht22Temperature2 = dht1.readTemperature();                                             // get temperature from 2nd DHT22 sensor
  dht22Temperature3 = dht2.readTemperature();                                             // get temperature from 3rd DHT22 sensor
  dht22Humidity = dht.readHumidity();                                                     // get humidity from 1st DHT22 sensor
  dht22Humidity2 = dht1.readHumidity();                                                   // get humidity from 2nd DHT22 sensor
  dht22Humidity3 = dht2.readHumidity();                                                   // get humidity from 3rd DHT22 sensor
  
  if (isnan(dht22Humidity) || isnan(dht22Temperature)) {                                  // Check DHT sensor if any reads failed and exit early (to try again).
    Serial.println("DHT22 Sensor 1 has failed to Inisalise! ");
    return;
  }  
  if (isnan(dht22Humidity2) || isnan(dht22Temperature2)) {                                // Check DHT sensor if any reads failed and exit early (to try again).
    Serial.println("DHT22 Sensor 2 has failed to Inisalise! ");
    return;
  }
  if (isnan(dht22Humidity3) || isnan(dht22Temperature3)) {                                // Check DHT sensor if any reads failed and exit early (to try again).
    Serial.println("DHT22 Sensor 3 has failed to Inisalise! ");
    return;
  }
  
  AverageTemp = (dht22Temperature + dht22Temperature2 + dht22Temperature3) / 3;           // Calculate average temperature
  ScaledAverageTemp = (AverageTemp * 100);                                                // average Temp of DHT, DHT1 and DHT2 temperatures (scaled * 100):
  AverageHumidity = (dht22Humidity + dht22Humidity2 + dht22Humidity3) / 3;                // Calculate average humidity
  ScaledAverageRH = (AverageHumidity * 100);                                              // average RH of DHT, DHT1 and DHT2 humidities (scaled * 100):
  //Serial2.print("Temperature : ");
  //Serial2.println(AverageTemp);
}

/*------------------------------------------------------------------------- pir --------------------------------------------------------------------------------

                  Turns on a night light connected to RELAY 1 of Block 1 when the room is dark (LDR) and there is movement detected (3 x PIR's)
                                                                                                                                                              */
void pir() {
 
 PIRPINState = digitalRead(PIRPIN);
 Serial2.print("PIR 1: "); Serial2.println(PIRPINState);
 PIR1PINState = digitalRead(PIR1PIN);
 Serial2.print("PIR 2: "); Serial2.println(PIR1PINState);
 PIR2PINState = digitalRead(PIR2PIN);
 Serial2.print("PIR 3: "); Serial2.println(PIR2PINState);
 LDRState = analogRead(LDRPIN);
 LDR2State = analogRead(LDR2PIN);
 Serial2.print("LDR 1 State: ");
 Serial2.println(LDRState);
 Serial2.print("LDR 2 State: ");
 Serial2.println(LDR2State);
   
 if ((LDRState < LDRbrightness) && (PIRPINState == HIGH)){
  digitalWrite(NightLightRly,LOW);
  NightLightState = true;
 } else {
  digitalWrite(NightLightRly,HIGH);
  NightLightState = false;
 }

 if ((LDR2State > LDR2brightness) &&  ((PIR1PINState == HIGH) or (PIR2PINState == HIGH))) {
  digitalWrite(NightLight2Rly,LOW);
  NightLight2State = true;
 } else {
  digitalWrite(NightLight2Rly,HIGH);
  NightLight2State = false;
 }

}

/*------------------------------------------------------------------------- getGASSensors ----------------------------------------------------------------------

                   Get the Readings from the 5 GAS Sensors and compaire to presets to turn on/off exhaust fans when gas detected over preset value
                                                                                                                                                              */
void getGASSensors() {

  BathGasSensor1 = analogRead(BATHGAS01PIN);
  BathGasSensor2 = analogRead(BATHGAS02PIN);
    
  KitGasSensor1 = analogRead(KITGAS01PIN);
  KitGasSensor2 = analogRead(KITGAS02PIN);
  KitGasSensor3 = analogRead(KITGAS03PIN);
  
  if ((BathGasSensor1 > BathGas1Preset) or (BathGasSensor2 > BathGas2Preset)) { 
   digitalWrite(BathFANRly,LOW);
   BathFanRlyState = true;                                                                // Set the bathroom exhaust fan on/off flag
  } else {
   digitalWrite(BathFANRly,HIGH);
   BathFanRlyState = false;
 }

 if (BathGasSensor1 > BathGas1Preset) {                                                   // Set the gas detected flag
  BathGas1Detected = true;
 } else {
  BathGas1Detected = false;
 }

 if (BathGasSensor2 > BathGas2Preset) {
  BathGas2Detected = true;
 } else {
  BathGas2Detected = false;                                                               // Set the gas detected flag
 }

 if ((KitGasSensor1 > KitGas1Preset) or (KitGasSensor2 > KitGas2Preset) or (KitGasSensor3 > KitGas3Preset)) {
  digitalWrite(KitchenFANRly,LOW);
  KitFanRlyState = true;                                                                  // Set the kitchen exhaust fan on/off flag
  } else {
  digitalWrite(KitchenFANRly,HIGH);
  KitFanRlyState = false;
 }

 if (KitGasSensor1 > KitGas1Preset) {                                                     // Set the gas detected flag
  KitGas1Detected = true;
 } else {
  KitGas1Detected = false;
 }

 if (KitGasSensor2 > KitGas2Preset) {                                                     // Set the gas detected flag
  KitGas2Detected = true;
 } else {
  BathGas2Detected = false;
 }

 if (KitGasSensor3 > KitGas3Preset) {                                                     // Set the gas detected flag
  KitGas3Detected = true;
 } else {
  KitGas3Detected = false;
 }
  
}

/*------------------------------------------------------------------------- modbus -----------------------------------------------------------------------------

                                           Collect all data from all sensors, switches  etc and send via modbus over tcp/ip
                                                                                                                                                              */
                                                                                                                                                            
void modbus() {
  
  Mb.R[0] = packBitsRead;                                                                 // 16 bit field to hold bits to be read in via Modbus:
  Mb.R[1] = packBitsWrite;                                                                // 16 bit field to hold bits to be written out via Modbus:
  Mb.R[2] = ScaledAverageTemp;                                                            // average Temp of DHT, DHT1 and DHT2 temperatures (scaled * 100):
  Mb.R[3] = ScaledAverageRH;                                                              // average RH of DHT, DHT1 and DHT2 humidities (scaled * 100):
  Mb.R[4] = ScaledbmpPressure;                                                            // Bearometric Pressure (scaled * 100)
  Mb.R[5] = ScaledbmpTemperature;                                                         // BMP Temperature Sensor (scaled * 100)
  Mb.R[6] = ScaledbmpAltitude;                                                            // BMP Sensor Calculated Altitude (scaled * 100)
  Mb.R[7] = BedMainLightRlyState;                                                         // stores the current on/off state of master bedroom main light
  Mb.R[8] = BedReadLight1RlyState;                                                        // stores the current on/off state of master bedroom reading light 1
  Mb.R[9] = BedReadLight2RlyState;                                                        // stores the current on/off state of master bedroom reading light 2
  Mb.R[10] = Bed2LightRlyState;                                                           // stores the current on/off state of 2nd bedroom light
  Mb.R[11] = ExternalLightRlyState;                                                       // stores the current on/off state of external light
  Mb.R[12] = BathLightRlyState;                                                           // stores the current on/off state of bathroom light
  Mb.R[13] = OfficeLightRlyState;                                                         // stores the current on/off state of office light
  Mb.R[14] = MainLightRlyState;                                                           // stores the current on/off state of living area light
  Mb.R[15] = NightLightState;                                                             // stores the current on/off state of nightlight 1
  Mb.R[16] = NightLight2State;                                                            // stores the current on/off state of nightlight 2
  Mb.R[17] = BathFanRlyState;                                                             // stores the current on/off state of bathroom exhaust fan
  Mb.R[18] = KitFanRlyState;                                                              // stores the current on/off state of kitchen exhaust fan
  Mb.R[19] = BathGas1Detected;                                                            // stores the bathroom gas sensor 1 detected flag
  Mb.R[20] = BathGas2Detected;                                                            // stores the bathrrom gas sensor 2 detected flag
  Mb.R[21] = KitGas1Detected;                                                             // stores the kitchen gas sensor 1 detected flag
  Mb.R[22] = KitGas2Detected;                                                             // stores the kitchen gas sensor 2 detected flag
  Mb.R[23] = KitGas3Detected;                                                             // stores the kitchen gas sensor 3 detected flag
     
  Mb.Run();
 
}

/*------------------------------------------------------------------------------------------------------------------------------------------------------------*/

Tri-Metric

C/C++
Collects Tri-Metric Serial data and sends over Modbus
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                       
                                            Integrated Networking Systems Home Automation Project
                                                        MEGA-TriMetric.ino Ver 1.0
                                                        
      This code listens on serial port 1 for data from a 2400 baud data stream from a Tri-Metric Battery Monitor:
      The format of the data is a continous repeating stream, for example:
      V=14.3,FV=14.3,V2=00.0,A=02.5,FA=02.5,AH=45.7,%=108,W=35.8,DSC=0.00,DSE=14.0,

      We have to break this down into variables V= FV= V2= A= FA= AH= PER= W= DSC= DSE= and then transmit them over MODBUS TCP
      to be displayed and manipulated on a Raspberry Pi 2 with Quadlog SCADA Server Software.
      
                                                                 Home Automation Project by Integrated Networking Systems Pty Ltd
                                                                               Coded by John Wood and Paul Alting van Geusau 2015

--------------------------------------------------------------------------- Header Files ----------------------------------------------------------------------------
                                                                                                                                                                   */
#include "arduino.h"
#include <SPI.h>
#include <Ethernet.h>
#include <Mudbus.h>             									                                        // https://gitorious.org/mudbus
#include "stdlib.h"
#include "Wire.h"
#include <LiquidCrystal_I2C.h>

/*------------------------------------------------------------------------- Define I2C Address: ---------------------------------------------------------------------
                                                                                                                                                                   */
#define         LCD_ADDRESS             0x26                                              // address for LCD:

/*------------------------------------------------------------------------- Digital Pin Definition ------------------------------------------------------------------
                                                                                                                                                                   */
//#define       RX0                     0                                                 // Serial Rx0 Port - USB
//#define       TX0                     1                                                 // Serial Tx0 Port - USB
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
#define         KitLightSw              2                                                 // PWM - CAP-TOUCH - Kitchen Light switch
//#define                               3                                                 // PWM - 
//#define       SSSDCARD                4                                                 // PWM - SS for SD Card
//#define                               5                                                 // PWM - 
//#define                               6                                                 // PWM - 
//#define                               7                                                 // PWM - 
//#define                               8                                                 // PWM - 
//#define                               9                                                 // PWM -  
//#define       SSETHERNET              10                                                // PWM - SS for Ethernet Sheild
//#define                               11                                                // PWM - 
//#define                               12                                                // PWM - 
//#define                               13                                                // PWM - 
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
//#define       TX3                     14                                                // Serial Tx3 Port - 
//#define       RX3                     15                                                // Serial Rx3 Port - 
//#define       TX2                     16                                                // Serial Tx2 Port - 
//#define       RX2                     17                                                // Serial Rx2 Port - 
//#define       TX1                     18                                                // Serial Tx1 Port - 
//#define       RX1                     19                                                // Serial Rx1 Port - Tri-Metric Battery Monitor
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
//#define       SDA                     20                                                // SDA - I2C Bus
//#define       SCL                     21                                                // SDL - I2C Bus
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Relays
#define         KitLightRly             22                                                // RELAY BLOCK 1-1 - Kitchen Light
//#define                               23                                                // RELAY BLOCK 1-2 - 
//#define                               24                                                // RELAY BLOCK 1-3 -
#define         BattChargerRly          25                                                // RELAY BLOCK 1-4 - Batter Charger
//#define                               26                                                // RELAY BLOCK 2-1 -
//#define                               27                                                // RELAY BLOCK 2-2 -
//#define                               28                                                // RELAY BLOCK 2-3 -
//#define                               29                                                // RELAY BLOCK 2-4 -
#define         MainWaterPumpRly        30                                                // REMOTE RELAY 1-1 - Water Pump
#define         MainSolenoidRly         31                                                // REMOTE RELAY 1-2 - Mains Water Solenoid
//#define       TankSloenoidRly         32                                                // REMOTE RELAY 2-1 - Tank Water Solenoid
//#define       FillSolenoidRly         33                                                // REMOTE RELAY 2-2 - Fill Solenoid
#define         BlackWaterPumpRly       34                                                // REMOTE RELAY 3-1 - Black Water pump
#define         BlackWaterSloenoidRly   35                                                // REMOTE RELAY 3-2 - Black Water solenoid
#define         AirConOnOffRly          36                                                // REMOTE RELAY 4-1 - Air Conitioner on/off relay
#define         AirConThermoRly         37                                                // REMOTE RELAY 4-2 - Air Conditioner thermostat on/off relay

// Capacitive Touch Buttons
//#define       MainTankWaterSw         38                                                // Pin 38 CAP TOUCH - Mains Water/Tank Water switch
//#define       FillTankSw              39                                                // Pin 39 CAP TOUCH - Fill Tank switch
//#define       OpenBlkWaterSol         40                                                // Pin 40 CAP TOUCH - Open black water tank drain solenoid
//#define       BlkWaterPumpSw          41                                                // Pin 41 CAP TOUCH - black water pump on/off
//#define       AirConPowerSw           42                                                // Pin 42 CAP TOUCH - Air conditioner on/off switch
//#define       AirConTempUpSw          43                                                // Pin 43 CAP TOUCH - Air condtioner temperature up switch
//#define       AirConTempDownSw        44                                                // Pin 44 CAP TOUCH - Air conditioner temperature down switch
//#define       AirConTimerSw           45                                                // Pin 45 CAP TOUCH - Air conditioner timer switch
//#define       AirConPowerSw1          46                                                // Pin 46 CAP TOUCH - Air conditioner on/off switch 2
//#define       AirConTempUp1Sw         47                                                // Pin 47 CAP TOUCH - Air condtioner temperature up switch 2
//#define       AirConTempDown1Sw       48                                                // Pin 48 CAP TOUCH - Air conditioner temperature down switch 2
//#define       AirConTimerSw1          49                                                // Pin 49 CAP TOUCH - Air conditioner timer switch 2
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
//#define       MISO                    50                                                // MISO
//#define       MOSI                    51                                                // MOSI
//#define       SCK                     52                                                // SCK
//#define       HARDWARESS              53                                                // Hardware SS

/*------------------------------------------------------------------------- Analogue Pin Definition -----------------------------------------------------------------
                                                                                                                                                                   */
// Define Pins for Current Sensors
#define         pin_iSensor_1           A0                                                // analog pin for Regulated 12 Volt Rail 30A Current Sensor:
#define         pin_iSensor_2           A1                                                // analog pin for Regulated 5 Volt Rail 30A Current Sensor:
#define         pin_iSensor_3           A2                                                // analog pin for UnRegulated 12 Volt Rail 50A Current Sensor:
#define         pin_iSensor_4           A3                                                // analog pin for Battery Charger 90A Current Sensor:

// 90 Amp Sensor Datasheet http://cdn.sparkfun.com/datasheets/Sensors/Current/DC%20Voltage%20and%20Current%20Sense%20PCB%20with%20Analog%20Output.pdf

//Define Pins for Voltage Divider Sensors
#define         pin_vSensor_1           A4                                                // analog pin for battery charger voltage. sensor #1:
#define         pin_vSensor_2           A5                                                // analog pin for regulated 12 volt voltage. sensor #2:

//#define                               A6                                                // 
//#define                               A7                                                // 
//#define                               A8                                                // 
//#define                               A9                                                // 
//#define                               A10
//#define                               A11
//#define                               A12
//#define                               A13
//#define                               A14
//#define                               A15

/*------------------------------------------------------------------------- Global Variables ------------------------------------------------------------------------
                Type                    Variable Name           Value                     Comments
                                                                                                                                                                   */
//                                             Tri-Metric Battery Monitor Variables:
#define                                 tm_buffer_size           96                       // size of buffer to hold all TriMetric data:
                boolean       		      tm_scan_ons             =   true;	          	    // scan one shot trigger:
                boolean	        	      tm_scan_37              =   false;					      // scan for second '%':
                uint8_t		              tm_buffer_index         =   0;                    // buffer index:
                uint8_t		              tm_buffer[tm_buffer_size];                        // buffer to hold all data from TriMetric:

                uint16_t        	      volts_1                 =   0;                    // Volts 1
                uint16_t	              volts_filtered_1        =   0;                    // Volts average 1
                uint16_t	              volts_2                 =   0;                    // Volts 2
                uint16_t	              amps                    =   0;                    // Amps
                uint16_t	              amps_filtered           =   0;                    // Amps average
                uint16_t	              amp_hours               =   0;                    // Amp Hours
                uint16_t	              soc                     =   0;                    // state of charge %
                uint16_t	              watts                   =   0;                    // Watts
                uint16_t	              days_since_charge       =   0;                    // Days Since Charge
                uint16_t	              days_since_equalise     =   0;                    // Days Since Equalise

//                                                   Timer Variables:
                uint32_t        	      lastTM_Scan             =   0;		                // present timer value:
                uint32_t	              periodTM_Scan           =   2000;						      // timer period pre-set:
                uint32_t                lastlcdWrite_Scan       =   0;                    // LCD Write timer
                uint32_t                periodlcdWrite_Scan     =   2000;

/*                                      Relay State Variables                                                                                                      */
                boolean                 KitLightRlyState        =   false;                // stores the current on/off state of night light
/*              boolean                 RELAY BLOCK 1-2State    =   false;                // 
                boolean                 RELAY BLOCK 1-3State    =   false;                // */
                boolean                 BattChargerRlyState     =   false;                // 
/*              boolean                 RELAY BLOCK 2-1State    =   false;                // 
                boolean                 RELAY BLOCK 2-2State    =   false;                // 
                boolean                 RELAY BLOCK 2-3State    =   false;                // 
                boolean                 RELAY BLOCK 2-4State    =   false;                //                                                                       */
                boolean                 MainWaterPumpRlyState   =   false;                // 
                boolean                 MainSolenoidRlyState    =   false;                // 
                boolean                 TankSolenoidRlyState    =   false;                // 
                boolean                 FillSolenoidRlyState    =   false;                // 
                boolean                 BlackWaterPumpRlyState  =   false;                // stores the current on/off state of night light
                boolean                 BlkWaterSloenoidRlyState=   false;                // 
                boolean                 AirConOnOffRlyState     =   false;                // stores the current on/off state of bathroom exhaust fan
                boolean                 AirConThermoRlyState    =   false;                // stores the current on/off state of kitchen exhaust fan

/*                                      Capacitive Touch Button States                                                                                             */
                boolean                 KitLightSwState         =   false;                // 
                boolean                 MainTankWaterSwState    =   false;                // 
                boolean                 FillTankSwState         =   false;                // 
                boolean                 OpenBlkWaterSolState    =   false;                // 
                boolean                 BlkWaterPumpSwState     =   false;                // 
                boolean                 AirConPowerSwState      =   false;                // 
                boolean                 AirConTempUpSwState     =   false;                // 
                boolean                 AirConTempDownSwState   =   false;                // 
                boolean                 AirConTempTimerSwState  =   false;                // 
                boolean                 AirConPowerSw1State     =   false;                // 
                boolean                 AirConTempUp1SwState    =   false;                // 
                boolean                 AirConTempDown1SwState  =   false;                // 
                boolean                 AirConTempTimer1SwState =   false;                // 

/*                                      Battery Charger Variables                                                                                                  */
                uint16_t                ChargerStartVolts       =   12.2;                 // Preset voltage for battery charger to turn on at
                uint16_t                ChargerStopVolts        =   14.3;                 // Preset voltage for battery charger to turn off at
                
/*                                      Ethernet Variables                                                                                                         */
                uint8_t                 mac[6] = {0xDE, 0xAB, 0xBF, 0xEF, 0xFE, 0xEF};    // MAC address, default is {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}:
                IPAddress               ip(192,168,88,178);                               // Sets IP address of ethernet card
                IPAddress               gateway(192,168,88, 1);                           // Sets gateway address of ethernet card
                IPAddress               subnet(255, 255, 255, 0);                         // Sets subnet address of ethernet card
                IPAddress               dnServer(192,168,88,1);                           // Sets DNS server address of ethernet card

                
/*------------------------------------------------------------------------- Initialise Hardware ---------------------------------------------------------------------
                                                                                                                                                                   */
                LiquidCrystal_I2C       lcd(LCD_ADDRESS,2,1,0,4,5,6,7,3,POSITIVE);
                Mudbus                  Mb;                                               // setup Modbus instance:

/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                                                                                                   */
void readTriMetric(uint8_t inByte);
void processTriMetricBuffer();
void modbus();

// Current Sensor Variables:
struct  iSensor_t
            {
                boolean         offset512;                                                // set for bi-directional sensor, offset is 512, bit 9, otherwise reset:
                uint8_t         pin_sensor;                                               // instance of sensor pin:
                int16_t         mVAmp_sp;                                                 // sensor sensitivity in mV per Amp:
                int16_t         offset_sp;                                                // offset value to be applied:
                int16_t         raw_pv;                                                   // present value of raw ADC counts, 0 - 1023:
                int16_t         value_pv;                                                 // present value of Amps (scaled * 100):
            };
 
                iSensor_t       iSensor_1 = {false, pin_iSensor_1, 66, 512};              // pin 0, scale is 66mV per Amp, offset is ADC max  2, sensor is 30Amps:
                iSensor_t       iSensor_2 = {false, pin_iSensor_2, 66, 512};              // pin 1, scale is 66mV per Amp, offset is ADC max  2, sensor is 30Amps:
                iSensor_t       iSensor_3 = {false, pin_iSensor_3, 40, 512};              // pin 2, scale is 40mV per Amp, offset is ADC max  2, sensor is 50Amps:
                iSensor_t       iSensor_4 = {false, pin_iSensor_4, 33, 512};              // pin 3, scale is 33mV? per Amp, offset is ADC max  2, sensor is 90Amps:

// Voltage Sensor Variables:
                int             val11; 
                int             volts_12vReg; 

/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------- Setup -----------------------------------------------------------------------------------
                                                                                                                                                                   */
void setup() {
	delay(500);											                                                        // wait for ethernet CPU to come out of reset:
	
	Serial.begin(9600);										                                                  // setup normal serial out for debug:
  Serial1.begin(2400);                                                                    // setup serial 1 for TriMetric meter:
  Serial3.begin(9600);                                                                    // Bluetooth Serial Port
  
  Serial.println("   Integrated Networking Systems Pty Ltd");                             // Output a friendly message to Serial Monitor
  Serial.println("         Home Automation Project");
  Serial.println("Coded by John Wood and Paul Alting van Geusau");
  Serial.println("                  2015\n\n");

  Serial3.println("INS Home Automation Project.");
  Serial3.println("Bluetooth Serial Port Initilised.");
  
  Wire.begin();                                                                           // initialize I2C wire interface:
  lcd.begin(20,4);

  //Realys
  pinMode(KitLightRly,OUTPUT);                                                            // RELAY BLOCK 1-1 - Kitchen Light
/*pinMode(RELAY BLOCK 1-2, OUTPUT);                                                       // RELAY BLOCK 1-2 - 
  pinMode(RELAY BLOCK 1-3, OUTPUT);                                                       // RELAY BLOCK 1-3 - */
  pinMode(BattChargerRly, OUTPUT);                                                        // RELAY BLOCK 1-4 - 
/*pinMode(RELAY BLOCK 2-1, OUTPUT);                                                       // RELAY BLOCK 2-1 - 
  pinMode(RELAY BLOCK 2-2, OUTPUT);                                                       // RELAY BLOCK 2-2 - 
  pinMode(RELAY BLOCK 2-3, OUTPUT);                                                       // RELAY BLOCK 2-3 - 
  pinMode(RELAY BLOCK 2-4, OUTPUT);                                                       // RELAY BLOCK 2-4 -                                                     */
  pinMode(MainWaterPumpRly, OUTPUT);                                                      // REMOTE RELAY BLOCK 1-1
  pinMode(MainSolenoidRly, OUTPUT);                                                       // REMOTE RELAY BLOCK 1-2
/*pinMode(TankSloenoidRly, OUTPUT;                                                        // REMOTE RELAY BLOCK 1-1
  pinMode(FillSloenoidRly, OUTPUT;                                                        // REMOTE RELAY BLOCK 2-1                                                */
  pinMode(BlackWaterPumpRly,OUTPUT);                                                      // REMOTE RELAY BLOCK 2-1
  pinMode(BlackWaterSloenoidRly,OUTPUT);                                                  // REMOTE RELAY BLOCK 2-2
  pinMode(AirConOnOffRly,OUTPUT);                                                         // REMOTE RELAY BLOCK 3-1
  pinMode(AirConThermoRly,OUTPUT);                                                        // REMOTE RELAY BLOCK 3-2

/*Capacitive Touch Buttons
  pinMode(KitLightSw, INPUT);                                                             // 
  pinMode(MainTankWaterSw, INPUT);                                                        // 
  pinMode(FillTankSw, INPUT);                                                             // 
  pinMode(OpenBlkWaterSol, INPUT);                                                        // 
  pinMode(BlkWaterPumpSw, INPUT);                                                         // 
  pinMode(AirConPowerSw, INPUT);                                                          // 
  pinMode(AirConTempUpSw, INPUT);                                                         // 
  pinMode(AirConTempDownSw, INPUT);                                                       // 
  pinMode(AirConTimerSw, INPUT);                                                          // 
  pinMode(AirConPowerSw1, INPUT);                                                         // 
  pinMode(AirConTempUp1, INPUT);                                                          // 
  pinMode(AirConTempDown1, INPUT);                                                        // 
  pinMode(AirConTimer1, INPUT);                                                           //                                                                       */

  Ethernet.begin(mac, ip, dnServer, gateway, subnet);                                     // Setting up the IP address.
  Serial.println("Ethernet Initisalised! ");
  Serial.print("Ethernet IP:  ");
  Serial.println(Ethernet.localIP());

	Serial.println("Waiting for data from TriMetric\n");
}

/*------------------------------------------------------------------------- Loop ------------------------------------------------------------------------------------
                                                                                                                                                                   */
void loop() {
//	if ((millis() - lastTM_Scan >= periodTM_Scan) && !tm_scan_ons)			                  // call sensorScan read at set period:
//	{
//		tm_scan_ons = true;									                                                // set TM scan one shot:
//	lastTM_Scan = millis();
//	}

//	if (tm_scan_ons)										                                                  // call sensorScan read at set period:
//	{
		if (Serial1.available() > 0)
			readTriMetric(Serial1.read());
//	}

//      
	modbus();
        if (millis() - lastlcdWrite_Scan >= periodlcdWrite_Scan) {
          writeLCD();
          VoltageDivider();
          lastlcdWrite_Scan = millis();
        }
}

/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------- FUNCTIONS -------------------------------------------------------------------------------

--------------------------------------------------------------------------- readTriMetric ---------------------------------------------------------------------------

                                             Constantly Repeating String From Tri-Metric
	               01234567890123456789012345678901234567890123456789012345678901234567890123456 == 77 chars, % is at pos 47
	                             V=14.3,FV=14.3,V2=00.0,A=02.5,FA=02.5,AH=45.7,%=108,W=35.8,DSC=0.00,DSE=14.0,

	                          with the '%' being the start of message character the stream will appear as follows;
	                            %=108,W=35.8,DSC=0.00,DSE=14.0,V=14.3,FV=14.3,V2=00.0,A=02.5,FA=02.5,AH=45.7,%
                                                                                                                                                                   */
void readTriMetric(uint8_t inByte) {
	if (inByte == char('%')) {									                                            // check for '%' character:
		if (tm_scan_37) {									                                                    // check for second '%' character:
			tm_scan_37 = false;								                                                  // second '%' character found, so reset for next message:
			++tm_buffer_index;								                                                  // increment buffer index:
			tm_buffer[tm_buffer_index] = '\0';						                                      // put NULL at end:
			processTriMetricBuffer();

			for (uint8_t i = 0; i < 128; i++)
			{
				tm_buffer[i] = '\0';							                                                // clear the buffer by filling with NULLS:
			}
		} else
		{
			tm_scan_37 = true;								                                                  // set flag:
		}

		tm_buffer_index = 0;									                                                // reset buffer index to start of buffer:
		tm_buffer[tm_buffer_index] = inByte;							                                    // put % into correct location at index:
	} else {
		++tm_buffer_index;									                                                  // increment buffer index:
		tm_buffer[tm_buffer_index] = inByte;							                                    // put % into correct location at index:
	}
}

/*------------------------------------------------------------------------- processTriMetricBuffer ------------------------------------------------------------------
                                                                                                                                                                   */
void processTriMetricBuffer() {
	uint8_t		i = 0;										                                                     // buffer index:
	uint8_t		k = 0;										                                                     // command index:
	char		cmd[5];										                                                       // char array to hold command:
	char		cmdData[8];									                                                     // char array to hold command data:
	int16_t		cmdValue = 0;
	float		cmdFloat = 0.0;

	Serial.print("\n");
	while (i < tm_buffer_index)									                                              // go through buffer:
	{
		k = 0;											                                                            // reset the cmd index:
		while (tm_buffer[i] != char('='))							                                          // build the cmd upto the '=':
		{
  			cmd[k] = tm_buffer[i];
			i++;
			k++;
  		}
  		cmd[k] = char('#');									                                                  // place the '=' inthe cmd buffer as it is used on some checks:
		i++;											                                                              // advance the buffer index to point to cmaData value:

		k = 0;											                                                            // reset the cmdData index:
		while (tm_buffer[i] != char(','))							                                          // build cmd data upto the ',':
		{
			cmdData[k] = tm_buffer[i];
			i++;
			k++;
		}
		i++;

		cmdData[k] = '\0';									                                                    // add termination NULL char for float conversion:
		cmdFloat = atof(cmdData);								                                                // convert char array upto NULL to float:
		cmdValue = int(cmdFloat * 10);								                                          // convert to int16_t and scale up by 10:


		if (cmd[0] == char('%'))								                                                // command soc:
		{
			soc = (uint16_t)cmdValue;
			Serial.print("SOC: ");
		}

		if (cmd[0] == char('W'))								                                                // command watts:
		{
			watts = (uint16_t)cmdValue;
			Serial.print("Watts: ");
		} else

		if ((cmd[0] == char('D')) && (cmd[1] == char('S')) && (cmd[2] == char('C')))	          // command DSC:
		{
			days_since_charge = (uint16_t)cmdValue;
			Serial.print("DSC: ");
		} else

		if ((cmd[0] == char('D')) && (cmd[1] == char('S')) && (cmd[2] == char('E')))	          // command DSE:
		{
			days_since_equalise = (uint16_t)cmdValue;
			Serial.print("DSE: ");
		} else

		if ((cmd[0] == char('V')) && (cmd[1] == char('#')))					                            // command V:
		{
			volts_1 = (uint16_t)cmdValue;
			Serial.print("Volts: ");
		} else

		if ((cmd[0] == char('F')) && (cmd[1] == char('V')))					                            // command FV:
		{
			volts_filtered_1 = (uint16_t)cmdValue;
			Serial.print("Volts Filtered: ");
		} else

		if ((cmd[0] == char('V')) && (cmd[1] == char('2')))					                            // command V2:
		{
			volts_2 = (uint16_t)cmdValue;
			Serial.print("Volts 2: ");
		} else

		if ((cmd[0] == char('A')) && (cmd[1] == char('#')))					                            // command A:
		{
			amps = (uint16_t)cmdValue;
			Serial.print("Amps: ");
		} else

		if ((cmd[0] == char('F')) && (cmd[1] == char('A')))					                            // command FA:
		{
			amps_filtered = (uint16_t)cmdValue;
			Serial.print("Amps Filtered: ");
		} else

		if ((cmd[0] == char('A')) && (cmd[1] == char('H')))					                            // command AH:
		{
			amp_hours = (uint16_t)cmdValue;
			Serial.print("Amp Hours: ");
		}
		Serial.println(cmdFloat);								                                                // serial print the float value:
	}
}

/*------------------------------------------------------------------------- readSensorCurrent(void * iSensor_arg) ---------------------------------------------------
    
  
    Analog input, reading and calculating values:
    Good to digest this detailed thread on reading analog inputs on the Arduino forum:
    http://forum.arduino.cc/index.php?topic=303189.60
  
    take aguments of pointed sensor:
    all statements use integer datatypes only, no floats used:
    read sensor apply offset and scale value by * 100:
                                                                                                                                                                   */
void readSensorCurrent(void *iSensor_arg) {
    iSensor_t   * iSensor_ptr;
    iSensor_ptr = (iSensor_t*)iSensor_arg;
 
    iSensor_ptr->raw_pv = analogRead(iSensor_ptr->pin_sensor) - iSensor_ptr->offset_sp;     // subtract offset value from analog value:
    iSensor_ptr->value_pv = (int16_t)(iSensor_ptr->raw_pv * 48.828125 / (iSensor_ptr->mVAmp_sp / 10));
 
/*  if (iSensor_ptr->offset512)                                                             // if sensor is bi-directional and has offset bit set:
        iSensor_ptr->raw_pv = analogRead(iSensor_ptr->pin_sensor) & 0x1FF;                  // mask off offset amount, 511 or 0x1FF:
    else
        iSensor_ptr->raw_pv = analogRead(iSensor_ptr->pin_sensor);                          // else use full range of ADC counts, 0 - 1023:
*/
 
/*  double  adcVolts;
    adcVolts = (analogRead(iSensor_1.pin_sensor) / 1023.0) * 5000;                          // mV:
    Amps1 = ((adcVolts - iSensor_1.offset) / iSensor_1.mVAmp);
 
    adcVolts = (analogRead(iSensor_2.pin_sensor) / 1023.0) * 5000;                          // mV:
    Amps2 = ((adcVolts - iSensor_2.offset) / iSensor_2.mVAmp);
 
    adcVolts = (analogRead(iSensor_3.pin_sensor) / 1023.0) * 5000;                          // mV:
    Amps3 = ((adcVolts - iSensor_3.offset) / iSensor_2.mVAmp);
    
  the following bit of code is form the manufacture of the 90amp curent sensor
  SPECS:  http://cdn.sparkfun.com/datasheets/Sensors/Current/DC%20Voltage%20and%20Current%20Sense%20PCB%20with%20Analog%20Output.pdf
  
  int VRaw;                                                                                 //This will store our raw ADC data
  int IRaw;
  float VFinal;                                                                             //This will store the converted data
  float IFinal;

  //Measurement
  VRaw = analogRead(A0);
  IRaw = analogRead(A1);
  
  //Conversion
  VFinal = VRaw/49.44;                                                                      //45 Amp board
  //VFinal = VRaw/12.99;                                                                    //90 Amp board
  //VFinal = VRaw/12.99;                                                                    //180 Amp board  
  
  IFinal = IRaw/14.9;                                                                       //45 Amp board
  //IFinal = IRaw/7.4;                                                                      //90 Amp board
  //IFinal = IRaw/3.7;                                                                      //180 Amp board
*/
}

/*------------------------------------------------------------------------- VoltageDivider --------------------------------------------------------------------------

To measure voltages:

Voltage input range : DC0-25 V
Voltage detection range : DC0.02445 V-25 V
Voltage analog resolution : 0.00489 V
                                                                                                                                                                   */

void VoltageDivider() {
  
  float temp; 
  val11=analogRead(pin_vSensor_2); 
  temp=val11/4.092; 
  val11=(int)temp;// 
  volts_12vReg=((val11%100)/10); 
  Serial.println(volts_12vReg); 
   
} 

/*------------------------------------------------------------------------- BatterCharger --------------------------------------------------------------------------

To measure voltages and turn battery charger on when battery voltage hits 12.2 V and off when Batery voltage reaches 14.3 V                                       */

void BatteryCharger() {
  
BattChargerRlyState = digitalRead(BattChargerRly);

if ((BattChargerRlyState == false) && ((volts_1 >= ChargerStartVolts) && (volts_1 <= ChargerStopVolts))) {
  digitalWrite(BattChargerRly, true); 
} else {
  digitalWrite(BattChargerRly, false);
}

}

/*------------------------------------------------------------------------- Modbus ----------------------------------------------------------------------------------

Move data capured from Tri-Metric over Serial port to MODBUS over TCP
                                                                                                                                                                   */
void modbus() {
  
  Mb.R[0] = volts_1;                                                                                    
  Mb.R[1] = volts_filtered_1;
  Mb.R[2] = volts_2;
  Mb.R[3] = amps;
  Mb.R[4] = amps_filtered;
  Mb.R[5] = amp_hours;
  Mb.R[6] = soc;
  Mb.R[7] = watts;
  Mb.R[8] = days_since_charge;
  Mb.R[9] = days_since_equalise;
  Mb.R[10] = KitLightRlyState;
/*Mb.R[11] = RELAY BLOCK 1-2State;
  Mb.R[12] = RELAY BLOCK 1-3State;
  Mb.R[13] = BattChargerRlyState;
  Mb.R[14] = RELAY BLOCK 2-1State;
  Mb.R[15] = RELAY BLOCK 2-2State;
  Mb.R[16] = RELAY BLOCK 2-3State; 
  Mb.R[17] = RELAY BLOCK 2-4State;                                                                                       */
  Mb.R[11] = MainWaterPumpRlyState;
  Mb.R[12] = MainSolenoidRlyState;
  Mb.R[13] = TankSolenoidRlyState;
  Mb.R[14] = FillSolenoidRlyState;
  Mb.R[15] = BlackWaterPumpRlyState;
  Mb.R[16] = BlkWaterSloenoidRlyState;
  Mb.R[17] = AirConOnOffRlyState;
  Mb.R[18] = AirConThermoRlyState;
  Mb.R[19] = OpenBlkWaterSolState; 
  
  
  Mb.Run();
}

/*------------------------------------------------------------------------- writeLCD() ------------------------------------------------------------------------------
                                                                                                                                                                   */
void writeLCD() {
  
  float volts = volts_1;                                                                    // Convert unsigned int to float
  volts = volts/10;                                                                         // Remove scalling
  
  int amps1 = amps;                                                                         // Convert unsigned int to signed int
  float amps2 = amps1;                                                                      // Convert int to float
  amps2 = amps2/10;                                                                         // Remove scalling
  
  int soc1 = soc;                                                                           // Convert unsigned int to signed int
  soc1 = soc1/10;                                                                           // Remove scalling
  
  int amp_hours1 = amp_hours;                                                               // Convert unsigned int to signed int
  float amp_hours2 = amp_hours1;                                                            // Convert int to float
  amp_hours2 = amp_hours2/10;                                                               // Remove scalling
  
  int watts1 = watts;                                                                       // Convert unsigned int to int
  watts1 = watts1/10;                                                                       // Remove scalling
  
  lcd.setCursor(0,0);
  lcd.print("Tri-Metric Batt Mon");
  lcd.setCursor(0,1);
  lcd.print(volts);
  lcd.print("V's");
  lcd.setCursor(0,2);
  lcd.print(amps2);
  lcd.print("A's ");
  lcd.setCursor(11,2);
  lcd.print(watts1);
  lcd.print("W's ");
  lcd.setCursor(0,3);
  lcd.print(amp_hours2);
  lcd.print("Ahs ");
  lcd.setCursor(11,3);
  lcd.print(soc1);
  lcd.print("% ");
    
}
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/

Dashboard 1

PHP
PHP code to display mysql data.
<html>
 <head>
 <meta http-equiv="refresh" content="30">
 <script type="text/javascript" src="https://www.google.com/jsapi"></script>
 <script type="text/javascript">
 google.load("visualization", "1", {packages:["corechart"]});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'time');
 data.addColumn('number', 'Volts');
 data.addColumn('number', 'Amps');
 data.addColumn('number', 'Amp Hours');
 data.addColumn('number', 'Watts');
 data.addColumn('number', 'SOC');

 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "sensordata" table
 
 $result = mysql_query("SELECT TIMESTAMPDIFF(MINUTE, timestamp, NOW()) as time1, volts, amps, amphours, watts, soc FROM trimetric WHERE timestamp > NOW()-INTERVAL 12 HOUR ORDER BY time1"); 
 if ($result !== false) {
 $num=mysql_numrows($result);

 $i=0;

echo"";

 while ($i < $num) {

 $time=mysql_result($result,$i,"time1")/60;
 $time = round($time, 2);
 $volts=mysql_result($result,$i,"volts");
 $amps=mysql_result($result,$i,"amps");
 $amphours=mysql_result($result,$i,"amphours");
 $watts=mysql_result($result,$i,"watts");
 $soc=mysql_result($result,$i,"soc");


 echo "['";
 echo "$time";
 echo "',";
 echo "$volts";
 echo ",";
 echo "$amps";
 echo ",";
 echo "$amphours";
 echo ",";
 echo "$watts";
 echo ",";
 echo "$soc";
 echo "]";
 if ($i < ($num - 1)) 
 {
 echo ",";
 }
 $i++;


 }
 }

?> 
 ]);

var options = {
 width: 1200, height: 500,
 hAxis: {title: 'Hours Ago'},
 vAxis: {title: 'Units', maxValue: 50, minValue: -50}
 };

var chart = new google.visualization.LineChart(document.getElementById('chart_div1'));
 chart.draw(data, options);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT timestamp, amps, amphours FROM trimetric Order By timestamp desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $amps=mysql_result($result,0,"amps");
 //$amphours=mysql_result($result,0,"amphours");
 
 echo "['Amps',";
 echo "$amps";
 //echo "],";
 //echo "['AmpHrs',";
 //echo "$amphours";
 echo "]";

}

?> 
 ]);

var options2 = {
 width: 200, height: 300,
 minorTicks: 10, max: 100, min: -100
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div2'));
 chart.draw(data, options2);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT timestamp, amphours FROM trimetric Order By timestamp desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $amphours=mysql_result($result,0,"amphours");
  
 echo "['AmpHours',";
 echo "$amphours";
 echo "]";

}

?> 
 ]);

var options2 = {
 width: 200, height: 300,
 minorTicks: 15, max: 150, min: -150
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div7'));
 chart.draw(data, options2);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT timestamp, watts FROM trimetric Order By timestamp desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $watts=mysql_result($result,0,"watts");
  
 echo "['Watts',";
 echo "$watts";
 echo "]";

}

?> 
 ]);

var options2 = {
 width: 200, height: 300,
 minorTicks: 20, max: 250, min: -250
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div6'));
 chart.draw(data, options2);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT timestamp, volts FROM trimetric Order By timestamp desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);


$volts=mysql_result($result,0,"volts");

echo "['Volts',";
 echo "$volts";
 echo "]";

}

?> 
 ]);

var options3 = {
 width: 200, height: 300,
 minorTicks: 10, max: 15, min: 11
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div3'));
 chart.draw(data, options3);
 }
 </script>


 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, dht22temp FROM dht22 Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);


$dht22temp=mysql_result($result,0,"dht22temp");

echo "['Temp',";
 echo "$dht22temp";
 echo "]";

}

?> 
 ]);

var options3 = {
 width: 200, height: 300,
 minorTicks: 11, max: 40, min: -5
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div4'));
 chart.draw(data, options3);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, dht22humidity FROM dht22 Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);


$dht22humidity=mysql_result($result,0,"dht22humidity");

echo "['Humidity',";
 echo "$dht22humidity";
 echo "]";

}

?> 
 ]);

var options3 = {
 width: 200, height: 300,
 minorTicks: 17, max: 100, min: 30
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div5'));
 chart.draw(data, options3);
 }
 </script>


 </head>
 <body>
 <div align="center">
 <H1 align="center">INS Home Automation Project<H1>
 <H2> Tri-Metric Battery Monitor Data</H2>
 <div align="center">
 <table width="900" border="1">
 <tr>
 <td><div align="center">
 <table width="1200" border="0">
 <tr>
 <td width="141">&nbsp;</td>
 <td width="10">&nbsp;</td>
 <td width="432"><div id="chart_div1"></div></td>
 <td width="141">&nbsp;</td>
 <td width="144">&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>
 <div align="center">
 <table width="1200" border="0">
 <tr>
 <td width="595"><div id="chart_div2"></div></td>
 <td width="195"><div id="chart_div7"></div></td>
 <td width="195"><div id="chart_div6"></div></td>
 <td width="195"><div id="chart_div3"></div></td>
 <td width="195"><div id="chart_div4"></div></td>
 <td width="195"><div id="chart_div5"></div></td>
 </tr>
 </table>
 </div></td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td><div align="center">
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');
// Retrieve all the data from the "trimetric" table
 $result = mysql_query("SELECT timestamp, volts, amps, amphours, watts, soc, dsc, dse FROM trimetric Order By timestamp desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $event=mysql_result($result,0,"timestamp");
 $volts=mysql_result($result,0,"volts");
 $amps=mysql_result($result,0,"amps");
 $amphours=mysql_result($result,0,"amphours");
 $watts=mysql_result($result,0,"watts");
 $soc=mysql_result($result,0,"soc");
 $dsc=mysql_result($result,0,"dsc");
 $dse=mysql_result($result,0,"dse");
  
 echo "Volts: ";
 echo $volts;
 echo "V ";
 echo "  Amps ";
 echo $amps;
 echo "A ";
 echo "  Watts: ";
 echo $watts;
 echo "W ";
 echo "  Amp Hrs: ";
 echo $amphours;
 echo "Ahrs ";
 echo "  State of Charge: ";
 echo $soc;
 echo "% ";
 echo "  Days Since Charge: ";
 echo $dsc;
 echo "  Days Since Equalise: ";
 echo $dse;
 
 
}

?>
 &nbsp</p>
 <a href="http://www.inshome.net.au/index.php">Home</a>


 </div></td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 </table>
 </div></td>
 </tr>
 </table>
 </div>
 </body>
 </html>

Dashboard 2

PHP
PHP code to display MySQL data.
<html>
 <head>
 <meta http-equiv="refresh" content="30">
 <script type="text/javascript" src="https://www.google.com/jsapi"></script>
 <script type="text/javascript">
 google.load("visualization", "1", {packages:["corechart"]});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'time');
 data.addColumn('number', 'Volts');
 data.addColumn('number', 'Charge Amps');
 data.addColumn('number', 'Charge Watts');
 data.addColumn('number', 'Solar Volts');
 data.addColumn('number', 'Solar Amps');
 data.addColumn('number', 'Battery Temp');
 data.addColumn('number', 'Heatsink Temp');

 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "sensordata" table
 
 $result = mysql_query("SELECT TIMESTAMPDIFF(MINUTE, time, NOW()) as time1, batvolts, batcurrent, batwatts, arrayvolts, arraycurrent, battemp, heatsinktemp FROM tristar WHERE time > NOW()-INTERVAL 12 HOUR ORDER BY time1"); 
 if ($result !== false) {
 $num=mysql_numrows($result);

 $i=0;

echo"";

 while ($i < $num) {

 $time=mysql_result($result,$i,"time1")/60;
 $time = round($time, 2);
 $batvolts=mysql_result($result,$i,"batvolts");
 $batcurrent=mysql_result($result,$i,"batcurrent");
 $batwatts=mysql_result($result,$i,"batwatts");
 $arrayvolts=mysql_result($result,$i,"arrayvolts");
 $arraycurrent=mysql_result($result,$i,"arraycurrent");
 $battemp=mysql_result($result,$i,"battemp");
 $heatsinktemp=mysql_result($result,$i,"heatsinktemp");


 echo "['";
 echo "$time";
 echo "',";
 echo "$batvolts";
 echo ",";
 echo "$batcurrent";
 echo ",";
 echo "$batwatts";
 echo ",";
 echo "$arrayvolts";
 echo ",";
 echo "$arraycurrent";
 echo ",";
 echo "$battemp";
 echo ",";
 echo "$heatsinktemp";
 echo "]";
 if ($i < ($num - 1)) 
 {
 echo ",";
 }
 $i++;


 }
 }

?> 
 ]);

var options = {
 width: 1200, height: 500,
 hAxis: {title: 'Hours Ago'},
 vAxis: {title: 'Units', maxValue: 60, minValue: 0}
 };

var chart = new google.visualization.LineChart(document.getElementById('chart_div1'));
 chart.draw(data, options);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, batvolts FROM tristar Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $batvolts=mysql_result($result,0,"batvolts");
  
 echo "['Volts',";
 echo "$batvolts";
 echo "]";

}

?> 
 ]);

var options2 = {
 width: 200, height: 300,
 minorTicks: 9, max: 15, min: 11
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div2'));
 chart.draw(data, options2);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, batcurrent FROM tristar Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $batcurrent=mysql_result($result,0,"batcurrent");
  
 echo "['ChrgAmps',";
 echo "$batcurrent";
 echo "]";

}

?> 
 ]);

var options2 = {
 width: 200, height: 300,
 minorTicks: 15, max: 60, min: 0
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div7'));
 chart.draw(data, options2);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, batwatts FROM tristar Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $batwatts=mysql_result($result,0,"batwatts");
  
 echo "['ChrgWatts',";
 echo "$batwatts";
 echo "]";

}

?> 
 ]);

var options2 = {
 width: 200, height: 300,
 minorTicks: 19, max: 100, min: 0
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div6'));
 chart.draw(data, options2);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, arrayvolts FROM tristar Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);


$arrayvolts=mysql_result($result,0,"arrayvolts");

echo "['ArrayVolts',";
 echo "$arrayvolts";
 echo "]";

}

?> 
 ]);

var options3 = {
 width: 200, height: 300,
 minorTicks: 29, max: 120, min: 0
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div3'));
 chart.draw(data, options3);
 }
 </script>


 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, arraycurrent FROM tristar Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);


$arraycurrent=mysql_result($result,0,"arraycurrent");

echo "['ArrayAmps',";
 echo "$arraycurrent";
 echo "]";

}

?> 
 ]);

var options3 = {
 width: 200, height: 300,
 minorTicks: 9, max: 40, min: 0
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div4'));
 chart.draw(data, options3);
 }
 </script>

 <script type='text/javascript' src='https://www.google.com/jsapi'></script>
 <script type='text/javascript'>
 google.load('visualization', '1', {packages:['gauge']});
 google.setOnLoadCallback(drawChart);
 function drawChart() {
 var data = new google.visualization.DataTable();
 data.addColumn('string', 'Label');
 data.addColumn('number', 'Value');
 data.addRows([
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');

// Retrieve all the data from the "example" table
 $result = mysql_query("SELECT time, heatsinktemp FROM tristar Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);


$heatsinktemp=mysql_result($result,0,"heatsinktemp");

echo "['CtrlrTmp',";
 echo "$heatsinktemp";
 echo "]";

}

?> 
 ]);

var options3 = {
 width: 200, height: 300,
 minorTicks: 11, max: 50, min: 0
 };

var chart = new google.visualization.Gauge(document.getElementById('chart_div5'));
 chart.draw(data, options3);
 }
 </script>


 </head>
 <body>
 <div align="center">
 <H1 align="center">INS Home Automation Project<H1>
 <H2> Tri-Star Solar Charge Controller Data</H2>
 <div align="center">
 <table width="900" border="1">
 <tr>
 <td><div align="center">
 <table width="1200" border="0">
 <tr>
 <td width="141">&nbsp;</td>
 <td width="10">&nbsp;</td>
 <td width="432"><div id="chart_div1"></div></td>
 <td width="141">&nbsp;</td>
 <td width="144">&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>
 <div align="center">
 <table width="1200" border="0">
 <tr>
 <td width="595"><div id="chart_div2"></div></td>
 <td width="195"><div id="chart_div7"></div></td>
 <td width="195"><div id="chart_div6"></div></td>
 <td width="195"><div id="chart_div3"></div></td>
 <td width="195"><div id="chart_div4"></div></td>
 <td width="195"><div id="chart_div5"></div></td>
 </tr>
 </table>
 </div></td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 <tr>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 <td><div align="center">
 <?php 

// Start MySQL Connection
include('./includes/mysql_connect.php');
// Retrieve all the data from the "trimetric" table
 $result = mysql_query("SELECT time, batvolts, batcurrent, batwatts, arrayvolts, arraycurrent, battemp, heatsinktemp, chargestate FROM tristar Order By time desc limit 1");
 if ($result !== false) {
 $num=mysql_numrows($result);

 $event=mysql_result($result,0,"time");
 $batvolts=mysql_result($result,0,"batvolts");
 $batcurrent=mysql_result($result,0,"batcurrent");
 $batwatts=mysql_result($result,0,"batwatts");
 $arrayvolts=mysql_result($result,0,"arrayvolts");
 $arraycurrent=mysql_result($result,0,"arraycurrent");
 $battemp=mysql_result($result,0,"battemp");
 $heatsinktemp=mysql_result($result,0,"heatsinktemp");
 $chargestate=mysql_result($result,0,"chargestate");
  
 echo "Battery Volts: ";
 echo $batvolts;
 echo "V ";
 echo "  Charge Current ";
 echo $batcurrent;
 echo "A ";
 echo "  Charge Watts: ";
 echo $batwatts;
 echo "W ";
 echo "  Array Volts: ";
 echo $arrayvolts;
 echo "V ";
 echo "  Array Current: ";
 echo $arraycurrent;
 echo "A ";
 echo "  Heatsink Temp: ";
 echo $heatsinktemp;
 

switch ($chargestate) {
	case 0:
		$chargestatelabel = "START";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 1:
		$chargestatelabel = "NIGHT_CHECK";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 2:
		$chargestatelabel = "DISCONNECT";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 3:
		$chargestatelabel = "NIGHT";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 4:
		$chargestatelabel = "FAULT";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 5:
		$chargestatelabel = "MPPT";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 6:
		$chargestatelabel = "ABSORPTION";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 7:
		$chargestatelabel = "FLOAT";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 8:
		$chargestatelabel = "EQUALIZE";
		echo " Charge State: "; echo $chargestatelabel;
		break;
	case 9:
		$chargestatelabel = "SLAVE";
		echo " Charge State: "; echo $chargestatelabel;
		break;
}
 
}

?>
 &nbsp</p>
 <a href="http://www.inshome.net.au/index.php">Home</a>


 </div></td>
 <td>&nbsp;</td>
 <td>&nbsp;</td>
 </tr>
 </table>
 </div></td>
 </tr>
 </table>
 </div>
 </body>
 </html>

Poll Tri-Metric Modbus over TCP

PHP
Polls Modbus on MEGA_TRI-METRIC over TCP and stores data in a MySQL Database
<?php
if (php_sapi_name() !='cli') exit;
//header('Refresh: 5');

echo date('d-m-Y'). "</br>";
echo date('H:i:s'). "</br>";

//echo "<h2>INS Home Automation Project Modbus TCP Test</h2>";
//echo "Polls Modbus on MEGA_TRI-METRIC over TCP and stores data in a MySQL Database.</br></br>";

require_once dirname(__FILE__) . '/../php/includes/mysql_connect.php';

require_once dirname(__FILE__) . '/../php/phpmodbus/ModbusMaster.php';
 
// Create Modbus object
$modbus = new ModbusMaster("192.168.88.178", "TCP");
 
try {
    // FC 3
    $recData = $modbus->readMultipleRegisters(0, 0, 10);
}
catch (Exception $e) {
    // Print error information if any
    echo $modbus;
    echo $e;
    exit;
}
 
// Print status information
//echo "</br>Modbus Status:</br>" . $modbus;
  
// Conversion
// Chunk the data array to set of 4 bytes
$values = array_chunk($recData, 2);
 
// Get signed integer from INT interpretation
$scaledData = array();
$count = 1;
//echo "</br>Tri-Metric Battery Monitor Data</br></br>";

foreach($values as $bytes){
        //echo PhpType::bytes2signedInt($bytes)/10 . "</br>";
        $scaledData[$count] = PhpType::bytes2signedInt($bytes)/10;
	$count++;
}

$volts = $scaledData[1]; //echo "Volts: "; echo $volts; echo "V's</br>";
$voltsfiltered = $scaledData[2]; //echo "Volts Filtered: "; echo $voltsfiltered; echo "V's</br>";
$volts2 = $scaledData[3];  //echo "Volts 2: "; echo $volts2; echo "V's</br>";
$amps = $scaledData[4]; //echo "Amps: "; echo $amps; echo "A's</br>";
$ampsfiltered = $scaledData[5]; //echo "Amps Filtered: "; echo $ampsfiltered; echo "A's</br>";
$amphours = $scaledData[6]; //echo "Amp Hours: "; echo $amphours; echo "Ahrs</br>";
$soc = $scaledData[7]; //echo "State of Charge: "; echo $soc; echo "%</br>";
$watts = $scaledData[8]; //echo "Watts: "; echo $watts; echo "W's</br>";
$dsc = $scaledData[9];  //echo "Days Since Charged: "; echo $dsc; echo " Day's</br>";
$dse = $scaledData[10];  //echo "Days Since Equalise: "; echo $dse; echo " Day's</br>";


mysql_query("INSERT INTO trimetric
	(volts, voltsfiltered, volts2, amps, ampsfiltered, amphours, soc, watts, dsc,dse)
	VALUES
	($volts, $voltsfiltered, $volts2, $amps, $ampsfiltered, $amphours, $soc, $watts, $dsc,$dse)")
or die(mysql_error());

mysql_close($dbhandle);

	
?>

Poll Mega-Sensors Modus

PHP
This file gets the modbus data from the Arduino MEGA-SENSORS board and stores
it into a database.
<?php
/* This file gets the modbus data from the Arduino MEGA-SENSORS board and stoes 
 it into a database. */

if (php_sapi_name() !='cli') exit;

//header('Refresh: 5');

//echo "<h1>Arduino MEGA-SENSORS Modbus to MySQL with PHP</h1>";

 require_once dirname(__FILE__) . '/../php/includes/mysql_connect.php';
 
 require_once dirname(__FILE__).'/../php/phpmodbus/ModbusMaster.php';   // Include phpmodbus
 
$modbus = new ModbusMaster("192.168.88.177", "TCP");					// Create Modbus object

try {
	$recData = $modbus->readMultipleRegisters(0,2,22);					// Modbus command
}
catch (Exception $e) {
	echo $modbus;														//Print error information if any
	echo$e;
	exit;
}


//echo "</br>Modbus Status:</br>" . $modbus;								// Print status information
  
// Conversion
$values = array_chunk($recData, 2);										// Chunk the data array to set of 2 Bytes
$rawData = array();													
$count = 1;
//echo "</br>Arduino MEGA_SENSORS RAW Data</br></br>";

foreach($values as $bytes){
        //echo PhpType::bytes2signedInt($bytes) . "</br>";			// Get signed integer from INT interpretation
        $rawData[$count] = PhpType::bytes2signedInt($bytes);
	$count++;
}
//echo "</br>Arduino MEGA_SENSORS Scaled Data</br></br>";

$dht22temp = $rawData[1]/100; //echo "DHT22 Average Temperature: "; echo "$dht22temp"; echo "C</br>";
$dht22humidity = $rawData[2]/100; //echo "DHT22 Average Humidity: "; echo "$dht22humidity"; echo "%</br>";
$bmppressure = $rawData[3]/10; //echo "BMP180 Pressure: "; echo "$bmppressure"; echo "hPa</br>";
$bmpTemp = $rawData[4]/100; //echo "BMP180 Temperature: "; echo "$bmpTemp"; echo "C</br>";
$bmpaltitude = $rawData[5]/10; //echo "Calculated Altitude: "; echo "$bmpaltitude"; echo "m</br></br>";

//echo "State Variables: 0 = off, 1 = on</br></br>";

$BedMainLightRlyState = $rawData[6]; //echo "Main Bedroom Light: "; echo "$BedMainLightRlyState"; echo "</br>";
$BedReadLight1RlyState = $rawData[7]; //echo "Bedroom Reaing Light 1: "; echo "$BedReadLight1RlyState"; echo "</br>";
$BedReadLight2RlyState = $rawData[8]; //echo "Bedroom Reading Light 2: "; echo "$BedReadLight2RlyState"; echo "</br>";
$Bed2LightRlyState = $rawData[9]; //echo "Bedroom 2 Light: "; echo "$Bed2LightRlyState"; echo "</br>";
$ExternalLightRlyState = $rawData[10]; //echo "External Light: "; echo "$ExternalLightRlyState"; echo "</br>";
$BathLightRlyState = $rawData[11]; //echo "Bathroom Light: "; echo "$BathLightRlyState"; echo "</br>";
$OfficeLightRlyState = $rawData[12]; //echo "Office Light: "; echo "$OfficeLightRlyState"; echo "</br>";
$MainLightRlyState = $rawData[13]; //echo "Main Living Area Light: "; echo "$MainLightRlyState"; echo "</br>";
$NightLightState = $rawData[14]; //echo "NightLight Light: "; echo "$NightLightState"; echo "</br>";
$NightLight2State = $rawData[15]; //echo "Nightlight 2 Light: "; echo "$NightLight2State"; echo "</br>";
$BathFanRlyState = $rawData[16]; //echo "Bathroom Exhaust Fan: "; echo "$BathFanRlyState"; echo "</br>";
$KitFanRlyState = $rawData[17]; //echo "Kitchen Exhuast Fan: "; echo "$KitFanRlyState"; echo "</br>";
$BathGas1Detected = $rawData[18]; //echo "Bathroom GAS 1 Sensor: "; echo "$BathGas1Detected"; echo "</br>";
$BathGas2Detected = $rawData[19]; //echo "Bathroom GAS 2 Sensor: "; echo "$BathGas2Detected"; echo "</br>";
$KitGas1Detected = $rawData[20]; //echo "Kitchen GAS 1 Sensor: "; echo "$KitGas1Detected"; echo "</br>";
$KitGas2Detected = $rawData[21]; //echo "Kitchen GAS 2 Sensor: "; echo "$KitGas2Detected"; echo "</br>";
$KitGas3Detected = $rawData[22]; //echo "Kitchen GAS 3 Sensor: "; echo "$KitGas3Detected"; echo "</br>";



mysql_query("INSERT INTO dht22
	(dht22temp, dht22humidity)
	VALUES
	($dht22temp, $dht22humidity)")
or die(mysql_error());

mysql_query("INSERT INTO bmp180
	(bmppressure, bmptemp, bmpaltitude)
	VALUES
	($bmppressure, $bmpTemp, $bmpaltitude)")
or die(mysql_error());


$result = mysql_query("SELECT BedMainLightRlyState, BedReadLight1RlyState, BedReadLight2RlyState, Bed2LightRlyState, ExternalLightRlyState, 
							  BathLightRlyState, OfficeLightRlyState, MainLightRlyState, NightLightState, NightLight2State, 
							  BathFanRlyState, KitFanRlyState, BathGas1Detected, BathGas2Detected, KitGas1Detected, 
							  KitGas2Detected, KitGas3Detected, time FROM MegaSensorsStates order by time desc limit 1")
or die(mysql_error());

if ($result !== false) {
 $num=mysql_numrows($result);

 $BedMainLightRlyState1=mysql_result($result,0,"BedMainLightRlyState"); 
 $BedReadLight1RlyState1=mysql_result($result,0,"BedReadLight1RlyState");
 $BedReadLight2RlyState1=mysql_result($result,0,"BedReadLight2RlyState");
 $Bed2LightRlyState1=mysql_result($result,0,"Bed2LightRlyState");
 $ExternalLightRlyState1=mysql_result($result,0,"ExternalLightRlyState");
 $BathLightRlyState1=mysql_result($result,0,"BathLightRlyState");
 $OfficeLightRlyState1=mysql_result($result,0,"OfficeLightRlyState");
 $MainLightRlyState1=mysql_result($result,0,"MainLightRlyState");
 $NightLightState1=mysql_result($result,0,"NightLightState");
 $NightLight2State1=mysql_result($result,0,"NightLight2State");
 $BathFanRlyState1=mysql_result($result,0,"BathFanRlyState");
 $KitFanRlyState1=mysql_result($result,0,"KitFanRlyState");
 $BathGas1Detected1=mysql_result($result,0,"BathGas1Detected");
 $BathGas2Detected1=mysql_result($result,0,"BathGas2Detected");
 $KitGas1Detected1=mysql_result($result,0,"KitGas1Detected");
 $KitGas2Detected1=mysql_result($result,0,"KitGas2Detected");
 $KitGas3Detected1=mysql_result($result,0,"KitGas3Detected");
 
};

if ($BedMainLightRlyState != $BedMainLightRlyState1){
 //echo "</br>Read BedMainLightRlyState: "; echo "$BedMainLightRlyState"; echo "</br>Previous BedMainLightRlyState: "; echo "$BedMainLightRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (BedMainLightRlyState) VALUES ($BedMainLightRlyState)")
 or dir(mysql_error());
};

if ($BedReadLight1RlyState != $BedReadLight1RlyState1){
 //echo "</br>Read BedReadLight1RlyState: "; echo "$BedReadLight1RlyState"; echo "</br>Previous BedReadLight1RlyState: "; echo "$BedReadLight1RlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (BedReadLight1RlyState) VALUES ($BedReadLight1RlyState)")
 or dir(mysql_error());
};

if ($BedReadLight2RlyState != $BedReadLight2RlyState1){
 //echo "</br>Read BedReadLight2RlyState: "; echo "$BedReadLight2RlyState"; echo "</br>Previous BedReadLight2RlyState: "; echo "$BedReadLight2RlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (BedReadLight2RlyState) VALUES ($BedReadLight2RlyState)")
 or dir(mysql_error());
};

if ($Bed2LightRlyState != $Bed2LightRlyState1){
 //echo "</br>Read Bed2LightRlyState: "; echo "$Bed2LightRlyState"; echo "</br>Previous Bed2LightRlyState: "; echo "$Bed2LightRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (Bed2LightRlyState) VALUES ($Bed2LightRlyState)")
 or dir(mysql_error());
};

if ($ExternalLightRlyState != $ExternalLightRlyState1){
 //echo "</br>Read ExternalLightRlyState: "; echo "$ExternalLightRlyState"; echo "</br>Previous ExternalLightRlyState: "; echo "$ExternalLightRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (ExternalLightRlyState) VALUES ($ExternalLightRlyState)")
 or dir(mysql_error());
};

if ($BathLightRlyState != $BathLightRlyState1){
 //echo "</br>Read BathLightRlyState: "; echo "$BathLightRlyState"; echo "</br>Previous BathLightRlyState: "; echo "$BathLightRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (BathLightRlyState) VALUES ($BathLightRlyState)")
 or dir(mysql_error());
};

if ($OfficeLightRlyState != $OfficeLightRlyState1){
 //echo "</br>Read OfficeLightRlyState: "; echo "$OfficeLightRlyState"; echo "</br>Previous OfficeLightRlyState: "; echo "$OfficeLightRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (OfficeLightRlyState) VALUES ($OfficeLightRlyState)")
 or dir(mysql_error());
};

if ($MainLightRlyState != $MainLightRlyState1){
 //echo "</br>Read MainLightRlyState: "; echo "$MainLightRlyState"; echo "</br>Previous MainLightRlyState: "; echo "$MainLightRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (MainLightRlyState) VALUES ($MainLightRlyState)")
 or dir(mysql_error());
};

if ($NightLightState != $NightLightState1){
 //echo "</br>Read NightLightState: "; echo "$NightLightState"; echo "</br>Previous NightLightState: "; echo "$NightLightState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (NightLightState) VALUES ($NightLightState)")
 or dir(mysql_error());
};

if ($NightLight2State != $NightLight2State1){
 //echo "</br>Read NightLight2State: "; echo "$NightLight2State"; echo "</br>Previous NightLight2State: "; echo "$NightLight2State1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (NightLight2State) VALUES ($NightLight2State)")
 or dir(mysql_error());
};

if ($BathFanRlyState != $BathFanRlyState1){
 //echo "</br>Read BathFanRlyState: "; echo "$BathFanRlyState"; echo "</br>Previous BathFanRlyState: "; echo "$BathFanRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (BathFanRlyState) VALUES ($BathFanRlyState)")
 or dir(mysql_error());
};

if ($KitFanRlyState != $KitFanRlyState1){
 //echo "</br>Read KitFanRlyState: "; echo "$KitFanRlyState"; echo "</br>Previous KitFanRlyState: "; echo "$KitFanRlyState1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (KitFanRlyState) VALUES ($KitFanRlyState)")
 or dir(mysql_error());
};

if ($BathGas1Detected != $BathGas1Detected1){
 //echo "</br>Read BathGas1Detected: "; echo "$BathGas1Detected"; echo "</br>Previous BathGas1Detected: "; echo "$BathGas1Detected1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (BathGas1Detected) VALUES ($BathGas1Detected)")
 or dir(mysql_error());
};

if ($BathGas2Detected != $BathGas2Detected1){
 //echo "</br>Read BathGas2Detected: "; echo "$BathGas2Detected"; echo "</br>Previous BathGas2Detected: "; echo "$BathGas2Detected1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (BathGas2Detected) VALUES ($BathGas2Detected)")
 or dir(mysql_error());
};

if ($KitGas1Detected != $KitGas1Detected1){
 //echo "</br>Read KitGas1Detected: "; echo "$KitGas1Detected"; echo "</br>Previous KitGas1Detected: "; echo "$KitGas1Detected1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (KitGas1Detected) VALUES ($KitGas1Detected)")
 or dir(mysql_error());
};

if ($KitGas2Detected != $KitGas2Detected1){
 //echo "</br>Read KitGas2Detected: "; echo "$KitGas2Detected"; echo "</br>Previous KitGas2Detected: "; echo "$KitGas2Detected1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (KitGas2Detected) VALUES ($KitGas2Detected)")
 or dir(mysql_error());
};

if ($KitGas3Detected != $KitGas3Detected1){
 //echo "</br>Read KitGas3Detected: "; echo "$KitGas3Detected"; echo "</br>Previous KitGas3Detected: "; echo "$KitGas3Detected1";
 //echo "</br>State has changed, saving new state to database.";
 mysql_query("INSERT INTO MegaSensorsStates (KitGas3Detected) VALUES ($KitGas3Detected)")
 or dir(mysql_error());
};

mysql_close($dbhandle);



?>

Credits

John Wood

John Wood

2 projects • 11 followers
Thanks to Paul Alting van Geusau.

Comments