Cronotemostato controllato via web

Da wiki.piffa.net.

Cronotermostato Domestico

Semplice progetto per realizzare un cronotermostato che visualizza data, ora e temperatura su un display oled

e che permette di controllo di una caldaia da remoto

Componenti necessari per realizzare il progetto[modifica]

Lista dei materiali utilizzati:

  1. Display Oled: http://www.banggood.com/0_96-Inch-4Pin-White-IIC-I2C-OLED-Display-Module-12864-LED-For-Arduino-p-958196.html
  2. Modulo RTC DS3231 --> libreria usata DS1302.h : http://www.banggood.com/5Pcs-DS3231-AT24C32-IIC-Real-Time-Clock-Module-For-Arduino-p-958132.html
  3. Termometro digitale Ds18b20: http://www.banggood.com/Wholesale-DS18B20-Waterproof-Digital-Temperature-Temp-Sensor-Probe-p-53674.html
  4. Modulo ethernet ENC28J60: http://www.banggood.com/ENC28J60-Ethernet-LAN-Network-Module-Schematic-For-Arduino-51-AVR-LPC-p-87596.html
  5. Relay: http://www.banggood.com/1-Channel-5V-Relay-Module-Shield-Board-For-Arduino-ARM-PIC-AVR-DSP-ARM-p-914846.html

Schema elettrico[modifica]

(disegno da realizzare)

Collegamento Relay[modifica]

Comando Relay -> Arduino pin 9

Collegamento sensore temperatura[modifica]

DS18B20 D0 -> Arduino pin 7

Nota: nel collegare il sensore di temperatura ricordarsi la resistenza tra D0 (dati) e Vcc da 4,7 Kohm

Collegamento display Oled[modifica]

OLED_DC -> Arduino pin A0 
OLED_CS -> Arduino pin A1 
OLED_CLK -> Arduino pin A2 
OLED_MOSI -> Arduino pin A3
OLED_RESET -> Arduino pin A4

Collegamento modulo ethernet[modifica]

ENC SO -> Arduino pin 12
ENC SI -> Arduino pin 11
ENC SCK -> Arduino pin 13
ENC CS -> Arduino pin 8
ENC VCC -> Arduino 3V3 pin
ENC GND -> Arduino Gnd pin

Nota: Il modulo ENC28J60 dev'essere alimentato a 3,3v non 5v quindi può risultare necessario con alcuni tipi di Arduino aggiungere una resistenza

Librerie utilizzate[modifica]

Per il termometro[modifica]

Per il corretto dialogo con il sensore

OneWire.h

Per aver il valore della temperatura già convertito ed utilizzabile

DallasTemperature.h

Per il modulo Ethernet[modifica]

EtherCard.h

Per il display oled[modifica]

Libreria per gestire la parte grafica del display creazione di linee, circonferenze ecc...

U8glib.h

Codice del progetto[modifica]

#include <SPI.h>
#include <Wire.h>
#include <DS1302.h>
#include <OneWire.h>
#include <EtherCard.h>
#include <DallasTemperature.h>      //libreria per conversione valore
#include <U8glib.h>
#define REL 9
#define DEBUG 1 
// modulo Oled con la libreria u8g
#define OLED_DC A0 // Pin D/C
#define OLED_CS A1 // Not connected
#define OLED_CLK A2 // Pin SCL
#define OLED_MOSI A3 // Pin SDA
#define OLED_RESET A4 // Pin RST
U8GLIB_SSD1306_128X64_2X u8g(OLED_CLK,OLED_MOSI,OLED_CS,OLED_DC,OLED_RESET);


// inizilaizzazione ethernet
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,100,120 };
byte Ethernet::buffer[500];
BufferFiller bfill;

// Modulo clock DS1302
//DS1302(ce(RST), data, clock);
DS1302 rtc(4,5,6);

// Termometro ds18b20
OneWire  ds(7);  // on pin 7 (a 4.7K resistor is necessary)
DallasTemperature sensors(&ds);
float temperatura;

void setup () {
  pinMode(REL,OUTPUT);
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
  ether.staticSetup(myip);
  Serial.begin(9600);
  // La funzione seguente è da invocare solo la prima volta che si deve settare l'orario o per correggerlo
  // set_time();
}

void set_time() {
 rtc.setDOW(SUNDAY); // Set Day-of-Week to FRIDAY
 rtc.setTime(17, 24, 0); // Set the time to 12:00:00 (24hr format)
 rtc.setDate(8, 1, 2015); // Set the date to August 6th, 2010
}

static word homePage(float temperatura) {
// Siccome BufferFiller  non gestisce in stampa i float
// faccio la conversione della temperatura in 2 numeri interi
// che saranno la parte intera e quella decimale.
  int temp = (int)(temperatura * 100);
  int intera = (int)temperatura;
  int decimale = temp-(intera*100);
//  Serial.println ("homepage");
//  Serial.println (temperatura);
//  char temper[10]=temperatura[];
  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='1'/>"
    "<title>Server</title>"
    "<h1>la temperatura rilevata e' $D.$D </h1>"
    "ora $S 
" // "data $S $S $S
" "<input type=button value='Relay 1 ON' onmousedown=location.href='/on'>" "<input type=button value='Relay 1 OFF' onmousedown=location.href='/off'>

" ), intera,decimale,rtc.getTimeStr(FORMAT_SHORT) //,rtc.getDOWStr(), rtc.getMonthStr(1),rtc.getDateStr(FORMAT_LONG,FORMAT_LITTLEENDIAN,'.') ); return bfill.position(); } void loop () { sensors.requestTemperatures(); temperatura = sensors.getTempCByIndex(0); char temp[10]; //temporarily holds data from vals dtostrf(temperatura, 4, 2, temp); //4 is mininum width, 3 is precision; float value is copied onto buff u8g.firstPage(); do { u8g.setFont(u8g_font_unifont); u8g.drawStr( 0, 20, "temp:"); u8g.drawStr( 60, 20, temp); // Disegno del termometro u8g.drawCircle(106,10,2); u8g.drawStr(0, 40,rtc.getDateStr()); u8g.drawStr(0, 60,rtc.getTimeStr(FORMAT_SHORT)); u8g.drawCircle(122, 5, 3, U8G_DRAW_UPPER_LEFT); u8g.drawCircle(122, 5, 3, U8G_DRAW_UPPER_RIGHT); u8g.drawLine(119, 5, 119, 56); u8g.drawLine(125, 5, 125, 56); u8g.drawLine(119, 10, 126, 10); u8g.drawLine(119, 20, 126, 20); u8g.drawLine(119, 30, 126, 30); u8g.drawLine(119, 40, 126, 40); u8g.drawLine(119, 50, 126, 50); u8g.drawPixel(118,57); u8g.drawPixel(126,57); u8g.drawCircle(122, 58, 5, U8G_DRAW_LOWER_LEFT); u8g.drawCircle(122, 58, 5, U8G_DRAW_LOWER_RIGHT); //Serial.println(rtc.getDateStr()); //Serial.println(rtc.getTimeStr()); } while( u8g.nextPage() ); word len = ether.packetReceive(); word pos = ether.packetLoop(len); if (pos) {// check if valid tcp data is received // data received from ethernet char* data = (char *) Ethernet::buffer + pos; #if DEBUG // display incoming data - this is handy but tends to lock the arduino up ? Serial.println("----------------"); Serial.println("data received:"); Serial.println(data); Serial.println("----------------"); #endif // "on" command received if (strncmp("GET /on",data,7) == 0) { digitalWrite(REL, HIGH); #if DEBUG Serial.println("option1 received"); #endif } // "off" command received if (strncmp("GET /off",data,8) == 0) { digitalWrite(REL, LOW); // set the LED off #if DEBUG Serial.println("option2 received"); #endif } ether.httpServerReply(homePage(temperatura)); // send web page data'09 } }