TempCTRL v1 firmware

From Open Source Ecology - Germany
Jump to navigation Jump to search

Hier die aktuelle Firmware-Version für TempCTRL V.1, namens "heizkreisrelais7". (Stand 30.01.2016)

Sie benötigt noch eine externe Library namens "UIPEthernet" und erlaubt die Verwendung von ENC28J60 Ethernet-Modulen, welche äusserst preisgünstig zu haben sind, im Unterschied zum klassischen W5100-Ethernet-Shield für Arduino. Früher konnte der ENC28J60 nur mit einer externen Library namens "EtherCard" betrieben werden, aber die Funktionsaufrufe der Ethercard-Library sind nicht kompatibel zur Standard-Ethernet-Library der Arduino-IDE, weshalb sie eben separat benötigt wird. Es gibt aber mittlerweile auch die Möglichkeit, einen ENC28J60 mittels UIPEthernet mit standard-konformen Funktionsaufrufen zu betreiben, weshalb diese hier zum Einsatz kommt.

Download der Library unter https://github.com/ntruchsess/arduino_uip


// W5100-based Ethernet-Shield
//#include <SPI.h>
//#include <Ethernet.h>

// ENC28J60 Ethernet-Shield - you need the UIPEthernet library for that !!!
#include <UIPEthernet.h>

/*
  LiquidCrystal Library - Pinout:

 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 */

// include the lcd-library code:
#include <LiquidCrystal.h>


#include <Boards.h>
#include <EtherCard.h>
#include <OneWire.h>
#include <DallasTemperature.h>


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// LCD-Keypad
// LiquidCrystal lcd(8, 9, 7, 6, 5, 4);


const int key1 = 6;    // the number of the pushbutton pin
const int key2 = 7;    // the number of the pushbutton pin
const int key3 = 8;    // the number of the pushbutton pin
const int key4 = 9;    // the number of the pushbutton pin
const int key5 = 10;    // the number of the pushbutton pin

int key1State = 0;         // variable for reading the pushbutton status
int key2State = 0;         // variable for reading the pushbutton status
int key3State = 0;         // variable for reading the pushbutton status
int key4State = 0;         // variable for reading the pushbutton status
int key5State = 0;         // variable for reading the pushbutton status

// int grad = 75;  // default soll-Wert für Heizung
int grad = 27;  // zum testen mit Körpertemperatur
int hysterese = 3; // erlaubte Schwankungsbreite bzw. Abweichung nach oben oder unten

// int MAXGRAD = 124; // Maximale Temp vom DS18B20 Temperatursensor
// int MINGRAD = -55; // Minimale Temp vom DS18B20 Temperatursensor
int MAXGRAD = 100; // Temperatur soll unter 100 Grad bleiben
int MINGRAD = 0; // Temperatur soll über 0 Grad bleiben

int MAXHYS = 50; // Schwankungsbreite = 1/2 MAXGRAD
int MINHYS = 0;


const int relPin =  13;      // the number of the relay pin
int rs =  0;      // the current Relais-mode as integer: 
String relState = " aus";



// Data wire is plugged into analog port A0 on the Arduino
// #define ONE_WIRE_BUS A0
#define BUS0 A0
#define BUS1 A1

#define TEMPERATURE_PRECISION 9

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
// OneWire oneWire(ONE_WIRE_BUS);
OneWire ow_bus0(BUS0);
OneWire ow_bus1(BUS1);


// Pass our oneWire reference to Dallas Temperature. 
// DallasTemperature sensors(&oneWire);
DallasTemperature sensors0(&ow_bus0);
DallasTemperature sensors1(&ow_bus1);


// arrays to hold device addresses
// uint8_t insideThermometer[8], outsideThermometer[8];
uint8_t sensoradresses0[8][8];
uint8_t sensoradresses1[8][8];


// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x36 };
static byte myip[] = { 192,168,178,207 };
static byte mygw[] = { 192,168,178,1 };

byte Ethernet::buffer[500];
BufferFiller bfill;

// const char website[] PROGMEM = "wikipedia.de";

float U = 0;
float mytemp = 0;
float temps0[8];
float temps1[8];

int STATIC_IP = 1;  // 0 = DHCP   1 = Static IP

int i = 0;
int count0 = 0;
int count1 = 0;

void setup () {

  // start serial port
  Serial.begin(9600);
  Serial.println("Heizkreisrelais online");


  // initialize the LED pin as an output:
  pinMode(relPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(key1, INPUT);     
  pinMode(key2, INPUT);     
  pinMode(key3, INPUT);     
  pinMode(key4, INPUT);     
  pinMode(key5, INPUT);     
 
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("Heizkreisrelais");
  lcd.setCursor(0, 1);
  lcd.print("V.04 by Case");
  lcd.clear();
  //delay(100);



  if (ether.begin(sizeof Ethernet::buffer, mymac,53) == 0)
  {
    //lcd.setCursor(0, 0);
    //lcd.print("Failed to access Ethernet controller");
    Serial.println( "Failed to access Ethernet controller");
  }
  else
  {
    //lcd.setCursor(0, 0);
    //lcd.print("Connected to Ethernet controller");
    Serial.println( "Connected to Ethernet controller");
  }

    
  if (STATIC_IP != 0) 
  {
    Serial.println("\nGet Static IP ...");
    ether.staticSetup(myip,mygw);
    ether.printIp("My IP: ", ether.myip);
    ether.printIp("My GW: ", ether.gwip);
  }  
  else 
  {
    Serial.println("\nGet DHCP ...");
 
    if (!ether.dhcpSetup())
      Serial.println("DHCP failed");
  
    ether.printIp("My IP: ", ether.myip);
    // ether.printIp("Netmask: ", ether.mymask);
    ether.printIp("GW IP: ", ether.gwip);
    ether.printIp("DNS IP: ", ether.dnsip);

    // if (!ether.dnsLookup(website))
    //   Serial.println("DNS failed");
    // ether.printIp("Server: ", ether.hisip);
    
  } // end else static
  
    
  //check Bus 0
  sensors0.begin();
  count0 = sensors0.getDeviceCount();
  Serial.print("Bus0 Adresses found: ");
  Serial.println(count0);


  for(i=0; i<count0; i++)
  {
    // if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 
    if (!sensors0.getAddress(sensoradresses0[i], i)) Serial.println("Unable to find address for Device " + i); 
  
    // show the addresses we found on the bus
    // Serial.print("Device 0 Address: ");
    printAddress(sensoradresses0[i]);
    Serial.println();

    // set the resolution to 9 bit
    sensors0.setResolution(sensoradresses0[i], 9);
 
    // sensors.requestTemperatures(); // Send the command to get temperatures
  
  } // end for
  sensors0.setWaitForConversion(false);
  
/*  
  //check Bus 1
  sensors1.begin();
  count1 = sensors1.getDeviceCount();
  Serial.print("Bus1 Adresses found: ");
  Serial.println(count1);
  
  //check Bus 1
  for(i=0; i<count1; i++)
  {
    if (!sensors1.getAddress(sensoradresses1[i], i)) Serial.println("Unable to find address for Device " + i); 
  
    // show the addresses we found on the bus
    // Serial.print("Device 0 Address: ");
    printAddress(sensoradresses1[i]);
    Serial.println();

    // set the resolution to 9 bit
    sensors1.setResolution(sensoradresses1[i], 9);
 
    // sensors.requestTemperatures(); // Send the command to get temperatures
  
  } // end for
  sensors1.setWaitForConversion(false);
  
*/
  
  // Startzustand: Relais ist ausgeschaltet
  relState = "0"; 
  rs=0;
  
} // end setup()


// function to print a device address
void printAddress(uint8_t deviceAddress[])
{
  for (uint8_t i = 0; i < 8; i++)
  {
    Serial.print(deviceAddress[i], HEX);
    if (i < 7) Serial.print(" ");
  }
}

// function to print the temperature for a device
void printTemperature(uint8_t deviceAddress[], int whichbus)
{
  float tempC = 0.0;
  
  if(whichbus == 0)  tempC = sensors0.getTempC(deviceAddress);
  if(whichbus == 1)  tempC = sensors1.getTempC(deviceAddress);
    
  Serial.print("Temp C: ");
  Serial.print(tempC);
  // U = tempC;
  // Serial.print(U);
}

// function to print a device's resolution
void printResolution(uint8_t deviceAddress[])
{
  Serial.print("Resolution: ");
  Serial.print(sensors0.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(uint8_t deviceAddress[])
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress,0);
  Serial.println();
}


static word homePage() {
  long t = millis() / 1000;
  word h = t / 3600;
  byte m = (t / 60) % 60;
  byte s = t % 60;
  word t0[8];
  word t1[8];


  for(i=0; i<8; i++) t0[i] = 22222.0;
  for(i=0; i<8; i++) t1[i] = 22222.0;
  
  for(i=0; i<count0; i++) t0[i] = temps0[i] * 100;
  for(i=0; i<count1; i++) t1[i] = temps1[i] * 100;
  
  t0[1]= grad;
  t0[2]= hysterese;
  t0[3]= rs;

  
  // Serial.println(U);
  
  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<meta http-equiv='refresh' content='10'/>"
    "<title>Heizkreisrelais, 2015 by OpenEcoLab Rahden</title>" 
    // "<h1>:$D.$D:$D.$D:</h1>"),
    // "<b>:$D.$D:$D.$D:</b>"),
    // "<b>:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:</b>"),
    
    "<b>:$D.$D:$D:$D:$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:$D.$D:</b>"),

    // t0[0]/100, t0[0]%100, t0[1]/100, t0[1]%100);
    // t0[0]/100, t0[0]%100, t0[1]/100, t0[1]%100, t0[2]/100, t0[2]%100, t0[3]/100, t0[3]%100);
    
    // t0[0]/100, t0[0]%100, t0[1]/100, t0[1]%100, t0[2]/100, t0[2]%100, t0[3]/100, t0[3]%100,

    t0[0]/100, t0[0]%100, t0[1], t0[2], t0[3],
    t0[4]/100, t0[4]%100, t0[5]/100, t0[5]%100, t0[6]/100, t0[6]%100, t0[7]/100, t0[7]%100,
    
    t1[0]/100, t1[0]%100, t1[1]/100, t1[1]%100, t1[2]/100, t1[2]%100, t1[3]/100, t1[3]%100,
    t1[4]/100, t1[4]%100, t1[5]/100, t1[5]%100, t1[6]/100, t1[6]%100, t1[7]/100, t1[7]%100);
    
  return bfill.position();
}

void loop () {

  
  // Serial.println(count0);
     printAddress(sensoradresses0[0]);
 
  sensors0.requestTemperatures(); // Send the command to get temperatures
  for(i=0; i<count0; i++)
  {
    temps0[i] = sensors0.getTempCByIndex(i);
     Serial.print("  ");
     Serial.println(temps0[i]);
  }

/*
  sensors1.requestTemperatures(); // Send the command to get temperatures
  for(i=0; i<count1; i++)
  {
    temps1[i] = sensors1.getTempCByIndex(i);
    // Serial.println(temps1[i]);
  }
*/



  // read the state of the pushbutton value:
  key1State = digitalRead(key1);
  key2State = digitalRead(key2);
  key3State = digitalRead(key3);
  key4State = digitalRead(key4);
  key5State = digitalRead(key5);

  delay(100);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  
  // Sollwert erhöhen
  if (key1State == HIGH) 
  { 
    if ( grad < MAXGRAD ) grad = grad + 1; 
    else grad = 0;
  } 
    // Sollwert verringern
  if (key2State == HIGH) 
  { 
    if ( grad > MINGRAD ) grad = grad - 1; 
    else grad = MAXGRAD;
  } 
  
  
  // Schwankungsbreite erhöhen
  if (key3State == HIGH) 
  { 
    if ( hysterese < MAXHYS ) hysterese = hysterese + 1; 
    else hysterese = 0;
  } 
   // Schwankungsbreite verringern
  if (key4State == HIGH) 
  { 
    if ( hysterese > MINHYS ) hysterese = hysterese - 1; 
    else hysterese = MAXHYS;
  } 


  // Relais per Taste umswitchen
  if (key5State == HIGH) 
  { 
    if (rs == 1) { relState = "0"; rs=0; }
    else { relState = "1"; rs=1; }
    
    Serial.print("Relais: ");
    Serial.println(relState);
  } // end if(key5State)
  

  // Relais automatisch je nach Temperatur umswitchen
  if((temps0[0] >= (grad+hysterese)) & (rs==1))
  {
    rs=0;
    relState = "0";
    Serial.println("Relais off");
    // delay(10);
    digitalWrite(relPin, LOW);
  } 

  if((temps0[0] <= (grad-hysterese)) & (rs==0))
  {
    rs=1;
    relState = "1";
    Serial.println("Relais on");
    // delay(10);
    digitalWrite(relPin, HIGH);
  } 




  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
     
  if (pos)  // check if valid tcp data is received
    ether.httpServerReply(homePage()); // send web page data
   
 
    
 
  lcd.setCursor(0,0);
//   lcd.print("Ist :");
//   lcd.print(grad);
  lcd.print("Ist:      ");
  lcd.setCursor(4,0);
  lcd.print(temps0[0]);


  lcd.setCursor(11, 0);
  lcd.print("Rel:");  // Relais Zustände: dauer-ein, dauer-aus, dem Temperatur-Programm folgend
  lcd.setCursor(15, 0);
  // Relais Zustände: dauer-ein, dauer-aus, dem Temperatur-Programm folgend
  lcd.print(relState);   
  
  
  
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  lcd.print("Soll:    ");
  lcd.setCursor(5, 1);
  lcd.print(grad);
  lcd.setCursor(10, 1);
  lcd.print("+/-:  ");
  lcd.setCursor(14, 1);
  lcd.print(hysterese); // 1/2 Range
    
    
} // end loop()