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

jueves, 23 de octubre de 2025

CONECTAR 2 DISPLAYS OLED SSD1306 A UN ARDUINO NANO


CONECTAR 2 DISPLAYS OLED SSD1306 A UN ARDUINO NANO
Alfredo Segura, México. Octubre de 2025.


El experimento fue largo y falto de información por parte de la comunidad y del propio foro de Arduino. Se trata de conectar 2 displays OLED SSD1306 (128x64) a un Arduino mediante el bus I2C, para lo cual procedí a cambiar de lugar en uno de ellos, el resistor que define la ADDRESS del mismo dispositivo, de tal manera que pueda ser detectado y utilizado por el I2C del Nano.

Esta nueva ADDRESS será la 0x3D que, de acuerdo con el datasheet del SSD1306, corresponde a la línea D/C (Data / Control) del chip interno del OLED, como se muestra en las siguientes imágenes:

Con estos arreglos, tenemos un OLED con la ADDRESS 0x3C original y otro con la 0x3D, listos para que el Arduino Nano los reconozca.

En el IDE de Arduino existe en el menú Archivo -> Ejemplos -> Wire -> Wire Scan que es un código que nos permite, previamente grabado en el Arduino Nano, observar los dispositivos I2C conectados. Así que ponemos ambos displays OLED (uno de ellos ya modificado) y efectivamente observamos en el Monitor Serial a 9600 bps, que aparecen las direcciones 0x3C y 0x3D.

Procedemos a teclear nuestro código para que el Arduino Nano nos controle ambos displays, mostrando en cada uno de ellos mensajes diferentes:

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

. . .

// Damos nombres diferentes a las instancias de Adafruit_SSD1306:

Adafruit_SSD1306 oleddisplay(ancho, alto, &Wire, -1);

Adafruit_SSD1306 displayoled(ancho, alto, &Wire, -1);

// En el setup, iniciamos Wire y verificamos que sean detectados ambos display:

Void setup() {

. . .

if (!oleddisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 0x3C

Serial.println("No está respondiendo el OLED 0x3C...");

for(;;);

}

Serial.println("Respondiendo correctamente el OLED 0x3C...");

if (!displayoled.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // 0x3D

Serial.println("No está respondiendo el OLED 0x3D...");

for(;;);

}

Serial.println("Respondiendo correctamente el OLED 0x3D...");

. . .


Y es precisamente aquí , que al tratar de detectar el OLED SSD1306 con ADDRESS 0x3D, se queda colgado el programa y en el Monitor Serial aparece la leyenda: “No está respondiendo el OLED 0x3D...”

Por supuesto podemos buscar la causa de este problema, sobre el cual yo analicé los archivos Adafruit_GFX.h y Adafruit_GFX.cpp y no encontré algo obvio sobre el mal funcionamiento.

Sin embargo, si al OLED modificado, se le devuelve el resistor a su posición original, para que vuelva a tener la ADDRESS 0x3C y se conectan ambos al Nano, los mensajes que se envían vía I2C, aparecen en los dos displays idénticos.

Buscando en Internet, alguien propuso usar un demultiplexor para lograr separar los comandos a un display y al otro, con los pines adicionales del Nano para controlar dicho demultiplexor. Lo planteó al foro de Arduino pero fue desanimado de hacerlo, y en su lugar se le sugirió usar otro circuito integrado que ya viene ex profeso para ese fin, el PCA9548.

Como había que conseguir dicho circuito integrado y yo tenía el CD4066B que consiste de 4 switches analógicos bidireccionales, me decidí hacer mi proyecto con este chip, del cual muestro su imagen:

Conectado este circuito integrado al Arduino Nano y a los displays OLED SSD1306, tenemos el diagrama final:

Finalmente el circuito completo montado en un protoboard, ha quedado funcional:

PROGRAMA ARDUINO



Alfredo Segura, México. Octubre de 2025.



sábado, 8 de marzo de 2025

Arduino RELOJ DS1307 BMP280 - AHT20 - OLED SDD1306 - AT24C32

  Página principal

Arduino
RELOJ DS1307

BMP280 - AHT20 - DS1307 -
OLED SDD1306 - AT24C32

Otro montaje de relojes, esta vez montado con un DS1307.
En esta ocasión utilizo el sensor de presión BMP280, junto con el sensor de temperatura y humedad AHT20.
Además utilizo la memoria
AT24C32 para registrar los valores diarios de temperatura, humedad, presión.
Se toman 4 valores por hora, en los minutos, 0, 15, 30, 45.
Con la memoria que tiene la  EEPROM 24C32 , se podría almacenar  10 días, pero eso lo dejo para el que lo quiera hacer.
La toma de los diferentes sensores se toma cada 5 segundos, y esta se representa en la pantalla OLED y se transmite al terminal.
Para visualizar los valores diarios almacenados en la memoria, se debe escribir en el terminal serie la orden "print".
Para modificar la hora y la fecha, he añadido dos botones, con uno seleccionas el valor que quieres cambiar, y con el otro incrementas el valor.
He tenido algún problema con el BMP280, se bloqueaba aleatoriamente sin motivo. Para arreglar esto, he reducido la velocidad del reloj del bus I2C y he colocado un condensador (
100uF 5V) en la alimentación.

Los pines del dibujo del BMP280 no corresponden a los pines reales, mirar en vuestro caso cuales son.



Respuesta de la placa cuando mandas la orden "print"


    Programa        Librería

Espero que os haya gustado este pequeño circuito.


Saludos.
Juan Galaz



Bibliografía:

https://github.com/adafruit/RTClib
https://naylampmechatronics.com/blog/52_tutorial-rtc-ds1307-y-eeprom-at24c.html


lunes, 2 de diciembre de 2024

RELOJ con ds1307 - OLED - ROTARY ENCODER - módulo 12E , HW-364B - Raspberry pi pico

He realizado varios montajes de reloj con el DS1307. 

El primero fue idea de Alfredo Segura, Querétaro, México, septiembre de 2024.

-  CONTRIBUCIÓN - RELOJ DS1307 -Arduino - OLED - Rotary Encoder. RELOJ_0

 

Luego me animé a hacer el mio con los diferentes microcontroladores. 

- Arduino - OLED - Rotary Encoder. RELOJ_SETA

- Raspberry pi pico - OLED - Rotary Encoder.    RELOJ_SETA_2

- ESP8266  , modulo 12E , HW-364B, OLED - Rotary Encoder. RELOJ_SETA_1
 

 

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

viernes, 2 de septiembre de 2022

Raspberry pi pico - Programación microPython - Sensores

  Página principal

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



Anteriormente había realizado un visualizador de sensores con el ESP32.
En este artículo lo realizo con la Raspberry pi pico y programando en microPython.
Todo el montaje lo realizo en pasos, y grabado en vídeo, paso a paso.

El final del montaje queda de la siguiente forma:



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

# SETA43
# seta43.duckdns.org
# seta43.blogspot.com
# Palencia / España
# 31-08-2022

import machine
import utime

led = machine.Pin(25, machine.Pin.OUT)

while True:
    led.value(0)
    utime.sleep(0.5)
    led.value(1)
    utime.sleep(0.5)


En este paso colocamos un sensor de temperatura y humedad
El sensor es el DHT22 o su equivalente AM2302.

# SETA43
# seta43.duckdns.org
# seta43.blogspot.com
# Palencia / España
# 31-08-2022

import machine
import utime

led = machine.Pin(25, machine.Pin.OUT)

from DHT22 import DHT22
from machine import Pin

dht_sensor=DHT22(Pin(15),dht11=False)

while True:
    #--DHT22--------------------------------------------   
    T, H = dht_sensor.read()
    if T is None:
        print("Error en el sensor!")
    else:
        print("Sensor DHT22->","{}ºC  {}%".format(T,H))

    led.value(0)
    utime.sleep(0.5)
    led.value(1)
    utime.sleep(0.5)


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

# SETA43
# seta43.duckdns.org
# seta43.blogspot.com
# Palencia / España
# 31-08-2022

import machine
import utime

led = machine.Pin(25, machine.Pin.OUT)

from DHT22 import DHT22
from machine import Pin

dht_sensor=DHT22(Pin(15),dht11=False)

analog_value = machine.ADC(28)


while True:
    #--DHT22--------------------------------------------   
    T, H = dht_sensor.read()
    if T is None:
        print("Error en el sensor!")
    else:
        print("Sensor DHT22->","{}ºC  {}%".format(T,H))
       
    #--LDR--------------------------------------------
    reading = analog_value.read_u16()    
    print("LDR-> ADC: ",reading)   

    led.value(0)
    utime.sleep(0.5)
    led.value(1)
    utime.sleep(0.5)


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.
Con este sensor se puede calcular la altura.

# SETA43
# seta43.duckdns.org
# seta43.blogspot.com
# Palencia / España
# 31-08-2022

import machine
import utime
from bmp180 import BMP180
from machine import I2C, Pin

led = machine.Pin(25, machine.Pin.OUT)

from DHT22 import DHT22
from machine import Pin

dht_sensor=DHT22(Pin(15),dht11=False)

analog_value = machine.ADC(28)

i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=200000) 
bmp180 = BMP180(i2c)
bmp180.oversample_sett = 2
baseline = bmp180.pressure/100
ALTURA = 790

print ("Doble sensor DHT22 y DS18x20")
#Write in cmd found addresses

i2cScan = i2c.scan()
counter = 0
for i in i2cScan:
    print('I2C Address ' + str(counter) + '      : '+hex(i).upper())
print ("**************************")
#---------------


while True:
    #--DHT22--------------------------------------------   
    T, H = dht_sensor.read()
    if T is None:
        print("Error en el sensor!")
    else:
        print("Sensor DHT22->","{}ºC  {}%".format(T,H))
       
    #--LDR--------------------------------------------
    reading = analog_value.read_u16()    
    print("LDR-> ADC: ",reading)
   
    #..BMP180---------------------------------------------   
    temperatura = bmp180.temperature
    presion = bmp180.pressure/100
    alt2=44330.0* (1-pow(presion/baseline,1/5.255) )   
    alt2=ALTURA+alt2
       
    alt2=round(alt2)
    temperatura=round(temperatura,1)
    presion=round(presion)
           
    print("Tem_BMP180=",temperatura,"ºC Presion=", presion," ALTITUD=",alt2)

    led.value(0)
    utime.sleep(0.5)
    led.value(1)
    utime.sleep(0.5)


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.
El esquema solo utilizo un sensor, en la practica utilizo 2 chip con sus respectivas lecturas.

# SETA43
# seta43.duckdns.org
# seta43.blogspot.com
# Palencia / España
# 31-08-2022

import machine
import utime
from bmp180 import BMP180
from machine import I2C, Pin
import onewire, ds18x20, time

led = machine.Pin(25, machine.Pin.OUT)

from DHT22 import DHT22
from machine import Pin

dht_sensor=DHT22(Pin(15),dht11=False)

analog_value = machine.ADC(28)

i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=200000) 
bmp180 = BMP180(i2c)
bmp180.oversample_sett = 2
baseline = bmp180.pressure/100
ALTURA = 790

print ("Doble sensor DHT22 y DS18x20")
#Write in cmd found addresses

i2cScan = i2c.scan()
counter = 0
for i in i2cScan:
    print('I2C Address ' + str(counter) + '      : '+hex(i).upper())
print ("**************************")
#---------------

ds_pin = machine.Pin(22)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()

while True:
    #--DHT22--------------------------------------------   
    T, H = dht_sensor.read()
    if T is None:
        print("Error en el sensor!")
    else:
        print("Sensor DHT22->","{}ºC  {}%".format(T,H))
       
    #--LDR--------------------------------------------
    reading = analog_value.read_u16()    
    print("LDR-> ADC: ",reading)
   
    #..BMP180---------------------------------------------   
    temperatura = bmp180.temperature
    presion = bmp180.pressure/100
    alt2=44330.0* (1-pow(presion/baseline,1/5.255) )   
    alt2=ALTURA+alt2
       
    alt2=round(alt2)
    temperatura=round(temperatura,1)
    presion=round(presion)
           
    print("Tem_BMP180=",temperatura,"ºC Presion=", presion," ALTITUD=",alt2)
   
    #--DS18B20--------------------------------------------
    ds_sensor.convert_temp()
    time.sleep_ms(750)
    x=0
    for rom in roms:
        #print ("Sensor=",x,"  ",rom,"  Temperatura=",ds_sensor.read_temp(rom))
        print ("Sensor_DS18B20_nº",x,"  ","  Temperatura=",ds_sensor.read_temp(rom))
        x=x+1
   
    print("---------------------")
    led.value(0)
    utime.sleep(0.5)
    led.value(1)
    utime.sleep(0.5)


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.

# SETA43
# seta43.duckdns.org
# seta43.blogspot.com
# Palencia / España
# 31-08-2022

import machine
import utime
from bmp180 import BMP180
from machine import I2C, Pin
import onewire, ds18x20, time

from DHT22 import DHT22
from machine import Pin
from ssd1306 import SSD1306_I2C

led = machine.Pin(25, machine.Pin.OUT)

dht_sensor=DHT22(Pin(15),dht11=False)

analog_value = machine.ADC(28)

i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=200000) 
bmp180 = BMP180(i2c)
bmp180.oversample_sett = 2
baseline = bmp180.pressure/100
ALTURA = 790

WIDTH  = 128                                            # oled display width
HEIGHT = 64
oled = SSD1306_I2C(WIDTH, HEIGHT, i2c)

print ("Doble sensor DHT22 y DS18x20")
#Write in cmd found addresses

i2cScan = i2c.scan()
counter = 0
for i in i2cScan:
    print('I2C Address ' + str(counter) + '      : '+hex(i).upper())
print ("**************************")
#---------------

ds_pin = machine.Pin(22)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()

while True:
    #--DHT22--------------------------------------------   
    T, H = dht_sensor.read()
    if T is None:
        print("Error en el sensor!")
    else:
        print("Sensor DHT22->","{}ºC  {}%".format(T,H))
       
    #--LDR--------------------------------------------
    reading = analog_value.read_u16()    
    print("LDR-> ADC: ",reading)
   
    #..BMP180---------------------------------------------   
    temperatura = bmp180.temperature
    presion = bmp180.pressure/100
    alt2=44330.0* (1-pow(presion/baseline,1/5.255) )   
    alt2=ALTURA+alt2
       
    alt2=round(alt2)
    temperatura=round(temperatura,1)
    presion=round(presion)
           
    print("Tem_BMP180=",temperatura,"ºC Presion=", presion," ALTITUD=",alt2)
   
    #--DS18B20--------------------------------------------
    ds_sensor.convert_temp()
    time.sleep_ms(750)
    x=0
    for rom in roms:
        #print ("Sensor=",x,"  ",rom,"  Temperatura=",ds_sensor.read_temp(rom))
        print ("Sensor_DS18B20_nº",x,"  ","  Temperatura=",ds_sensor.read_temp(rom))
        x=x+1
   
    oled.fill(0)
    oled.text("-Seta43- ",0,8)
    tmp=str(T)+" C  DHT22"
    oled.text(tmp,0,16)
    tmp=str(H)+" %  DHT22"
    oled.text(tmp,0,24)
    tmp=str(presion)+" mBa BMP180"
    oled.text(tmp,0,32)
    tmp=str(alt2)+   " m   BMP180"
    oled.text(tmp,0,40)
    tmp=str(reading)+" luz LDR"
    oled.text(tmp,0,48)
    oled.show()

   
    print("---------------------")
    led.value(0)
    utime.sleep(0.5)
    led.value(1)
    utime.sleep(0.5)


Como se puede entender, para el funcionamiento de todo, se hace uso de varias librerías.
Para que funcione las librerías deben ser copiadas a la raspberry pi pico.

 

PROGRAMAS Y LIBRERÍAS

VÍDEO


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
seta_PIB
seta_PIA
https://lindevs.com/set-up-raspberry-pi-pico-sdk-on-ubuntu
https://www.electroniclinic.com/raspberry-pi-pico-rp2040-programming-in-micropython-with-examples/
https://www.youtube.com/watch?v=2gihPgEkvL8
https://picockpit.com/raspberry-pi/es/todo-sobre-la-frambuesa-pi-pico/


martes, 14 de junio de 2022

Arduino nano ,Radio RDA5807, Representación OLED con RDS

  Página principal

Arduino nano
Radio RDA5807
Representación OLED con RDS

Hace uno años hice  rards.html  con  la visualización en un LCD 3310 y decodificación del RDS.
Me habían pedido que lo hiciera con
OLED SSD1306Z y botones pulsadores tipo TOUCH (sin contacto).



Como no tengo símbolos de los TOUCH los he sustituido en el esquema por botones normales, aunque el diseño está realizado con TOUCH.








Espero que este montaje os haya parecido interesante.

PROGRAMAS

Saludos.
Juan Galaz



Bibliografía:

radiofm.html
rards.html
ardura.html
 
http://arduino.vom-kuhberg.de/index.php
RADIO DATA SYSTEM- RDS- Por: Aitzol Zuloaga Izaguirre.
http://www.rds.org.uk/2010/Overview.htm

miércoles, 10 de noviembre de 2021

TransistorTester para Arduino Nano y OLED SSD1306Z

  Página principal



Transistor Tester para Arduino Nano
OLED SSD1306Z
Traducido por SETA43


Navegando por internet, encontré un analizador de componentes llamado  TransistorTester, el autor era  Karl-Heinz Kübbeler .
Sobre este montaje, que en principio solo se había creado para analizar transistores, existían múltiples versiones.
La versión que he utilizado es 1.08.004, que en este caso no está creada por el autor,  está realizada para arduino.
Me he permitido el atrevimiento de traducir esta versión al español, solo son unas cuantas palabras.
También no se representaba bien los componentes en el OLED, lo he intentado arreglar como he podido.
He de comentar que me ha sorprendido lo sencillo del montaje, y lo útil que es.
Detecta perfectamente si es un transistor NPN o PNP, JFETs, Diodos, Condensadores, Resistencias. Y lo mas curioso es la forma automática de detectar los pin.

La versión original de TransistorTester está realizada sobre un ATMEGA328 y con un interruptor rotativo, no utiliza el arduino, además de existir múltiples versiones comerciales.






Condensador de 3.9nF  y   1uF



Ressistencias de 330 ,1K, 10K




Transistor BC109 y BD681



Detalle del circuito




PROGRAMA

Este es un montaje muy práctico, se lo recomiendo a todos los electrónicos, será muy útil en cualquier momento para chequear componentes.
Puede funcionar con la alimentación del USB del arduino, pero funciona mejor alimentando al pin Vin del arduino, que soporta hasta 12V.

Para una mejor funcionamiento deberíamos quitar la resistencia que está en el pin D13, es la que alimenta el LED de prueba.


Saludos.
Juan Galaz



Bibliografía:

https://github.com/kr4fty/Ardutester
https://www.sysadminsdecuba.com/2020/08/ardutester-tester-de-componentes-con-arduino/
https://create.arduino.cc/projecthub/mircemk/diy-super-simple-electronic-component-tester-234752
https://create.arduino.cc/projecthub/plouc68000/ardutester-v1-13-the-arduino-uno-transistor-tester-dbafb4

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/