RDCAMPOS
Published © GPL3+

MetOnline

Control relays trought internet and get sensor values. Controla relés pela internet e obtem dados de sensor.

IntermediateFull instructions provided1,906
MetOnline

Things used in this project

Story

Read more

Schematics

http://fritzing.org/projects/metonline

Code

Main Code

Arduino
// NAO USAR PINOS 10, 11, 12 e 13 - utilizados pelo ETHERNET
// DESLIGAR SD: pin 4 output high. W500: pin 10 output.
// W5100 problema do restart: colocar um capacitor de 47nF entreo o RESET e o GND

#include <DHT.h>
#include <LiquidCrystal_I2C.h> // biblioteca by Frank Brabander 1.1.2 https://github.com/johnrickman/LiquidCrystal_I2C
#include <SPI.h>
#include <Ethernet.h>

float umidade;
float temperatura;
float indice;

bool opcaoDisplay = true; //variavel para alternar no LCD entre sensores e estado dos reles
int botaoAlterna = 9;

//variaveis para controlar debounce do pushbutton e taxa de atualizacoes
unsigned long tempoAnterior = 0;
unsigned long debounceDelay = 350;
unsigned long tempoLCD = 0;
unsigned long delayLCD = 2000;

String dados;
int reles[4] = { 5, 6, 7, 8 };

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 105);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
EthernetServer server(80);

DHT dht(2, DHT11);
LiquidCrystal_I2C lcd(0x27, 20, 4); // seta endereco LCD para 0x27 com DISPLAY de 16 char e 2 linhas

String HTTP_req; // armazena requisicao HTTP

void setup() {

	Serial.begin(9600);

	//desligando modulo SD do W5100
	pinMode(4, OUTPUT);
	digitalWrite(4, HIGH);

	//iniciando servidor
	Ethernet.begin(mac, ip, gateway, subnet);
	server.begin();

	//iniciando sensor DHT11
	dht.begin();

	//iniciando LCD
	lcd.init();
	lcd.setBacklight(HIGH);

	pinMode(botaoAlterna, INPUT);

	//definindo e iniciando os reles
	for (int i = 0; i < 4; i++) {
		pinMode(reles[i], OUTPUT);
		digitalWrite(reles[i], HIGH);
	}
}

void loop() {

	//atualizando dados e estado dos reles
	if (millis() > (tempoLCD + delayLCD)) { // so atualiza se "chegou a hora"
		tempoLCD = millis();
		atualizaDados();
		escreveLCD();
	}

	//altera entre leitura local e da internet
	if ((digitalRead(botaoAlterna) == HIGH)
			&& (millis() > (tempoAnterior + debounceDelay))) { // controlando debounce
		tempoAnterior = millis();
		if (opcaoDisplay) {
			opcaoDisplay = false;
			lcd.clear();
		} else {
			opcaoDisplay = true;
		}
		//atualizaDados();
		escreveLCD();
	}

	//Aguarda conexao do browser
	EthernetClient client = server.available();
	if (client) {
		Serial.println("new client");
		// requisicao http termina com linha em branco
		boolean currentLineIsBlank = true;
		while (client.connected()) {
			/*if (millis() > (tempoRequisicao + delayRequisicao)) {
			 tempoRequisicao = millis();
			 }*/
			if (client.available()) {
				char c = client.read();
				HTTP_req += c;
				// if you've gotten to the end of the line (received a newline
				// character) and the line is blank, the http request has ended,
				// so you can send a reply
				if (c == '\n' && currentLineIsBlank) {
					// enviando header JSON
					client.println("HTTP/1.1 200 OK");
					//client.println("Content-Type: text/html"); // header de retorno padro
					client.println("Content-Type: application/json"); // header para JSON
					client.println("Access-Control-Allow-Origin: http://192.168.0.100"); //permitir acesso do jquery do servidor
					client.println("Connection: close");
					client.println();
					processaReles();
					client.print(dados);
					Serial.print(HTTP_req);
					HTTP_req = "";    // requisicao completa, esvaziando string
					break;
				}
				if (c == '\n') {
					// you're starting a new line
					currentLineIsBlank = true;
				} else if (c != '\r') {
					// you've gotten a character on the current line
					currentLineIsBlank = false;
				}
			}
		}
		// delay pro browser receber os dados
		delay(1);
		// termina a conexao
		client.stop();
	}
	delay(1);
}

//atualiza dados no programa e prepara JSON
void atualizaDados() {
	umidade = dht.readHumidity();
	temperatura = dht.readTemperature();
	indice = (dht.computeHeatIndex(dht.readTemperature(),dht.readHumidity(), false));
	dados = ("{\"temperatura\":" + String(temperatura) + ",\"umidade\":" + String(umidade) + ",\"indice\":" + String(indice) + ",\"reles\":{");
	dados = dados + "\"0\":" + !digitalRead(reles[0]);
	dados = dados + ",\"1\":" + !digitalRead(reles[1]);
	dados = dados + ",\"2\":" + !digitalRead(reles[2]);
	dados = dados + ",\"3\":" + !digitalRead(reles[3]) + "}}";
}

// mostra dados do sensor ou estado dos rels
void escreveLCD() {
	if (opcaoDisplay) {
		lcd.setCursor(0, 0);
		lcd.print("T ");
		lcd.print(temperatura, 1);
		lcd.write(byte(223));
		lcd.print("C ");
		lcd.write(byte(165));
		lcd.print(" U ");
		lcd.print(round(umidade));
		lcd.print("%");
		lcd.setCursor(0, 1);
		lcd.print("I ");
		lcd.print(indice, 1);
		lcd.write(byte(223));
		lcd.print("C ");
		lcd.write(byte(165));
		lcd.print(" DHT11");
	} else {
		lcd.setCursor(0, 0);
		lcd.print("R0 ");
		if (digitalRead(reles[0]) == LOW) {
			lcd.print("ON  ");
		} else {
			lcd.print("OFF ");
		}
		lcd.write(byte(165));
		lcd.print(" R1 ");
		if (digitalRead(reles[1]) == LOW) {
			lcd.print("ON  ");
		} else {
			lcd.print("OFF ");
		}
		lcd.setCursor(0, 1);
		lcd.print("R2 ");
		if (digitalRead(reles[2]) == LOW) {
			lcd.print("ON  ");
		} else {
			lcd.print("OFF ");
		}
		lcd.write(byte(165));
		lcd.print(" R3 ");
		if (digitalRead(reles[3]) == LOW) {
			lcd.print("ON  ");
		} else {
			lcd.print("OFF ");
		}
	}
}

//requisicao de alteracao de rele
void processaReles() {
	if (HTTP_req.indexOf("r") > -1) {
		//tem pedido de rele pegando o numero dele
		int posicaoRele = (HTTP_req.indexOf("r") + 1);
		int numeroRele = ((int)(HTTP_req.charAt(posicaoRele))) - 48;
		//pegando solicitacao
		int posicaoAcao = (HTTP_req.indexOf("r") + 3);
		int numeroAcao = ((int)(HTTP_req.charAt(posicaoAcao))) - 48;
		//se for valor valido modifica rele
		if ((numeroRele >= 0 && numeroRele <= 3) && (numeroAcao >= 0 && numeroAcao <= 1)) {
			digitalWrite(reles[numeroRele], !numeroAcao);
			//atualiza antes de enviar
			atualizaDados();
		}
	}
}

Main HTML

HTML
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
	<title>Controle Arduino</title>
	<link href="https://fonts.googleapis.com/css?family=Ropa+Sans" rel="stylesheet">
	<link rel="icon" href="http://www.arduino.cc/favicon.ico">
	<link rel="stylesheet" type="text/css" href="style.css">
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>	
	<script>
		//definindo variaveis
		var urlArduino = "http://192.168.0.105"; //trocar para o ip do seu arduino
		var urlConsulta = "";
		var stringRele = "";

		//atualiza valores na pagina
		function updateValues () {
			//verifica se houve clique nos "botoes" e prepara url
			if (stringRele != "") {
				urlConsulta = (urlArduino + stringRele);
			} else {
				urlConsulta = urlArduino;
			}
			stringRele = ""; //
			
			//faz a consulta, se houver link do rele atualiza o estado dele no arduino qd chama o getJSON
			$.getJSON(urlConsulta, function(json) {
				//atualiza valores
				$('#temperatura').text((json.temperatura).toFixed(1));
				$('#indice').text((json.indice).toFixed(1));
				$('#umidade').text(json.umidade);
				
				//atualiza botoes
				Object.keys(json.reles).forEach(function(key) {
					var meuLink = "#r" + key;
					if (json.reles[key] == 0) {
						$(meuLink).removeClass("on").addClass("off");
						$(meuLink).attr('value',0);
					} else {
						$(meuLink).removeClass("off").addClass("on");
						$(meuLink).attr('value',1);
					}
				})
			});
		}

		//executa qd entra na pagina
		updateValues();
		
		//intervalor para chamar a funo automaticamente a cada 2s
		window.setInterval(function(){
			updateValues();
		}, 2000);
		
		//funo para click em link dos reles descartando outros links
		$(function(){
			$("a").click(function(){
				var meuId = $(this).attr("id");
				// verifica se o link tem um id
				if (typeof meuId !== typeof undefined && meuId !== false) {
					// se tem "r" no id do link  poque  um boto (nao colocar ids com "r" em outros links)
					if ((($(this).attr("id")).indexOf("r")) != -1) {         
						//pega o valor atual do boto e prepara o complemento com o inverso para a url de consulta
						if ($(this).attr("value") == 0) {
							stringRele = ("?" + $(this).attr("id") + "=1");
						} else {
							stringRele = ("?" + $(this).attr("id") + "=0");
						}
						//realiza a consulta
						updateValues(stringRele);
					}
				}
			});
		});
	</script>	
</head>
<body>
	<div>
		<div id="inicio">
			<div class="logo"></div>
			<div class="titulo"><h1>Controle Arduino</h1></div>
		</div>
		<div>
			<table>
				<tr>
					<th>Temperatura (&deg;C)</th>
					<th>ndice de Calor (&deg;C)</th>
					<th>Umidade (%)</th>
				</tr>
				<tr>
					<td></td>
					<td></td>
				</tr>
				<tr>
					<td id="temperatura"></td>
					<td id="indice"></td>
					<td id="umidade"></td>
				</tr>
			</table>
		</div>
		<div id="buttons">
			<a href="#" class="button off" id="r0" value="0">Rel 0</a>
			<a href="#" class="button off" id="r1" value="0">Rel 1</a>
			<a href="#" class="button off" id="r2" value="0">Rel 2</a>
			<a href="#" class="button off" id="r3" value="0">Rel 3</a>
		</div>
	</div>
	<div>
		<p>&sup1; Preciso do sensor <a href="https://www.mouser.com/ds/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf" target=_BLANK>DHT11</a> de +/-5% para umidade e +/-2 graus Celsius para temperatura.</p>
	</div>
</body>
</html>

Stylesheet

CSS
body {
	font-family: 'Ropa Sans', sans-serif;
	margin: 0px;
}
h1 {
	margin:0px;
}		
table {
	width: 100%;
	border-collapse: collapse;
}
th, td {
	font-size:3em;
	text-align:center;
	width:33%;
}

#inicio {
	margin: 0px 0px 10px 0px;
	text-align: center;
	background-color: #00979d;
	line-height: 120px;
	height: 120px;
	color: #ffffff;
}
.logo {
	background-image: url(https://content.arduino.cc/brand/arduino-white.svg),url(https://content.arduino.cc/brand/arduino_compressed-white.svg);
	background-position: 30px 10px,30px 120px;
	background-repeat: no-repeat,no-repeat;
	background-size: 134px 100px,58px 32px;
	box-sizing: content-box;
	display: block;
	height: 100px;
	float:left;
	padding: 10px 30px;
	position: relative;
	width: 134px;
}
.titulo {
	float:left;
	width: 80%;
	text-align:center;
}

#buttons {
	text-align:center;
}

.button {
	color:#ffffff;
	font-size:3em;
	height:120px;
	line-height:120px;
	text-decoration: none;
	padding: 18px 8px 18px 8px;
	border-top: 1px solid #CCCCCC;
	border-right: 1px solid #333333;
	border-bottom: 1px solid #333333;
	border-left: 1px solid #CCCCCC;			
}
.on {
	background-color: #00979d;
}
.off {
	background-color: #e67e22;
}

Credits

RDCAMPOS

RDCAMPOS

0 projects • 1 follower

Comments