Tuesday, December 31, 2013

The Start.......

So I have my goal, now the means to get there, the fun part.......

Since I am heating with wood, fuel isnt the problem. The Problem is control and storage. I have already done the calculations for the storage, so really the control is the final puzzle piece

As I discussed earlier, the arduino MCU (micro-control unit) is the primary building block here. As I started with versions 1 and 2, it became necessary to make communication the underlying priority, but first the nuts and bolts.....

The system is pretty basic when you look at it. We have a wood furnace, a biomass heat exchanger, pumps and valves and a storage tank. Water is pumped from the tank, through the heat exchanger and back to the tank. I decided to have everything based on the temperature of the exchanger. After all, if you pump water through a cold exchanger, then we will be taking heat out of the storage tank and heating up a cold exchanger.....not good. 

The system is designed using two loops. The LOOPA is the primary and the LOOPB the backup, and the augmenter, more on that later. So Lets look at just the software to run just LOOPA for now. 

Here is the entire sketch: Its for a Arduino UnoR3, running with an ethernet connection. There is some MQTT stuff, Ill point out and talk about later, right now we will look at what its basically doing:


       #include <SPI.h>
        #include <LiquidCrystal_I2C.h>
        #include <Wire.h>
        #include <Ethernet.h>
        #include <PubSubClient.h>
          
          
        LiquidCrystal_I2C lcd(0x27, 20,4);
         
        byte mac[]    = {  0xDE, 0xAD, 0x01, 0xA1, 0xBE, 0xEF };
        byte server[] = { 192, 168, 30, 9 };
        byte ip[]     = { 192, 168, 30, 20 };
        byte subnet[] = {255, 255, 255, 0};
        byte gateway[] = { 192, 168, 30, 1};
        
        void callback(char* topic, byte* payload, unsigned int length) {
          // handle message arrived
        }
        EthernetClient ethClient;
        PubSubClient client(server, 1883, callback, ethClient);
         
          
          int EXCH = A0; 

          int DigiPinFLOA = 7;  //pin that reads FlowSW LOOP A

          int VALVE2 = 2;
          int VALVE1 = 8;
          int PUMPA = 9;
          int keepalive = 4;
          int DigiPinFLOAState = 0;
          int keepaliveState = 0;
   
    void setup()
            
            {
             Ethernet.begin(mac, ip,  subnet, gateway);
               if (client.connect("arduinoClientLA")) {
               client.publish("/mainTopic/Announce/LOOPA","ONLINE"); }
             
             
             
               pinMode(keepalive, OUTPUT);         
               pinMode(PUMPA, OUTPUT);
               pinMode(VALVE1, OUTPUT);
               pinMode(VALVE2, OUTPUT);
               pinMode(DigiPinFLOA, INPUT); 
               lcd.backlight();
               
               
               Serial.begin(9600); //start the serial connection
              //Title on first line of LCD
              lcd.backlight();
              lcd.begin();
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print("** LOOP-A STATUS **");
              
              digitalWrite(PUMPA,HIGH);   //// On Boot up shut everything off....
              digitalWrite(VALVE1, HIGH);
              digitalWrite(VALVE2,HIGH);
             
          }
          
          void loop()
          {
                      
                digitalWrite(keepalive, HIGH); // <--- keepalive Hardware signal to monitor)
               
             int reading = analogRead(EXCH); 
              float voltage = reading * 5.0; 
                   voltage /= 1024.0;
              float temperatureC = (voltage - 0.5) * 100;  
              float EXCH = (temperatureC * 9.0 / 5.0) + 32.0;
                char charMsgA[10];
                memset(charMsgA,'\0',10);
                dtostrf(EXCH, 4, 2, charMsgA);
                client.publish("/ENGTemps/EXCH/EXCH",charMsgA); // <-update EXCH temp to broker

            
            if (EXCH <150.00 ) { 
           
                 digitalWrite(PUMPA, HIGH);  //RelayBrd requires a HIGH for OFF
                   delay(2000);  //shut pump off wait 2 secs
                 digitalWrite(VALVE1, HIGH);
                 digitalWrite(VALVE2, HIGH);
                    delay(1000);  

                       lcd.setCursor(0,1);
                       lcd.print("   ** SHUTDOWN **  ");               
                      lcd.setCursor(0,3);
                       lcd.print("EXCH:        F");
                       lcd.setCursor(6,3);
                       lcd.print(EXCH);   
                     delay(750);
                   client.publish("/ENG/Status/LOOPA","SHUTDOWN"); // <--- Webpage update 
                   delay(1000);
                   client.publish("/LOOPA/Messages/","12"); // <-- Codes to Loop B
                    
                }//<<--- end <150 Loop
           
            
          
             if (EXCH >150.00 && EXCH < 200) {

                 digitalWrite(VALVE1,LOW); //LOW for ON, Open Valves, start pump
                 digitalWrite(VALVE2, LOW);
                     delay(3000);     
                   digitalWrite(PUMPA, LOW); 
                     delay(3000);
                  int (DigiPinFLOAState) = digitalRead(DigiPinFLOA); 
                    
                    if (DigiPinFLOAState == 0)
                      { 

                       lcd.setCursor(0,1);
                       lcd.print("   ++  FAILURE ++   ");               
                       lcd.setCursor(0,3);
                       lcd.print("EXCH:        F");
                       lcd.setCursor(6,3);
                       lcd.print(EXCH);
                      delay(750);
                    client.publish("/ENG/Status/LOOPA","FAILED"); // <--- Webpage update
                    delay(1000);
                    client.publish("/LOOPA/Messages/","10"); // <-- Codes to Loop B
                     
                 
                     }
                       
                    else  
                     {

                       lcd.setCursor(0,1);
                       lcd.print("    -- ONLINE --    ");               
                       lcd.setCursor(0,3);
                       lcd.print("EXCH:        F");
                       lcd.setCursor(6,3);
                       lcd.print(EXCH); 
                    delay(750);
                   client.publish("/ENG/Status/LOOPA","ONLINE"); // <--- Webpage update
                   delay(1000);
                   client.publish("/LOOPA/Messages/","11"); // <-- Codes to Loop B
                    delay(1000);   
                     }  
                        
                } //<<-- 150 endunderlaying
         
         
                if (EXCH > 200)
                 
                   {
                  
                   lcd.setCursor(0,1);
                       lcd.print("    -- ONLINE --    ");               
                       lcd.setCursor(0,3);
                       lcd.print("EXCH:        F");
                       lcd.setCursor(6,3);
                       lcd.print(EXCH);    
                  client.publish("/ENG/Status/LOOPA","ONLINE");
                  delay(500);   
                  client.publish("/LOOPA/Messages/" , "15");// <-- Codes to Loop B
                  delay(1500);
                 }  
               
         
          //  client.loop(); // listen to subscriptions for important messages
             
          } //<<-- void loop end
   



So lets look at the first part............

   int EXCH = A0; 

          int DigiPinFLOA = 7;  //pin that reads FlowSW LOOP A

          int VALVE2 = 2;
          int VALVE1 = 8;
          int PUMPA = 9;
          int keepalive = 4;
          int DigiPinFLOAState = 0;
          int keepaliveState = 0;

So the first part of the sketch is the meat of the sketch. For now Im gona ignore the MQTT stuff, but if you can read the sketch and understand it then youll see what Im doing.

This part sets up out pump for LOOPA, and the valves. Each Valve is on either side of the pump. If the pump fails, or the loop shutdown, the pump can be removed because the valves isolate the pump from the loop when shut. 

DigiPinFLOA is the digital signal that is coming from the FLOW Switch. A Flow Switch is just after the isolation valve. When the valves are open and the pump running, the FLOW Switch will gives us a digital +5Vdc, or a HIGH signal indicating water is in fact flowing in the loop. The Loop also has its own Exchange temperature sensor, which is connected to Analog A0. This is a TMP-36 but you can subsitiute what you like, youll just have to change the way the sketch interprets the voltage or resistance its sending back. In the case of a Maxim DS18B20, or similar, youll have to read the bytes coming back and the unique id for the sensor. All can be done, I chose the TMP-36, its easy to use, inexpensive, and does the job. This sensor is located in the biomass exchanger, and Ill show more of that later.

The keepaliveState, is a hardware heartbeat between this MCU and the Monitor. The Monitor is another MCU thats watching the operation of the system, for now its just telling the Monitor, Im "ALIVE"


The next section sets up all the pins for the arduino:
  

 void setup()
            
            {
             Ethernet.begin(mac, ip,  subnet, gateway);
               if (client.connect("arduinoClientLA")) {
               client.publish("/mainTopic/Announce/LOOPA","ONLINE"); }
             
             
             
               pinMode(keepalive, OUTPUT);         
               pinMode(PUMPA, OUTPUT);
               pinMode(VALVE1, OUTPUT);
               pinMode(VALVE2, OUTPUT);
               pinMode(DigiPinFLOA, INPUT); 
               lcd.backlight();
               
               
               Serial.begin(9600); //start the serial connection
              //Title on first line of LCD
              lcd.backlight();
              lcd.begin();
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print("** LOOP-A STATUS **");
              
              digitalWrite(PUMPA,HIGH);   //// On Boot up shut everything off....
              digitalWrite(VALVE1, HIGH);
              digitalWrite(VALVE2,HIGH);
             

The first part of the SETUP we will address later, thats the network stuff and the MQTT login. The next part is the pinModes, these setup the pins on the arduino and tell it what signals to read or send out signals on. You can also see there is a LCD attached, this sets up the LCD screen so you can visually see what is going on. Finally before the sketch goes into operation, we send the pump and valves a HIGH signal. The relay board running the pumps and valves, require a HIGH to turn them off. On boot, I selected everything to be off, as a starting point.

In part 2 of this start up, Ill explain the operation of the LOOP......

No comments:

Post a Comment