Mostrando entradas con la etiqueta Sensores. Mostrar todas las entradas
Mostrando entradas con la etiqueta Sensores. Mostrar todas las entradas

miércoles, 7 de diciembre de 2022

Arduino Sensores comerciales de temperatura - rtl_433

  Página principal

Arduino
Sensores comerciales de temperatura.

rtl_433


Después de mi anterior artículo para recibir la señal de los sensores meteorológicos rec433.html , y con la espina clavada de no saber como era el modo de chequear errores, me puse a mirar por internet.
El que busca encuentra, y estaba cerca, estaba dentro de los repositorio de Debian 11, era el programa rtl_433.
Utilizando el receptor de televisión Realtek Semiconductor Corp. RTL2838 DVB-T , se podía recibir un montón de emisores comerciales de estaciones meteorológicas.
Era un filón, es muy buena la documentación que explicaba el protocolo, ahora puedo realizar el programa arduino que detecta errores.
En Debian 11, si queréis bajar las fuentes desde los repositorios, para compilar o ver sus ficheros,  tendréis que dar estas ordenes.
apt-get build-dep rtl-433
apt-get source rtl-433
cd rtl-433-20.11
dpkg-buildpackage -uc -b


seta@debian11:~$ rtl_433

rtl_433 version unknown inputs file rtl_tcp RTL-SDR SoapySDR
Use -h for usage help and see https://triq.org/ for documentation.
Trying conf file at "rtl_433.conf"...
Trying conf file at "/home/seta/.config/rtl_433/rtl_433.conf"...
Trying conf file at "/usr/local/etc/rtl_433/rtl_433.conf"...
Trying conf file at "/etc/rtl_433/rtl_433.conf"...
Registered 145 out of 175 device decoding protocols [ 1-4 8 11-12 15-17 19-21 23 25-26 29-36 38-60 63 67-71 73-100 102-105 108-116 119 121 124-128 130-149 151-161 163-168 170-175 ]
Detached kernel driver
Found Rafael Micro R820T tuner
Exact sample rate is: 250000.000414 Hz
[R82XX] PLL not locked!
Sample rate set to 250000 S/s.
Tuner gain set to Auto.
Tuned to 433.920MHz.
Allocating 15 zero-copy buffers
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2022-12-07 20:06:47
model     : TFA-Pool     Id        : 203
Channel   : 1            Battery   : 1             Temperature: 9.9 C        Integrity : CHECKSUM

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _


time      : 2022-12-07 20:06:47
model     : TFA-Pool     Id        : 203
Channel   : 1            Battery   : 1            
Temperature: 9.9 C        Integrity : CHECKSUM

time      : 2022-12-07 20:57:57
model     : AlectoV1-Temperature                   House Code: 51
Channel   : 3            Battery   : 1            
Temperature: 20.90 C      Humidity  : 49 %          Integrity : CHECKSUM

time      : 2022-12-07 20:51:57
model     : Prologue-TH  subtype   : 5             id        : 144
Channel   : 2            Battery   : 1            
Temperature: 20.10 C      Humidity  : 20 %          Button    : 1


time      : 2022-12-07 20:17:19                    brand     : OS
model     : Oregon-v1    SID       : 9
Channel   : 3            Battery   : 1
Temperature: 10.7 C       Integrity : CHECKSUM


time      : 2022-12-07 20:07:46
model     : Hideki-Temperature                     Rolling Code: 11
Channel   : 1            Battery   : 1            
Temperature: 9.4 C        Integrity : CRC

time      : 2022-12-07 20:17:39
model     : Hideki-TS04  Rolling Code: 0
Channel   : 2            Battery   : 1          
Temperature: 19.4 C       Humidity  : 30 %          Integrity : CRC

time      : 2022-12-07 21:07:10
model     : Prologue-TH  subtype   : 5             id        : 141
Channel   : 1            Battery   : 1            
Temperature: 20.50 C      Humidity  : 16 %          Button    : 0





Para mi modelo  TFA-Pool , el test de errores se hace mediante suma,  CHECKSUM.
TFA pool temperature sensor.

10 24 bits frames

    CCCCIIII IIIITTTT TTTTTTTT DDBF

- C: checksum, sum of nibbles - 1
- I: device id (changing only after reset)
- T: temperature
- D: channel number
- B: battery status
- F: first transmission


Es fácil de programar, y en mi caso si los datos son correctos se manda CHECKSUM=1 .

Espero que os haya gustado este artículo, y os recomiendo que probéis las señales recibidas en vuestra casa.
Lo curios del tema, es que también se reciben señales de los sensores de ciertos coches.

model     : Renault      type      : TPMS          id        : 330fb5
flags     : 36           pressure_kPa: 251.2 kPa   temperature_C: 11 C       mic       : CRC

model     : Toyota       type      : TPMS          id        : f13c3038
status    : 128          pressure_PSI: 34.500      temperature_C: 10.000     mic       : CRC

model     : Citroen      type      : TPMS          state     : c2            id        : 0f330778
flags     : 12           repeat    : 3             Pressure  : 233 kPa       Temperature: 15 C         maybe_battery: 51         mic       : CHECKSUM

model     : Nexus-T      House Code: 158
Channel   : 1            Battery   : 1             Temperature: 8.60 C


En este archivo os muestro las señales recibidas en mi casa.

En el programa del arduino he colocado un sensor de presión, por lo que si solo queréis ver los datos del sensor, debéis anular el código correspondiente al BMP180, es comentar 3 líneas.

PROGRAMA


Saludos.
Juan Galaz


Bibliografía:


https://github.com/merbanan/rtl_433
https://triq.org/rtl_433/
rec433.html

martes, 4 de octubre de 2022

Raspberry pi pico, Programación C, Sensores: LDR - DHT22 (AM2302) - BMP180 - 18B20 OLED DS1302

  Página principal

Raspberry pi pico
Programación C
Sensores:
LDR - DHT22 (AM2302) - BMP180 - 18B20
OLED DS1302


Anteriormente había realizado un visualizador de sensores con el ESP32.
Algún tiempo después lo hice en la Raspberry pi pico programándolo en
microPython - PICO4
En este artículo lo realizo con la Raspberry pi pico y programando en C.

El final del montaje queda de la siguiente forma:





sen_p1 y sen_p2
El primer paso es colocar un led a modo de piloto de alimentación, y hacer parpadear el led que viene en la placa.

#include <stdio.h>
#include <pico/stdlib.h>


#define OUTPUT 1
#define INPUT 0
#define HIGH 1
#define LOW 0

void pinMode(unsigned int port, char modo);
void digitalWrite(unsigned int port, char val);
void delay(long t);

#define MILED 25

int main()
{
    stdio_init_all();
    delay(1000);
    printf("-----------------------\n");
    printf("----Hola SENSORES------\n");
    pinMode(MILED, OUTPUT);
    while(1)
    {
      printf("Estado %d\n",0);
      digitalWrite(MILED, LOW);
      delay(1000);
      printf("Estado %d\n",1);
      digitalWrite(MILED, HIGH);
      delay(2000);
    }
}


//---------------I/O----------------
void pinMode(unsigned int port, char modo)
{
    gpio_init(port);
    if(modo==OUTPUT)
        gpio_set_dir(port, GPIO_OUT);
     else
        gpio_set_dir(port, GPIO_IN);
}

void digitalWrite(unsigned int port, char val)
{
    gpio_put(port, val);
}

void delay(long t)
{
    sleep_ms(t);
}

Como me parece más fácil el modo de configurar los puertos de la forma que loa hace arduino , he creado un par de funciones tipo arduino.
A partir de ahora, las funciones se meterán en un fichero ardu.h donde se incluirán las funciones.


sen_p3
En este paso colocamos un sensor de temperatura y humedad

El sensor es el DHT22 o su equivalente AM2302.


#include <stdio.h>
#include <pico/stdlib.h>

#include "ardu.h"

#define MILED 25

//----DHT-----------
#define PIN_DHT 15
unsigned int humedad,temperatura,control;
unsigned char dataSensor[5];
unsigned int ck;
void leerDHT(void);

int main()
{
    stdio_init_all();
    delay(1000);

    printf("----Hola SENSORES------\n");
    pinMode(MILED, OUTPUT);
    while(1)
    {
      leerDHT();
      printf("AM2302_H=%.1f%%   T=%.1f ºC   Control=%d\n",(float)humedad/10,(float)temperatura/10,control);
     
      digitalWrite(MILED, LOW);
      delay(1000);
      digitalWrite(MILED, HIGH);
      delay(2000);
      printf("-----------------------\n");
    }
}


//----------DHT--------------------
void leerDHT(void)
{
  unsigned char n,z,x;
  unsigned char contador1,contador0;
  unsigned char datos[45];
  control=temperatura=humedad=0;
 
  pinMode(PIN_DHT,OUTPUT);
  digitalWrite(PIN_DHT,LOW);
  delay(2);
  digitalWrite(PIN_DHT,HIGH);
  pinMode(PIN_DHT,INPUT);
 
  for(n=0;n<42;n++)
  {
    contador0=contador1=0;
    while(1==digitalRead(PIN_DHT))
    {
      delayMicroseconds(5);
      contador1++;
      if(contador1>250)goto salir;
    }
    while(0==digitalRead(PIN_DHT))
    {
      delayMicroseconds(5);
      contador0++;
      if(contador1>250)goto salir;     
    }
    datos[n]=contador1;   
  }

  z=0;
  x=0;
  for(n=2;n<42;n++)
    {
      dataSensor[z]<<=1;
      if(datos[n]>=contador0) { (dataSensor[z])|=1;}
      x++;
      if(x==8) { x=0;  z++;  }      
    }

  humedad=dataSensor[0];
  humedad<<=8;
  humedad|=dataSensor[1];
  temperatura=dataSensor[2];
  temperatura<<=8;
  temperatura|=dataSensor[3];
  control=dataSensor[4];
salir: 
;
}
//---------------------------------
En este caso he tenido que crear yo las funciones de lectura.
Primero la hice sobre arduino y luego trasladé el código a la Raspberry pi pico.
El paso de una placa a otra fue fácil, no tuve que hacer ningún cambio.



El protocolo
1-wire, es bastante sencillo de programar.

----Hola SENSORES------
AM2302_H=39.4%   T=22.5 ºC   Control=108
-----------------------
AM2302_H=40.7%   T=22.5 ºC   Control=121


sen_p4
En este paso ponemos un sensor de luz tipo LDR,
y leemos el valor mediante un conversor ADC.

...
#include "hardware/gpio.h"
#include "hardware/adc.h"
...

//---Voltios LDR---
uint16_t result;
...

main()
{
...
 //INIT --ADC-- 
    adc_init();
    adc_gpio_init(28);    // Select ADC input 0 (GPIO26)
    adc_select_input(2);
    const float conversion_factor = 3.3f / 4096;
...

while(1)
    {
....
      result = adc_read();
      printf("LDR-> RAW=%d, voltaje=%f V\n", result, result * conversion_factor);
...
    }
}
En este caso solo  muestro el código correspondiente a la conversión A/D.
Este código no tiene demasiado explicación, configuración pin 28, y lectura del valor.

----Hola SENSORES------
AM2302_H=38.8%   T=23.5 ºC   Control=112
LDR-> RAW=402, voltaje=0.323877 V
-----------------------
AM2302_H=40.1%   T=23.5 ºC   Control=125
LDR-> RAW=403, voltaje=0.324683 V
-----------------------


sen_p5
En este paso colocamos un sensor de presión que además dispone de un sensor de temperatura.

El sensor viene en un módulo BMP180, los datos se mandan mediante el bus I2C.


...
#include "pico/binary_info.h"
#include "hardware/i2c.h"

#include <math.h>
...

//----I2C-------
i2c_inst_t *XXi2c = i2c0;        //i2c1 para 26-27   12c0 para 0-1 ...
#define    SDA_PIN 0
#define    SCL_PIN 1
 
#define  BMP180_ADDR 0x77 // 7-bit address
#define  BMP180_WRITE_MODE _u(0xFE)
#define  BMP180_READ_MODE _u(0xFF)
#define     BMP180_REG_CONTROL 0xF4
#define     BMP180_REG_RESULT 0xF6
#define     BMP180_COMMAND_TEMPERATURE 0x2E

void bmpGetData(void);
void bmpComand(uint8_t cmd);
int bmpInput(char address);
void getVarBMP(void);
void scanI2C(void);

long Temperatura, Presion, PresionBase;
...

main()
{
...
//INIT --I2C--
    printf("SDA=%d  SDL=%d \n", SDA_PIN, SCL_PIN);
    i2c_init(i2c_default, 100000);
    gpio_set_function( SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function( SCL_PIN, GPIO_FUNC_I2C);
    gpio_pull_up( SDA_PIN);
    gpio_pull_up( SCL_PIN);
    bi_decl(bi_2pins_with_func( SDA_PIN,  SCL_PIN, GPIO_FUNC_I2C));
   
    scanI2C();  
    getVarBMP();
    delay(50);
    bmpGetData();    //Calcula la presión base......
    PresionBase=Presion;
...

while(1)
    {
....
     bmpGetData();
     printf("BMP_TempGRADOS=%0.2f ºC\n",(float)Temperatura/100);
     printf("BMP_Presion=%0.2f bares\n",(float)Presion/100); 
...
    }
}


Solo muestro el código correspondiente a la comunicación I2C y al cálculo de la presión.
En este caso el código del arduino es totalmente diferente al de la Raspberry.
Me costó mucho tiempo y trabajo el descubrir la diferencia entre los tipos de enteros.
En arduino el tamaño de int es de 16bit, en la raspberry es de 32bit.
Y se me ocurrió utilizar el tipo sort, y resulto erroneo su tamaño, por lo que lo mejor es utilizar int16_t o uint16_t.
Hay que tener en presente que existen varios I2C en la raspberry y debemos especificar el que usamos.
Por ejemplo: i2c1 para 26-27  e  12c0 para 0-1 .........
Aunque la librería es mia, he utilizado algún código de otros, en bibliografía  pongo las fuentes.
-----------------------
AM2302_H=41.0%   T=23.7 ºC   Control=136
LDR-> RAW=915, voltaje=0.737183 V
BMP_TempGRADOS=22.21 ºC
BMP_Presion=934.37 bares
-----------------------

Señales del bus I2C cuando lee datos, funcion void bmpGetData(void)

sen_p6
En este paso colocamos un sensor de temperatura 18B20.

Este chip se comunica mediante una sola línea de datos, y si se quiere se puede utilizar solo dos lineas para hacer funcionar el sensor.
Además se pueden colocar varios chip en paralelo, que se podrán leer sus temperaturas independientemente.


//----DS18B20------
#define ONE_WIRE_PIN 22
void onewire_reset();
void onewire_write(unsigned char data);
int onewire_read();
int ds1820_read();

float temp18B;
...

main()
{

while(1)
    {
....
      temp18B=ds1820_read();
      printf("DS18b20_Temp=%0.2f ºC\n",temp18B/10);
...
    }
}


//-------------ONEWIRE-------------
void onewire_reset()
{
    pinMode(ONE_WIRE_PIN,OUTPUT); digitalWrite(ONE_WIRE_PIN,LOW);  
    delayMicroseconds(500);
    digitalWrite(ONE_WIRE_PIN,HIGH);  pinMode(ONE_WIRE_PIN,INPUT);
    delayMicroseconds(500);                
    digitalWrite(ONE_WIRE_PIN,HIGH);  pinMode(ONE_WIRE_PIN,INPUT);
}


void onewire_write(unsigned char data)
{
    unsigned char count;
    for(count = 0; count < 8; ++count)
    {
        pinMode(ONE_WIRE_PIN,OUTPUT); digitalWrite(ONE_WIRE_PIN,LOW);
        delayMicroseconds(2);              
        if(data & 1)
          {  digitalWrite(ONE_WIRE_PIN,HIGH);  }
          else
          {  digitalWrite(ONE_WIRE_PIN,LOW);   }
        data>>=1;

        delayMicroseconds(60);               
        digitalWrite(ONE_WIRE_PIN,HIGH);  pinMode(ONE_WIRE_PIN,INPUT);
        delayMicroseconds(2);                // for more than 1us minimum.
    }
}


int onewire_read()
{
    unsigned char count;
    unsigned char data;
    for(count = 0; count < 8; ++count)
    {
        data>>=1;
        pinMode(ONE_WIRE_PIN,OUTPUT);
        digitalWrite(ONE_WIRE_PIN,LOW);
        delayMicroseconds(2);             
        pinMode(ONE_WIRE_PIN,INPUT);
        delayMicroseconds(10);              
        if(digitalRead(ONE_WIRE_PIN)&1 )  {  data|=128;  }
        delayMicroseconds(50); 
    }
    delayMicroseconds(100);
    return data;
}

int ds1820_read()
{
    unsigned char busy=0, tempL, tempH; 
    long  temp;
   
    onewire_reset();
    onewire_write(0xCC);              
    onewire_write(0x44);  
    delay(10);
    onewire_reset();
    onewire_write(0xCC);           
    onewire_write(0xBE);           
   
    tempL = onewire_read();
    tempH = onewire_read();
 
    temp=tempH; temp<<=8; temp|=tempL;
    //Serial.print(" HEX ");Serial.print(temp,HEX);
    temp=(temp*625)/1000;
  return(temp); 
}

1-Wire es un protocolo de comunicaciones en serie diseñado por Dallas Semiconductor.
Está basado en un bus, un maestro y varios esclavos de una sola línea de datos en la que se alimentan.
En este protocolo se pueden colocar varios 18B20 en paralelo, por lo cual debería colocar una función de detección de elementos.
Otra forma es saber la identificación en ROM de cada elemento.
En mi caso uno de los 18B20 tiene la siguiente dirección:  byte addr[8]={0x28,0xDC,0x5C,0x16,0xA8,1,0x3C,0x28};
Esto me hubiese costado mucho, además solo voy a colocar un 18B20, por lo que utilizo un modo de lectura diferente.

SKIP ROM [CCh] Este comando puede ahorrar tiempo en un sistema de bus de caída única al permitir que el bus maestro acceda al funciones de memoria sin proporcionar el código ROM de 64 bits. Si hay más de un esclavo presente en el bus y se emite un comando de lectura después del comando Saltar ROM, se producirá una colisión de datos en el bus como múltiples esclavos transmiten simultáneamente (los pulldowns de drenaje abierto producirán un resultado AND cableado). www.dalsemi.com

-----------------------

AM2302_H=42.3%   T=24.7 ºC   Control=159

LDR-> RAW=236, voltaje=0.190137 V
BMP_TempGRADOS=23.30 ºC
BMP_Presion=933.90 bares
-----------------------


sen_p7
Por último colocamos un visualizardor tipo OLED
, el modelo SSD1306.
Lo bueno de colocar este modelo es que se conecta en el bus I2C, lo que resulta muy práctico y sencillo.

...
#include "ole.h"
char miBuffer[40];
...
main()
{
...
while(1)
    {
...
      xclearDisplay();
      StringAT(0,0,"--SETA43--");
     
      sprintf(miBuffer,"LDR=%d  %0.3fV",result,result * conversion_factor);
      StringAT(0,1,miBuffer);
     
      sprintf(miBuffer,"DHT_Hum. %.1f %c",(float)humedad/10,37);
      StringAT(0,2,miBuffer);
     
      sprintf(miBuffer,"DHT_Temp. %.1f %cC",(float)temperatura/10,127);
      StringAT(0,3,miBuffer);
     
      sprintf(miBuffer,"DS18b20_=%0.2f %cC",temp18B/10,127);
      StringAT(0,4,miBuffer);
     
      sprintf(miBuffer,"BMP_Pres.=%0.1f b ",(float)Presion/100);
      StringAT(0,5,miBuffer);
      sprintf(miBuffer,"BMP_Temp.=%0.1f %cC",(float)Temperatura/100,127);
      StringAT(0,6,miBuffer);
...
    }
}
Para utilizar el OLED, he empleado una biblioteca mía que realicé en arduino hace años.
Es simple de utilizar, solo hay que añadir el fichero ole.h , no tiene muchas funciones, pero hace su trabajo.

Cuando empecé a programar la raspberry pi pico, pensé que la transición sería más fácil, pero no fue así.
La cantidad de bibliotecas que existe en arduino no existen en raspberry.
El paso de programas entre arduino y rasberry no es inmediata, y muchos de los programas y biblitecas no funcionan,
Debemos pensar que los int en arduino son de 16bit, y en raspberry es de 32bit, esto genera muchos problemas.
Si queremos utilizar enteror de 16bit en raspberry, se debe utilizar
int16_t o uint16_t.

PROGRAMAS

Espero que este montaje os haya parecido interesante.

Saludos.

Juan Galaz



Bibliografía:

https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf
https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf
https://www.puntoflotante.net/termometro.htm
espgrs.html

28/02/2016 - Arduino - Predicción del tiempo. GY-68 - BMP-180.  Predicción
21/02/2016 - Arduino power low - Termómetro máximos y mínimos con gráfica - DS18B20 LCD Nokia PCD8544. Tempe
09/02/2016 - Arduino -Barómetro - Termómetro. GY-68 -  BMP-180. Parte 2 (librería propia). ArduBer
03/02/2016 - Arduino -Barómetro - Termómetro. GY-68 -  BMP-180. Parte 1.  ArduBar

lunes, 24 de mayo de 2021

ARDUINO - SENSORES - BMP180- XFW-HX711.

ARDUINO - SENSORES

BMP180
XFW-HX711


El otro día me llego dos módulos que había pedido, el BMP180 (un viejo conocido con el cual había realizado 3 proyectos, y el XFW-HX711, un sensor  de peso.
Quería añadir los dos módulos al ESP32, pero quería antes probarlos en un arduino nano.

En primer lugar he realizado el montaje del sensor de presión, que muestra los datos en un OLED y en el terminal serie.
Para este montaje he utilizado el antiguo montaje :
Barómetro - Termómetro. GY-68 -  BMP-180. Parte 2 (librería propia). ArduBer , pero adaptándolo al OLED.
Como se puede observar lo he alimentado con 3V3 , para probar si funcionaría con el ESP32, aunque funciona también a 5V.
Lo bueno de este proyecto es que utilizan los dos módulos el protocolo I2C, lo que facilita mucho el diseño.




PROGRAMA


Como ya tenía montado el circuito de sensor de presión, he añadido el sensor de peso.
Como tutorial he seguido los pasos de:https://naylampmechatronics.com/blog/25_tutorial-trasmisor-de-celda-de-carga-hx711-balanza-digital.html
He añadido una línea donde figura el peso en gramos.
Empezamos explicando un poco el funcionamiento del módulo de pesaje.

Cuando un conductor se estira, su resistencia aumenta. Cuando está comprimido, su resistencia disminuye.
A estas piezas de metal la llamaremos Celdas De Carga.
Esta resistencia se mide con un convertidor A/D de 24bits , HX711, que transmite los dados mediante protocolo serie propio al arduino.

 



Una vez que tenemos montado el circuito, debemos calibrarlo.
El método es utilizar un objeto que sepamos su peso, yo he utilizado uno que antes había pesado en una báscula.
En mi caso había utilizado dos POWER_BANK que en total pesaban 133 grs.
Lo ideal es utilizar un peso que se ajuste al máximo de peso de la celda de carga, no es mi caso.
Ahora con el siguiente programa mido el valor que nos devuelve el módulo.

#include "HX711.h"
const int DOUT=2;
const int CLK=3;

HX711 balanza;
void setup() {
  Serial.begin(9600);
  balanza.begin(DOUT, CLK);
  Serial.print("Lectura del valor del ADC:t");
  Serial.println(balanza.read());
  Serial.println("No ponga ningún objeto sobre la balanza");
  Serial.println("Destarando...");
  balanza.set_scale(); //La escala por defecto es 1
  balanza.tare(20);  //El peso actual es considerado Tara.
  Serial.println("Coloque un peso conocido:");
}

void loop() {

  Serial.print("Valor de lectura: t");
  Serial.println(balanza.get_value(10),0);
  delay(100);
}


Con un peso de 133 grs nos proporciona una medida de 261425 .
Con el dato obtenido  hacemos un cálculo:
    261425:0.133 grs =1965601
El valor obtenido de la operación lo colocamos en:

    #define AJUSTE 1965601
    balanza.set_scale(AJUSTE);

Con esto ya podemos medir el peso de un objeto.
Debemos saber que cuando se reinicia el programa toma un primer peso que coloca como tara, para luego restarlo del peso total.



Peso de una POWER-BANK de 65grs, que corresponde al peso real.




Detalle de la celda de carga.



Peso de dos monedas de 50 CENT, que corresponde al valor real.
El circuito funciona muy bien, con una precisión alta.

Espero que les guste este proyecto.

PROGRAMA Y LIBRERÍA

Saludos.
Juan Galaz

Bibliografía:
https://naylampmechatronics.com/blog/25_tutorial-trasmisor-de-celda-de-carga-hx711-balanza-digital.html
28/02/2016 - Arduino - Predicción del tiempo. GY-68 - BMP-180.  Predicción
21/02/2016 - Arduino power low - Termómetro máximos y mínimos con gráfica - DS18B20 LCD Nokia PCD8544. Tempe
09/02/2016 - Arduino -Barómetro - Termómetro. GY-68 -  BMP-180. Parte 2 (librería propia). ArduBer
03/02/2016 - Arduino -Barómetro - Termómetro. GY-68 -  BMP-180. Parte 1.  ArduBar



viernes, 23 de abril de 2021

ESP32 - SENSORES - OLED SSD1306Z - Servidor WEB

ESP32-  SENSORES

OLED  SSD1306Z
Servidor WEB
Temperatura/Humedad  DHT 22  (AM2302)
Temperatura 18B20
LUZ LDR


Este proyecto está realizado para poner en práctica un montón de montajes juntos, y practicar con el ESP32.
Está formado por 3 sensores, luz (LDR), temperatura y humedad ( DHT 22  (AM2302) ), sensor de temperatura (18B20).
Los datos se representan en un OLED (SSD1306Z) , además de tener un servidor WEB donde también se visualizan los datos en cualquier navegador.

Esquema eléctrico.


Circuito montado.


Pantalla OLED.


Datos en un navegador.

La construcción de este montaje fue  añadiendo y rediseñando montajes anteriores realizados con placas de arduino.

El primer paso era colocar la pantalla OLED 
SSD1306Z utilizando una librería propia que se añade con:
    #include "olex.h"
    #include <Wire.h>

El primer contacto con esta pantalla la tuve en el montaje arolet.html donde cree la librería.

Seguí añadiendo una LDR, que solo se necesita un conversor A/D . He utilizado el PIN34 (ADC6) , aunque probé con otros pins, pero cuando añadí el servidor web, funcionaban mal. Este funciona PIN perfectamente.

Como primer sensor de temperatura he utilizado el DHT 22  (AM2302) , además proporciona porcentaje de humedad. Para esto utilizo la librería  #include "DHT.h"  de   https://learn.adafruit.com/dht   .
Este sensor lo he empleado bastante por su bajo precio. ar433.html   raspb.html.

Como segundo sensor de temperatura he utilizado el 18B20 , muy barato y fácil de usar, junto con la posibilidad de poner varios en la misma línea de comunicaciones. Para su funcionamiento he utilizado una función creada por mi hace varios años int getTemp(void) . Este sensor lo he utilizado en varios montajes:  colorl.html , arwifi.html .

Como también quiero tener un reloj con la hora, he aprovechado el ejemplo que viene con el ESP32, SimpleTime.
En este ejemplo se toma la fecha y hora del servidor de internet pool.ntp.org , para luego ajustarnos a nuestra zona horaria. En el caso de la zona horaria de España  es +1h , o 3600 segundos.
En este caso también he añadido algo mio, los días de la semana.
En el ejemplo SimpleTime utilizaba en su configuración la IP dinámica que proporciona el router. Como a mi no me gustaba que cambiase la IP cada vez que se conectase, la he cambiado a IP estática, en mi caso 192.168.1.150
Si se quiere seguir utilizando la IP dinámica, comentar la línea:  #define IP_STATIC

Una vez montados todos los sensores, y ver que sus datos se representan bien en el OLED, nos toca crear el servidor WEB.
En un montaje anterior con el ESP8266  espb.html , había creado un servidor para encender y apagar LED.
En este caso lo he adaptado para visualizar los datos de sensores en un navegador.

Este proyecto me ha servido para ponerme en contacto con el ESP32, y ver todas sus posibilidades.
Espero que les haya gustado.


PROGRAMAS Y LIBRERÍAS

Saludos.
Juan Galaz

Bibliografía:
https://randomnerdtutorials.com/esp32-dht11-dht22-temperature-humidity-sensor-arduino-ide/
https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
https://www.profetolocka.com.ar/2020/07/09/programando-el-esp-32-con-el-arduino-ide/
https://www.prometec.net/presentando-el-esp32/


 

miércoles, 5 de junio de 2019

Sensores-Tratamiento de datos metereológicos con Python - Generar página web con temperaturas

Página principal

Sensores

Tratamiento de datos metereológicos
con
Python
Generar página web de temperaturas


Este artículo es una continuación de una serie de artículos sento.html , oracam.html, serora.html .
El propósito de este artículo es capturar los datos que manda un módulo ( en este caso un arduino con sensores) a través del puerto serie ( /dev/ttyUSB0', '/dev/ttyUSB1','/dev/ttyACM0','/dev/ttyACM1'....) y procesarlos para guardarlos en un fichero ( ejemplo: Temp2019_06_04.csv ).
Además de todo lo anterior, creará una página web donde se visualizarán los datos a través de un servidor web.
No soy muy partidario de Python, pero al estar muy implantado en todas la plataformas del tipo Raspberry o Orange-PI,  que es donde se va montar el servidor, la programación se va a realizar en este lenguaje. Deberéis perdonar lo mal que sé programar en Python, soy novato en este lenguaje de programación, normalmente programo en C/C++ o Básic.

Lo primero es saber el formato que tienen los datos que transmite el modulo de sensores (arduino) a través del puerto serie.
Formato de datos
INICIO
Temperatura,14.0
Humedad,32
#presion,923
#Temperatura,26.1
FINAL
Como podéis observar el formato es bastante simple:
Dos cadenas INICIO y FINAL, y en medio datos.
Cada línea de datos está compuesto del tipo de dato y el valor, separados por una coma.

Lo primero que hace el programa es buscar el módulo en todos los puertos serie posibles.
Al escanear los puertos, si existe el módulo, responderá el módulo con la palabra SENSORTOTAL empezándose a ejecutarse la rutina principal del programa.

En la rutina principal del programa, se lee continuamente el puerto serie hasta que encuentra datos a procesar.
Cuando encuentra datos, los almacena en las variables  dTemperatura, dHumedad, dPresion.
La visualización en tiempo real se realiza en consola.


Cada minuto se van almacenando las variables en un fichero con el formato TempAÑO_MES_DIA.csv  .
Ejemplo : Temp2019_06_04.csv
Esto se realiza con los comandos en python:
nombreFichero="Temp20"+time.strftime("%y_%m_%d")+".csv"
f = open(nombreFichero,'a')
f.write(time.strftime("%H,%M"))
f.write(',')
f.write(dTemperatura+','+dHumedad+','+dPresion+','+'\n')
f.close()

Como podéis observar cada día se crea automáticamente un fichero de datos.
Formato del fichero de datos metereológicos
00,00,21.6,25,924,
00,01,21.6,25,924,
00,02,21.6,25,924,
00,03,21.6,25,924,
00,04,21.5,25,924,
Lo bueno de este formato es que se puede importar con una hoja de cálculo para su tratamiento.

El programa, cada 41 segundos o cada vez que recibe datos del módulo de sensores, actualiza el fichero  index.html que es el que se representa en la página web.
El código python que se utiliza para crear la página web es el siguiente:
            print "Crear pagina"
            fw = open('index.html','w')

            mensajeWeb = """
<html>
<head>
    <meta http-equiv="refresh" content="115">
    <title>PALENCIA</title>
</head>
<body bgcolor="#ffff99">
<h2>Palencia, Spain
<hr size="2" width="100%">
<img  alt="" src="web.jpg" height="480" width="640"><br>
<hr size="2" width="100%">
"""
            mensajeWeb = mensajeWeb + time.strftime("%d/%m/%y") +"  "+ time.strftime("%H:%M:%S")
            mensajeWeb = mensajeWeb + """<br>"""
            mensajeWeb = mensajeWeb + mensaje
            mensajeWeb = mensajeWeb + """
<h2><a href="gradia.html">GRAFICOS</a><br>
<img  alt="" src="mapa.png" >
</h2>           
</body>
</html>"""

            fw.write(mensajeWeb)
            fw.close()
Como había veces que los navegadores utilizaban la cache, y para que se actualizase cada 2 minutos, añadí en la cabecera del fichero html :  <meta http-equiv="refresh" content="115">
Con lo que obliga al navegador a actualizar automáticamente la página web.
El resultado es el siguiente:


Podéis comprobar el resultado en mi página:
http://seta43.duckdns.org/seta/webcam/index.html
http://seta43.ddns.net/seta/webcam/index.html
El resultado no lo he hecho muy vistoso a propósito, para hacer mas legible el código, el que quiera lo puede mejorar retocando el código html.

Para ejecutar el programa en python he creado un programa en bash llamado app_python.sh que se ejecuta cuando se inicia el ordenador.
app_python.sh
#!/bin/bash
cd /home/seta/www/webcam
xterm -e "python camtem4.py"
He de reconocer que en mi placa OrangePI no consigo que se inicie automáticamente, aunque en el ordenador PC se inicie perfectamente, y mira que lo he revisado, pero nada, lo debo iniciar yo, por lo cual si se va la luz en el servidor, debo lanzarlo yo remotamente.

PROGRAMA


Saludos.
Juan Galaz


Bibliografía:
https://pyserial.readthedocs.io/en/latest/
sento.html
predi.html
raspb.html
arterec.html
tm16tem.html

lunes, 29 de abril de 2019

Sensores 18B20 LDR BMP180 DHT22, Arduino - Gambas - Python

Página principal


Sensores

18B20 LDR BMP180 DHT22

Arduino - Gambas - Python


Debía realizar un circuito electrónico para añadir a una página web donde indicara la temperatura ambiente.
La idea era solo colocar un sensor de temperatura 18B20, pero se me ocurrió añadir mas sensores.
En este circuito coloco varios sensores:
-18B20 sensor de temperatura.
-LDR sensor de luz.
-BMP180 sensor de presión y temperatura.
-DHT220 sensor de temperatura y humedad. (he utilizado el equivalente AM2302)


Todos los datos de estos sensores se transmiten al PC mediante el terminal serie.

Circuito montado.


Circuito.

Para la representación de los datos he utilizado dos programas.
El primero está realizado en Gambas (VB para linux).
El segundo realizado en Python.
En ambos programas busca la placa de sensores dentro de todos los posibles puertos serie.
Si encuentra el módulo de sensores los representa en pantalla.
Toda la programación se ha realizado en el entorno Linux con la distribución Debian 9.
La información de sensores se manda cada 5 segundos.
Su transformación para que funcionase en Windows en el caso de Phyton es fácil, solo cambiar la lista de dispositivos serie.

Programa Gambas (VB para linux).


Programa Phyton.

El montaje es perfecto para probar sensores.
Si no tenéis alguno de los sensores, deberéis anular el código correspondiente al sensor en el programa del arduino.

PROGRAMAS

VIDEO





Saludos.
Juan Galaz


Bibliografía:
predi.html
raspb.html
arterec.html
tm16tem.html