//#include <HTU21D.h>
#include "DHT.h"
#include <DS18B20.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ctype.h>
#define DHTPIN 18 // Pin donde está conectado el sensor
//#define DHTTYPE DHT11 // Descomentar si se usa el DHT 11
#define DHTTYPE DHT22 // Sensor DHT22
DHT dht(DHTPIN, DHTTYPE);
/*
void setup() {
Serial.begin(9600);
Serial.println("Iniciando...");
}
void loop() {
delay(2000);
float h = dht.readHumidity(); //Leemos la Humedad
float t = dht.readTemperature(); //Leemos la temperatura en grados Celsius
float f = dht.readTemperature(true); //Leemos la temperatura en grados Fahrenheit
//--------Enviamos las lecturas por el puerto serial-------------
Serial.print("Humedad ");
Serial.print(h);
Serial.print(" %t");
Serial.print("Temperatura: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.println(" *F");
}
*/
/*
Relacionado con las pantallas
*/
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x78 ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//////////////
/*
Relacionado con Virtuino.
*/
#include <WiFi.h>
//---VirtuinoCM Library settings --------------
#include "VirtuinoCM.h"
VirtuinoCM virtuino;
#define V_memory_count 32 // the size of V memory. You can change it to a number <=255)
float V[V_memory_count]; // This array is synchronized with Virtuino V memory. You can change the type to int, long etc.
bool debug=true;
//--- SETTINGS conexion Wifi------------------------------------------------
const char* ssid = "ONETEK"; // enter the name (SSID) of your WIFI network
const char* password = "2708511921NGR"; // enter your WIFI network PASSWORD
WiFiServer server(8000); // Default Virtuino Server port
IPAddress ip(192, 168, 100, 109); // where 150 is the desired IP Address. The first three numbers must be the same as the router IP
IPAddress gateway(192, 168, 100, 1); // set gateway to match your network. Replace with your router IP
//---
//HTU21D htu;
//---
/*
Relacionado con los sesores DS18B20
*/
DS18B20 ds(32); // pin GIO donde esta conectado los datos de los sensores.
struct obj_DS18B20{
uint8_t Index; // indice del sensor, relacionado con que función
String address; // Codigo o direccion del sensor
String Descrip; // Descipcion del sensor
uint8_t Resol; // resolución
uint8_t Power; // tipo de alimentacion
float Offset=0; // correncion de la medida ºC
float Cel=0.0; // temperatura ºC de la ultima medida
float Far=0.0; // Temperatura ºF de la ultima medida
uint8_t CntRep; // Numero de no reportes
bool Identificado=false; // ya fue identificado
bool Reporto=false; // ya reporto
bool Inhibidor=false;// Si falla inhibe el funcionamiento. para el equipo.
};
obj_DS18B20 Sen_Temp[20]; // numero de sensores posibles
// definicion de la medida hecha por cada sensor DS18B20.
const String ArrIden []={"Cooler Salida","Cooler Retorno","Comp.Salida","Comp.Succion","Comp. bloque","Sal.Conde"};
int LED = 32; /*LED pin defined*/
int Sensor_input = 18; /*Digital pin for sensor input*/
int TotalDS=0; // numero de sensores DS18B20 conseguidos.
/// fin de relacionados con los sensores DS18B20
//====== conexion como Cliente WiFi ========================================================
void connectToWiFiNetwork(){
Serial.println("Connecting to "+String(ssid));
// If you don't want to config IP manually disable the next two lines
IPAddress subnet(255, 255, 255, 0); // set subnet mask to match your network
WiFi.config(ip, gateway, subnet); // If you don't want to config IP manually disable this line
WiFi.mode(WIFI_STA); // Config module as station only.
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
}
//========== conexion como Accespoint WiFi =======================================================
void initAccessPoint(){
Serial.print("Setting soft-AP ... "); // Default IP: 192.168.4.1
WiFi.mode(WIFI_AP); // Config module as Access point only. Set WiFi.mode(WIFI_AP_STA); to config module as Acces point and station
boolean result = WiFi.softAP("ESP32", "12345678"); // SSID: Virtuino Network Password:12345678
if(result == true) {
Serial.println("Server Ready");
Serial.println(WiFi.softAPIP());
}
else Serial.println("Failed!");
}
//==============================================================
///// V I R T U I N O
//==============================================================
//======= onCommandReceived
/* This function is called every time Virtuino app sends a request to server to change a Pin value
* The 'variableType' can be a character like V, T, O V=Virtual pin T=Text Pin O=PWM Pin
* The 'variableIndex' is the pin number index of Virtuino app
* The 'valueAsText' is the value that has sent from the app */
void onReceived(char variableType, uint8_t variableIndex, String valueAsText){
if (debug){
Serial.print("onReceived");
Serial.print(" Tipo:");
Serial.print(variableType);
Serial.print("Variable: ");
Serial.println(valueAsText);
}
if (variableType=='V'){
float value = valueAsText.toFloat(); // convert the value to float. The valueAsText have to be numerical
if (variableIndex<V_memory_count) V[variableIndex]=value; // copy the received value to arduino V memory array
}
}
//==============================================================
/* This function is called every time Virtuino app requests to read a pin value*/
String onRequested(char variableType, uint8_t variableIndex){
if (debug){
Serial.print("onRequested");
Serial.print(" Tipo:");
Serial.print(variableType);
Serial.print("Indice Var: ");
Serial.println(variableIndex);
}
if (variableType=='V') {
if (variableIndex<V_memory_count) return String(V[variableIndex]); // return the value of the arduino V memory array
}
if (variableType=='M') {
String txt="";
txt=Sen_Temp[variableIndex].address+" "+Sen_Temp[variableIndex].Descrip;
return txt;
}
return "";
}
//==== eSTA FUNCION ES LLAMADA CONTINUAMENTE PARA GESTIONAR LA COMUNICACION virtuino =======
void virtuinoRun(){
WiFiClient client = server.available();
if (!client) return;
if (debug) Serial.println("Connected");
unsigned long timeout = millis() + 3000;
while (!client.available() && millis() < timeout) delay(1);
if (millis() > timeout) {
Serial.println("timeout");
client.flush();
client.stop();
return;
}
virtuino.readBuffer=""; // clear Virtuino input buffer. The inputBuffer stores the incoming characters
while (client.available()>0) {
char c = client.read(); // read the incoming data
virtuino.readBuffer+=c; // add the incoming character to Virtuino input buffer
if (debug) Serial.write(c);
}
client.flush();
if (debug) Serial.println("\nReceived data: "+virtuino.readBuffer);
String* response= virtuino.getResponse(); // get the text that has to be sent to Virtuino as reply. The library will check the inptuBuffer and it will create the response text
if (debug) Serial.println("Response : "+*response);
client.print(*response);
client.flush();
delay(10);
client.stop();
if (debug) Serial.println("Disconnected");
}
//= Este dela es llamado para evita el bloqueo y hacer llamadas al gestor Virtuino === vDelay
void vDelay(int delayInMillis){long t=millis()+delayInMillis;while (millis()<t) virtuinoRun();}
//////////////////////////////////////////////////////////////////////////////////////
//// FIN DEL PROCESO VIRTUINO ///////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
/// CONVIERTE UN ENTERO EN HEX
const char LHex[]="0123456789ABCDEF";
String Int_Hex(int v)
{
String TxHex="";
int H=0,L=0,i=0;
H=v/16;
L=v%16;
TxHex=String(LHex[H])+String(LHex[L]);
/* Serial.print("\n\rV:");Serial.print(v);Serial.print(" ");Serial.print(v,HEX);
Serial.print(" LHex[H]:");Serial.print(LHex[H]);Serial.print(" LHex[L]:");Serial.print(LHex[L]);
Serial.print(" HEX:");Serial.println(TxHex);
*/
return TxHex;
}
//// IDENTIFICA Y CUENTA LOS DS18B20 PRESENTES
void DS18B20Cnt()
{
uint8_t i,j;
String AddressTxt="";
while (ds.selectNext())
{// identifica el proximo encontrado.
ds.getFamilyCode(); // lee el codigo de familia
AddressTxt="";
uint8_t address[9];
ds.getAddress(address); // lee la direccion.
address[8]=0; // poner terminador 0
for (i=0;i<8;++i)
AddressTxt+= Int_Hex(address[i]); // conversion de una direccion a String
AddressTxt+='\0';
////
//Serial.println(AddressTxt);
////
// Loop1: ver si ya lo tenemos en la lista.
for (i=0; i<TotalDS; ++i)
{
for (j = 0; j < 8; j++)// LOOP2: compara las dos direcciones
{
if( Sen_Temp[i].address != AddressTxt) break;// no son iguales, ir al proximo
} // fin loop2
if(j==8)
{ // actualiza los datos.
Sen_Temp[i].Cel=ds.getTempC(); // temperatura en ºC
Sen_Temp[i].Far=ds.getTempF(); // temperatura en ºF
Sen_Temp[i].Resol=ds.getResolution(); // ressolución
Sen_Temp[i].Power=ds.getPowerMode(); // como se alimenta.
if(debug) {Serial.print(i); Serial.println("\t Actualizado");}
break;// son iguales, salir de loop 1
}
} // fin loop1
if (i==TotalDS) // recorrimos todos y no hubo igual
{// agregar el nuevo.
Sen_Temp[TotalDS].address=String(AddressTxt);
Sen_Temp[TotalDS].Descrip =String(ArrIden[TotalDS]);
Sen_Temp[TotalDS].Cel=ds.getTempC();
Sen_Temp[TotalDS].Far=ds.getTempF();
Sen_Temp[TotalDS].Resol=ds.getResolution();
Sen_Temp[TotalDS].Power=ds.getPowerMode();
++TotalDS;
if(debug) {Serial.print("\n\rNuevo: ");
Serial.print(i); Serial.println("\t Actualizado\r\n");}
}
}
// Serial.print("\n\rConseguidos:");Serial.println(TotalDS);
}
uint8_t incomingByte;
static float Ptemperature=0, Phumidity=0;
static uint8_t CntHTU=0;
const String Series="HR=% T=ºC Gas=x100ppm";
void PlotDatos()
{
Serial.println(Series);
Serial.print(Phumidity,2);
Serial.print("\t");
Serial.print(Ptemperature,2);
Serial.print("\t");
if(incomingByte=='9')Serial.println(float(ReadMQ2(false))/100.0,3);
else Serial.println(float(ReadMQ2(true))/100.0,3);
}
void DspTabla()
{
uint8_t i,j,k;
if(debug) return;
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0,0); // Start at top-left corner
Serial.println("\n\rDireccion\t Descripcion\t ºC \t ºF \t Res \ pwr");
for(i=0;i<TotalDS;++i)
{
Serial.print(Sen_Temp[i].address);
Serial.print(" ");
Serial.print(Sen_Temp[i].Descrip);
Serial.print("\t");
Serial.print(Sen_Temp[i].Cel,2);
Serial.print("\t");
Serial.print(Sen_Temp[i].Far,2);
Serial.print("\t");
Serial.print(Sen_Temp[i].Resol);
Serial.print("\t");
Serial.println(Sen_Temp[i].Power);
display.print(Sen_Temp[i].address);
display.print(" ");
display.print(Sen_Temp[i].Descrip);
display.print("\t");
display.println(Sen_Temp[i].Cel,2);
display.display();
}
Serial.print("Gas ppm: ");
Serial.print(analogRead(Sensor_input));
Serial.print("\t Temp ºC: ");
Serial.print(dht.readTemperature(),2);
Serial.print("\t HR %: ");
Serial.print(dht.readHumidity(),2);
}
/*
Lectura del sensor MQ
*/
int MQ2=0;
int ReadMQ2(bool Ultima){
static int Pvalue=0, value=0,Cnt=0;
int sensor_Aout = analogRead(Sensor_input); /*Analog value read function*/
value+=sensor_Aout;
++Cnt;
if (Cnt==10)
{
Pvalue=value/10;
Cnt=0;
value=0;
}
if (Ultima) // Rereso la ultima?
return sensor_Aout; // Si, retornar el ultimo valor leido
else if (Pvalue>0)
return Pvalue;// retornal el promedio
else
return sensor_Aout; // si no se ha hecho un promedio retorna el ultimo
}
/*
Lectura de los sensores DS18B20
*/
void DS18B20ReadShrt()
{
String Tipo="";
while (ds.selectNext()) {
switch (ds.getFamilyCode()) {
case MODEL_DS18S20:
Tipo="DS18S20";
break;
case MODEL_DS1822:
Tipo="DS1822 ";
break;
case MODEL_DS18B20:
Tipo="DS18B20";
break;
default:
Tipo="DESCONO";
break;
}
Serial.print(Tipo);
Serial.print("\t");
uint8_t address[8];
ds.getAddress(address);
for (uint8_t i = 0; i < 8; i++) {
// Serial.print(" ");
if (address[i]<16) Serial.print("0");
Serial.print(address[i],HEX);
}
Serial.print("\t");
Serial.print(ds.getResolution());
Serial.print("\t");
if (ds.getPowerMode()) {
Serial.print("Ext");
} else {
Serial.print("Par");
}
Serial.print("\t");
Serial.print(ds.getTempC());
Serial.print(" C / ");
Serial.print(ds.getTempF());
Serial.println(" F");
}
}
/*
Lectura del sensor HTU21
float h = dht.readHumidity(); //Leemos la Humedad
float t = dht.readTemperature(); //Leemos la temperatura en grados Celsius
float f = dht.readTemperature(true); //Leemos la temperatura en grados Fahrenheit
*/
void DHT22DRead(){
static float temperature=0, humidity=0;
static int Cnt=0;
// if(htu.measure()) {
temperature += dht.readTemperature();
humidity+= dht.readHumidity();
++Cnt;
if (Cnt==10)
{
Ptemperature=temperature/10.0;
Phumidity=humidity/10.0;
Cnt=0;
temperature=0;dht.readHumidity();
humidity=0;
}
// }
}
void ScaniiC() {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
delay(5000);
}
int NroDS18B20=0;
//==============================================================
//=setup========================================================
//==============================================================
void setup() {
//----- Virtuino settings
Serial.begin(9600);
Serial.println("*****************************************************");
Serial.println("*****************************************************");
delay(2000);
ScaniiC();
//virtuino.=true; // set this value TRUE to enable the serial monitor status
//virtuino.password="1234"; // Set a password or prefix to your web server for more protection
// avoid special characters like ! $ = @ # % & * on your password. Use only numbers or text characters
if(display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
Serial.println("Display en 0x3D");
} else if(display.begin(SSD1306_SWITCHCAPVCC,0x3C)) {
Serial.println("Display en 0x3C");
} else if(display.begin(SSD1306_SWITCHCAPVCC,0x78)) {
Serial.println("Display en 0x78");
} else if(display.begin(SSD1306_SWITCHCAPVCC,0x7A)) {
Serial.println("Display en 0x7A");
} else {
Serial.println(F("SSD1306 allocation failed"));
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
// Clear the buffer
display.clearDisplay();
// Draw a single pixel in white
display.drawPixel(10, 10, SSD1306_WHITE);
// Show the display buffer on the screen. You MUST call display() after
// drawing commands to make them visible on screen!
display.display();
delay(2000);
// display.display() is NOT necessary after every single drawing command,
// unless that's what you want...rather, you can batch up a bunch of
// drawing operations and then update the screen all at once by calling
// display.display(). These examples demonstrate both approaches...
virtuino.begin(onReceived,onRequested,256); //Start Virtuino. Set the buffer to 256. With this buffer Virtuino can control about 28 pins (1 command = 9bytes) The T(text) commands with 20 characters need 20+6 bytes
virtuino.key="1234"; //This is the Virtuino password. Only requests the start with this key are accepted from the library
//connectToWiFiNetwork();
//initAccessPoint();
//server.begin();
pinMode(2,OUTPUT);
Serial.print("Devices: ");
Serial.println(NroDS18B20=ds.getNumberOfDevices());
Serial.println();
DS18B20Cnt();
dht.begin();
// Serial.println(F("DHT_22 error"));
}
/*
Proceso que se ejecuta
*/
void proceso() {
//proceso
//DS18B20ReadShrt();
digitalWrite(2,HIGH);
ReadMQ2(false);//
DS18B20Cnt();
DHT22DRead();
if (incomingByte=='0')
DspTabla();
else
PlotDatos();
digitalWrite(2,LOW);
}
void DispTabla()
{
for(uint8_t i=0;i<NroDS18B20;i++)
{
Serial.print("\n\r Tabla");
Serial.println("Nro\tireccion\tDescripcion \tRes\tºC\tºF\tCnt\tIden\tRep");
Serial.print(Sen_Temp[i].Index); // indice del sensor, relacionado con que función
Serial.print(Sen_Temp[i].address); // Codigo o direccion del sensor
Serial.print(Sen_Temp[i].Descrip); // Descipcion del sensor
Serial.print(Sen_Temp[i].Resol); // resolución
Serial.print(Sen_Temp[i].Power); // tipo de alimentacion
Serial.print(Sen_Temp[i].Cel); // temperatura ºC de la ultima medida
Serial.print(Sen_Temp[i].CntRep); // Numero de no reportes
Serial.print(Sen_Temp[i].Identificado); // ya fue identificado
Serial.print(Sen_Temp[i].Reporto); // ya reporto
}
}
//============================================================== loop
//==============================================================
//==============================================================
void loop() {
// virtuinoRun(); // Necessary function to communicate with Virtuino. Client handler
if (Serial.available())
{
incomingByte = toupper(Serial.read());
switch(incomingByte)
{
case 'R':
{
Serial.println("Run");
DispTabla();
break;
}
case 'T':
{
Serial.println("Tabla");
DispTabla();
break;
}
case 'D':
{
debug= !debug;
if(debug) Serial.println("\n\rDebug On");
else Serial.println("\n\rDebug Off");
break;
}
}
}
// enter your loop code here.
if(incomingByte=='R')
proceso();
if(incomingByte=='T')
DispTabla();
//------ avoid to use delay() function in your code
vDelay(1000); // This is an example of the recommended delay function. Remove this if you don't need
}