martes, 17 de abril de 2018

Arduino - Receptor de sensores de temperatura comerciales 433MHz

Página principal

Arduino

Receptor de sensores de temperatura

comerciales 433MHz

xsetaseta@gmail.com

Había visto hace tiempo un artículo donde se exponía la posibilidad de escuchar los sensores de temperaturas comerciales de las estaciones meteorológicas. Yo tengo un par de estaciones de ese tipo, y como curiosidad descubrí que funcionaban en la misma frecuencia y eran compatibles. Para que funcionasen los dos sensores a la vez debía cambiar el canal en los sensores.



Por suerte las dos estaciones meteorológicas tenían el mismo tipo de sensor y eran compatibles.

Estos sensores funcionan en la frecuencia de 433.xxxMHz , si no es muy selectivo el receptor puede recibir señales en toda la banda.
Tengo dos tipos de receptores, el uno es mas sensible que otro, aunque un poco mas caro lo recomiendo.
En el mercado chino existen numerosos receptores, algunos funcionan a 351MHz, y otros están sintonizados mal.  En la parte de bibliografía pongo el enlace del que me ha funcionado bien (2€).


Recomiendo este por ser mas sensible.


Montado el circuito receptor y alimentado a 5V me puse a estudiar los datos recibidos.

Gráfica de datos recibidos.


Después un estudio interprete las señales de este modo, tuve suerte, acerté.


Estudiando los datos mandados y con bastante trabajo, pude determinar la estructura de los datos.

Los datos emitidos se repiten varias veces, de esta forma podemos asegurarnos que el valor es correcto, no se si tiene verificación vía CRCs.
He de reconocer que tuve suerte, no estaban codificados como en algunos emisores.
También he descubierto que los datos extras son el estado de la batería.


Circuito montado con su antena.


Detalle del circuito, he quitado componentes usados en el desarrollo.

Al usar la interrupción INT0 para decodificar la señal, he configurado el pin D2 como entrada y conectado la salida DATA del receptor al pin D2.

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Int433");
  pinMode(2, INPUT);
  pinMode(IN_READ, INPUT);

  cli();                // Disable INT
  EIMSK |= (1 << INT0);  // Enable external interrupt INT0
  EICRA |= (1 << ISC01); // Trigger INT0   en bajada
  sei();
}


El programa en el arduino se encarga de interpretar la señales y mandar los datos vía serie.
Int433
Canal,2,Grados,202,Extra,15
Canal,2,Grados,202,Extra,15
Canal,2,Grados,202,Extra,15
Canal,2,Grados,202,Extra,15
Canal,2,Grados,202,Extra,15
Canal,2,Grados,202,Extra,15
Canal,2,Grados,202,Extra,15
Canal,2,Grados,202,Extra,15
Canal,1,Grados,216,Extra,18
Canal,1,Grados,216,Extra,2
Canal,1,Grados,216,Extra,2
Canal,1,Grados,216,Extra,2
Canal,1,Grados,104,Extra,1
Canal,1,Grados,216,Extra,2
Canal,1,Grados,216,Extra,2
Canal,1,Grados,216,Extra,2
Canal,1,Grados,216,Extra,2
Datos recibidos vía serie

Para hacer un poco mas vistoso la visión de los datos, realicé en Gambas3 (Visual Basic Linux) un programa.


Las gráficas de la señales están realizadas mediante Osciloscopio Hantek6022BL y PulseView bajo Linux (Debian8_32bits).

PROGRAMAS

Hasta pronto.
JUAN GALAZ

Bibliografía:

setacom.html
hantek.html
https://fetzerch.github.io/2014/11/15/reveng433/
https://es.aliexpress.com/item/1pair-2pcs-433mhz-rf-transmitter-and-receiver-kit-For-Wireless-Power-switch-socket-remote-control-LED/32311933574.html?spm=a2g0s.9042311.0.0.lWlrua

miércoles, 11 de abril de 2018

Arduino - Comunicación Serie por Software - Interrupciones

Página principal


Arduino
Comunicación Serie por Software

Interrupciones
xsetaseta@gmail.com

Debía realizar un análisis de unas señales que transmitían códigos. Para obtener los datos de estas señales debía decodificar los diferentes impulsos de estas señales. El chip decodificador debía ser un arduino, y como nunca había realizado este trabajo, debía experimentar un patron de señales conocidas, y la mas conocida era la comunicación serie.
El estándar serie  es bien conocido, su decodificación normalmente se hace vía hardware, aunque a baja velocidad también se puede decodificar vía Software. Esta es una práctica de decodificación mediante programa de una señal con el protocolo serie, (USART) universal synchronous and asynchronous receiver-transmitter.

Imagen de una señal serie.


Tiempo de la señal Start a una velocidad de 300bps.


Tiempo de la señal Stop a una velocidad de 300bps.

La señal representada corresponde a una señal serie de 8 bits y 1 bits de parada.

Para decodificar esta señal he utilizado dos métodos diferentes:
El primer método cheque continuamente un Pin del arduino, que debemos determinar en el Setup.
El segundo método solo se interrumpe la ejecución del programa si existe un cambio en el Pin2, el cual genera la interrupción 0.

Modo 1.
Creamos una interrupción que continuamente mira el estado del pin que se designa como entrada.
 
  SRetardoStop = SRetardo * 10;

  SRetardoMax = SRetardo * 14;
  // initialize Timer1
  cli();          // disable global interrupts
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B
  TCCR1B |= (1 << WGM12); // turn on CTC mode:
  TCCR1B |= (1 << CS10);  //sin prescaler
  OCR1A = Scontador;   //contador
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt:
  sei();          // enable global interrupts

Vemos como utilizamos el Timer1, le asignamos un valor al contador, cuando el contador llegue a cero produce una interrupción, carga de nuevo el valor del contador, y se ejecuta la rutina de la interrupción.
La rutina de la interrupción es donde se estudia la señal del pin y se llama:
ISR(TIMER1_COMPA_vect)
{
}

Gráfica del chequeo de señal y la toma de valores de la señal.


Modo 2.
Para este caso no existe ninguna temporización, el programa utiliza la interrupción externa Int0 que se encuentra en el Pin 2 del arduino.
El programa solo se interrumpe cuando detecta un cambio de señal en el Pin 2 del arduino.
bool SetupSerie2(unsigned int  baud)
{
  pinMode(2, INPUT);
  digitalWrite(2, HIGH); // Enable pull-up resistor
  cli();                 // Enable global interrupts
  EIMSK |= (1 << INT0);  // Enable external interrupt INT0
  EICRA |= (1 << ISC00); // Trigger INT0 on Change
  sei();
......

La rutina de la interrupción es donde se estudia los tiempos del cambio de señal del Pin 2 del arduino y se llama:
ISR(INT0_vect)
{

}


En los dos casos cuando se ha completado la lectura de un byte,  se pone la variable SDatoEstado = 1; .
En el bucle del programa principal que chequea continuamente el SDatoEstado = 1; , mediante la rutina  SerialAvailable() ,cuando detecta un carácter válido, se obtiene el byte  mediante la rutina SerialGet().
Para esta práctica no he querido crear un buffer que sería lo normal, pues si se entretiene mucho el programa principal pudiera sobrescribirse los datos.
En ambos casos a velocidades superiores a 4800 bps, me producían errores, se mezclaban las interrupciones, no he querido profundizar en su posible solución.

Para entender la interrupciones en el arduino, estuve buscando en internet un tutorial, encontrando este:
https://arduinodiy.wordpress.com/2012/02/28/timer-interrupts/
en plan atrevido, realicé una traducción, espero que no sea muy mala. TRADUCCION

Las gráficas de la señales están realizadas mediante Osciloscopio Hantek6022BL y PulseView bajo Linux (Debian8_32bits).

PROGRAMAS

Hasta pronto.
JUAN GALAZ

Bibliografía:

https://aprendiendoarduino.wordpress.com/2016/11/13/interrupciones/
https://arduinodiy.wordpress.com/2012/02/28/timer-interrupts/
http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/


lunes, 2 de abril de 2018

Osciloscopio Hantek6022BL en Linux OpenHantek y PulseView

Página principal
Osciloscopio Hantek6022BL
en
Linux

OpenHantek y PulseView
xsetaseta@gmail.com

Después de medio año con mi osciloscopio digital Hantek6022BL me surgió el tener que analizar unas señales digitales.
En un anterior artículo realizaba mi experiencia tras una semana utilizando el osciloscopio.
Primera-semana-con-el-osciloscopio.html
Como hacía tiempo que no había mirado sobre algún programa que bajo linux se pudiese hacer uso del osciloscopio, me puse a mirar.
Efectivamente, había novedades:
En primer lugar era el http://openhantek.org/ , ya tenía soporte para el Hantek6022BL .
El programa openhantek es un programa que realiza el soporte de varios osciloscopios digitales USB, hasta hace poco no soportaba el Hantek6022BL, pero ahora lo soporta bastante bien.
Desde la página web solo podemos bajar el código fuente, no existen binarios.
Después de muchas pruebas, descubrí que debido a las dependencias en la librería QT ("Minimum supported Qt5 version is 5.4.0!"), debemos tener un Debian9,  Mint18, Ubuntu 17.10 . Intente por todos los medios intentar compilarlo en Debian 8, pero me fué imposible. Con anteriores versiones de openhantek si se podía compilar para Debian 8, pero no tenía soporte para el Hantek6022BL.
Para la compilación debemos seguir los siguientes pasos:
Después de ver como compila sin errores, no habrá creado el ejecutable en  el directorio openhantek .
Si intentamos ejecutarlo, veremos que nuestro osciloscopio no es detectado.
Deberemos añadir al directorio /lib/udev/rules.d/ algunos ficheros para que nuestro Hantek6022BL  USB sea reconocido.
Debemos copiar el fichero  firmware/60-hantek.rules/lib/udev/rules.d/
Volvemos a ejecutar el programa con el USB desconectamos.
Una vez con el programa funcionando, conectamos el USB y veremos como nos aparece nuestro 6022BL.
Ya podemos ver como nos funciona el programa con nuestro Hantek6022BL. Tendremos que activar un canal.
Para que nos reconozca el osciloscopio debemos tener el botón que se encuentra al lado del conector USB, metido (modo H) antes de conectar el USB.


Hantek6022BL funcionando en linux bajo openhantek

Para el que no quiera complicarse en compilar tengo los ficheros en:
https://drive.google.com/drive/folders/1zfv4cq8lpocLDWRQydqtaIDuZbndaVit?usp=sharing

He compilado OpenHantek para Mint18 64bits , Ubuntu 17.10 64bits, Debian 9.4 32bits.
Debemos de dar permisos de ejecución a los ficheros ejecutables.


Para analizar señales digitales con el Hantek6022BL teníamos saleae  desde la página  https://www.saleae.com/downloads , pero solo funcionaba en 64bits.
Como normalmente trabajo en Debian 32bits, este programa no me servia, debía encontrar una solución.
Buscando encontré un programa PulseView ,que hacía uso del programa sigrok para capturar señales digitales , https://sigrok.org/wiki/Main_Page.
Este es un interface gráfico para representar señales digitales y analizar protocolos.
Para este caso no me he complicado mucho, he bajado los ficheros binarios que se encuentran en https://sigrok.org/wiki/Downloads. existen versiones para 32bits y 64bits.
Para que nos reconozca el osciloscopio debemos tener el botón que se encuentra al lado del conector USB, sacado (modo L) antes de conectar el USB.
Al igual que en el modo analógico, deberemos añadir al directorio /lib/udev/rules.d/ algunos ficheros para que nuestro Hantek6022BL  USB sea reconocido. Los tengo recopilados en https://drive.google.com/drive/folders/1zfv4cq8lpocLDWRQydqtaIDuZbndaVit?usp=sharing , son todos los que terminan en *.rules .
Aquí me he encontrado un error en el reconocimiento de dispositivo, tarde algún tiempo en encontrar la solución.
Arrancamos el programa  ./PulseView-NIGHTLY-i686.AppImage
Veremos que no detecta el Hantek6022BL.
Sin salir del programa desconecte el USB del osciloscopio y vuelva a conectar.
Ahora salir del programa y volver a entra, verás que ahora si lo detecta y funciona.


Pulseview funcionando con  Hantek6022BL

Espero que le haya ayudado a alguien.

Hasta pronto.
JUAN GALAZ

Bibliografía:
http://openhantek.org/
https://sigrok.org/wiki/Main_Page
https://sigrok.org/wiki/PulseView

domingo, 25 de marzo de 2018

Arduino - Detector de movimiento RCWL-0516 - Serial Plotter en GAMBAS

Página principal


Arduino
Detector de movimiento
RCWL-0516
Serial Plotter en GAMBAS
xsetaseta@gmail.com

El otro día navegando por la red vi el artículo sobre un detector de movimiento RCWL-0516
http://www.rogerclark.net/investigating-a-rcwl-9196-rcwl-0516-radar-motion-detector-modules/ .
Era un detector de movimiento que no funcionaba por infrarrojo, era por interferencia en un oscilador al acercarse un objeto.
El objeto debe tener algo de agua o ser metálico, o que produzca interferencias en un circuito oscilante.
Objetos como espuma o papel no son detectadas.
Pedidas por internet,  precio barato alrededor de 1€,  llegó  rápido.
Me puse hacer pruebas imitando los que había visto en la página antes mencionada.
La verdad que el circuito no decepciona, es bastante sensible al movimiento de personas.
Se puede utilizar en aparatos de alarma, o en el encendido de luces automáticas.
El material que me produjo más interferencia, si estaba cerca del módulo fue la ferrita.

Product Introduction:
  • 1.Operating Voltage:4-28V
  • 2.Operating Current:2.8mA (typical);3mA (max)
  • 3.Detection Distance:5-9m
  • 4.Transmitting Power:20mW (typical);30mW (max)
  • 5.Output Voltage:3.2-3.4V
  • 6.Output Voltage Driving Capacity:100mA
  • 7.Trigger Way:repeat trigger
  • 8.Output Control Low Level:0V
  • 9.Output Control High Level:3.3V
  • 10.Operating Temperature:-20~80 celsius
  • 11.Storage Temperature:-40~100 celsius


Circuito de pruebas con arduino.


Detalle de la conexión al pin 12 para las prueba.


Esquema del módulo.


Señales  del pin 12 y de la salida VOUT visualizadas con Serial Plotter de arduino.


Serial Plotter realizado con Gambas (Visual basic para linux)

Como suelo utilizar  arduino 1.05 , me di cuenta que no tenía el Serial plotter que si tiene la versión 1.6.
Me había gustado la gráfica que generaba la utilidad de Serial plotter, por lo cual me puse manos a la obra para realizarla con Gambas (Visual Basic para linux), el trabajo no debería ser muy difícil.
El resultado es el que se muestra, un visualizar de 2 canales, bastante correcto.

Pensando una utilidad rápida para el módulo, construí en 2 minutos un medidor de pulsos de corazón.
Recubrí el módulo con varias capas de plástico de cubrir alimentos.
Tapé uno de los lados del módulo con varias capas de papel de aluminio.
Con una goma coloque la parte del módulo no tapado con aluminio sobre una vena.
Las variaciones de presión de la vena generan pequeños cambios de frecuencia en el módulo, produciendo los impulsos de tensión.
Está claro que se puede perfeccionar, pero para una primera prueba vale.


Detector de pulsos.



Gráfica de mis pulsos cardíacos.


PROGRAMA Serial plotter PARA GAMBAS3


Hasta pronto.
JUAN GALAZ

Bibliografía:
https://github.com/jdesbonnet/RCWL-0516/
http://www.rogerclark.net/investigating-a-rcwl-9196-rcwl-0516-radar-motion-detector-modules/
https://www.electroschematics.com/13246/get-started-microwave-radar-motion-sensor/

viernes, 23 de marzo de 2018

Control de coche RC NIKKO mediante Arduino y nRF24L01

Página principal


Control de coche
RC NIKKO
mediante
Arduino y nRF24L01
xsetaseta@gmail.com

Los domingos suelo ir a un rastrillo donde se pueden conseguir aparatos electrónicos muy baratos.
En una de las veces encontré un coche RC de la marca MIKKO, no tenía mando claro, además no sabes si funciona, por eso es tan barato.
Una vez en casa y desarmado el coche, encontré una placa basada en el CI PT8A978. Este circuito es parte de una pareja de circuitos (receptor/emisor) utilizado para el control de coches RC.



Como no tenía ningún mando que pudiese utilizar para manejar el coche RC, me propuse hacer un mando con arduino y el nRF24L01.
En primer lugar he utilizado mi anterior circuito carreco.html que maneja un coche mediante dos motores.
El mando a distancia es el mismo, pero utilizado un arduino-mini-pro, y he metido todo en el hueco de las pilas. Todo bastante compacto, y alimentado por dos pilas de 1,5V.


Mando con el circuito emisor. Se inserta todo en el hueco de las pilas.

Circuito del mando.

Navegando por internet encontré http://androidcontrol.blogspot.com.es/2012/07/android-rc-control.html .
En el se explica como aprovechar el circuito que viene en el coche NIKKO.
Lo primero es anular la alimentación del CI y del circuito emisor.
Después se anulan la 4 resistencias que manejan los dos motores.
Coloco 4 resistencias de 560 ohmios entre las salidas del arduino y las entradas de los transistores.

Esquema del circuito NIKKO y las modificaciones.


Coche con la carcasa quitada.


Vista superior del coche modificado.


Circuito del coche.

Cuando monté todo, me encontré con un problema grave, al ponerse en marcha los motores del coche, producían una bajada de tensión que hacía resetear el arduino.
Por debajo de los 5V en las baterías, el circuito regulador de 3.3V no funcionaba bien, el arduino se resetea.
Si utilizamos baterías recargables el valor es de 4,8V , y no se puede usar para alimentar el circuito.
Para que funcione todo sin depender del tipo de baterías utilizado, he empleado una batería que se utilizan en drones de 3.7V 500mA para alimentar el circuito de control.
En la parte de fuerza se puede alimentar con cualquier tipo de batería, y como se ve en la foto he colocado además un regulador 7805 para poder alimentar los motores con 2 baterías recicladas de portátiles, con una tensión de 3,7V cada una (7.4V).

También intente hacer que el control de velocidad fuese analógico, pero los transistores que emplea el circuito Nikko no están preparados para este modo de funcionamiento, y se calentaban.

Para hacerlo algo más vistoso he añadido 2 LED que se pueden encender desde el mando.






VIDEO DEL FUNCIONAMIENTO


PROGRAMA



Hasta pronto.
JUAN GALAZ

Bibliografía:
carreco.html
carreci.html
http://androidcontrol.blogspot.com.es/2012/07/android-rc-control.html

martes, 13 de marzo de 2018

Sensor de temperatura 2 módulos - ds18B20 Representación en OLED 128x64 SSD1306Z / GM009605 - Arduino y nRF24L01

Página principal

Sensor de temperatura
2 módulos - ds18B20
Representación en

OLED 128x64
SSD1306Z - GM009605

 
Arduino y nRF24L01
xsetaseta@gmail.com

En dos anteriores montajes, arolet.html ardusen.html había realizado un termómetro a distancia de dos módulos con el NRF24L01, y el segundo unas rutinas  en modo texto para manejar un OLED SSD1306Z.
Este montaje es la unión de los dos montaje antes mencionados.
Al tener casi todo el trabajo hecho, la unión de los dos programas no llegó a 2 horas con todo funcionando.

Esquema de los módulos emisores. (Realizado con https://easyeda.com/ )


Sensor de temperatura.


Esquema de la base de detectores. (Realizado con https://easyeda.com/ )


Circuito de la base de sensores con OLED.

Se puede observar que se muestra la temperatura de los dos sensores en la pantalla de OLED.
Debo de decir que si el módulo de temperatura se encuentra lejos, o tiene que traspasar algunas paredes, la señal se puede perder y no llegar la temperatura. En caso de que la base pida la temperatura a uno de los dos módulos y no le responda el módulo, se borra la indicación de temperatura. Esto es bueno y malo, hay veces y bastantes que no llegan los datos, dejamos de ver la temperatura, aunque hace 10 segundos la sabíamos. Es fácil cambiar el programa para que solo se pierda la visión si hace mucho que no recibimos respuesta del sensor, pero eso te lo dejamos como trabajo.
Recomiendo ver los anteriores montajes en que está basado este montaje.
Aunque algunos se extrañen, la frecuencia de 2.4GHz no es demasiado buena para traspasar objetos, dependiendo del tipo de material pueden perder bastante señal. Con visión directa es muy buena, puede llegar muy lejos con una buena antena y poca potencia, además de permitir transmitir muchos datos.
Para casos como este yo recomiendo los módulos de 433MHz-MX-05V, son bastante mas baratos y traspasan mejor las paredes.
Hace algunos años hice estos montajes, emisor y transmisor   con módulos de 433MHz.



PROGRAMA3


Hasta pronto.
Juan Galaz


Bibliografía:

arolet.html
ardusen.html

jueves, 8 de marzo de 2018

Termómetro OLED 128x64 con SSD1306Z y Arduino



Termómetro
OLED 128x64
SSD1306Z
GM009605
Arduino


Hace tiempo que me había llegado una pantalla del tipo OLED, con una resolución de 128x64, y aún no lo había empleado.
Nunca he trabajado con pantallas de tipo OLED, por lo que no sabía como trabajaba.
En primer lugar diremos que la pantalla viene para ser controlada mediante el bus I2C, por lo cual se necesitan pocos cables, alimentación y CLK , SDA.
Lo primero que suelo hacer es bajarme todos las manuales del fabricante que puedo.
Lo siguiente es intentar buscar alguna librería para arduino  que maneje la pantalla.
La librería mas famosa es la de Adafruit-GFX-Library , junto con Adafruit_SSD1306. Estas librerías funciona muy bien, tienen todo lo necesario para manejar gráficamente la pantalla.
Otra librería es  Universal 8bit Graphics Library, https://github.com/olikraus/u8glib/ ,  que puede manejar diferentes tipos de pantalla. Antes de utilizar esta librería de debe de descomentar la linea que corresponde a nuestra pantalla. En las pruebas que realicé para mi pantalla la línea era : U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);    // I2C / TWI
Estas librería están hechas para un montón de pantallas, por lo cual no están optimizadas para una en concreto. El resultado es que suelen ocupar bastante memoria de programa (10Kb), y la mitad de la memoria RAM 1024. En muchos casos no se puede añadir otra librería por falta de memoria.
Este aviso suele aparecer en la compilación:
Las variables Globales usan 1.956 bytes (95%) de la memoria dinámica, dejando 92 bytes para las variables locales. El máximo es 2.048 bytes.
Poca memoria disponible, se pueden producir problemas de estabilidad.

Como me gusta programar mis propias rutinas de manejo de pantalla, me puse manos a la obra.
Tomando como referencia la librería Adafruit , me puse crear mis rutinas sin utilizar librería alguna, todas las rutinas están en el propio programa.
Empecemos por conocer la estructura de pantalla del OLED.

La estructura es bastante común, líneas de 128 bytes, y el total de líneas es de 8, por lo cual el total de bytes es de 1024 bytes.
En anteriores montajes arnok.htmlmatrixd.html también había trabajado con esquemas de pantalla parecidos, por lo cual ya tengo alguna experiencia.
En líneas generales el funcionamiento es el siguiente:
  • -Se crea un buffer   (buffer[OLE_BUFFER];) de 1024 bytes donde se pintan todas las líneas o caracteres.
  • -Una vez pintado todo, se vuelca todo en la pantalla OLED mediante la orden display();
Esto es simple, y es el método que se utiliza en la mayoría de los programas de ordenador.
Pero mover 1024 bytes mediante en el Bus I2C no es lo rápido que debiera ser para no ser notado el repintado.
Para solucionar este problema, cree una rutina que solo repintaba 1 línea de la 8 que existen.
Mediante este método conseguía una velocidad 8 veces mayor en escritura de caracteres, no sirve para  puntos y líneas.
La activación de este método es mediante ModeDisplay=1; .

Otro problema que tuve fue lo pequeños que se ven los caracteres, diminutos, había que solucionarlo, crear diferentes tamaños de caracteres.

El resultado no fue del todo malo, por lo menos se veían los caracteres, que es lo que se pretendía.
En modo gráfico solo he implementado plot, line (en solo modo vertical y horizontal),y  drawBox.

Para probar todo he pensado un termómetro digital utilizando el 18B20, sencillo y rápido.

Esquema del circuito.


Circuito montado.

He realizado dos programas, uno inserta todas la rutinas en el propio programa y otro coloca un fichero de cabecera olex.h donde se colocan las rutinas. Los dos funcionan igual, pero en uno queda el programa mas sencillo de ver, solo queda el programa no las rutinas.
El tener que utilizar 1024 bytes a modo de buffer, implica usar la mitad de la memoria  impidiendo hacer programas más grandes.
En el próximo programa intentaré hacer rutinas para texto que solo utilicen 128 bytes.

En las mediciones de consumo se puede observar que varía bastante dependiendo los puntos que se encuentren encendidos, entre 3 mA y 17 mA, en modo normal. En las pruebas el circuito funcionaba perfectamente a 3.3V
PROGRAMA





Después de un par de días  pensando en la poca memoria RAM que dejaba al utilizar un buffer de 1024byes, decidí solucionar el problema.
La solución era reducir el buffer a 256bytes. Esto implica no poder utilizar gráficos (plot , líne). Además se imprime caracteres en líneas completas.
Para el caso que nos ocupa sirve de sobra, y la liberación de memoria es bastante 768 bytes.
La salida del compilador nos da lo siguiente:
El Sketch usa 7.320 bytes (22%) del espacio de almacenamiento de programa. El máximo es 32.256 bytes.
Las variables Globales usan 1.004 bytes (49%) de la memoria dinámica, dejando 1.044 bytes para las variables locales. El máximo es 2.048 bytes.

PROGRAMA2

Como seguía pensando en el montaje, y en la posibilidad de eliminar el buffer de la memoria RAM para representar caracteres, me puse manos a la obra. El resultado es la eliminación del buffer y la liberación de la memoria RAM, resultando 1300 bytes libres para ser utilizados por otras librerías.
También se corrigió el que salían los decimales negativos.
Salida del compilador nos da lo siguiente:
El Sketch usa 7.422 bytes (23%) del espacio de almacenamiento de programa. El máximo es 32.256 bytes.
Las variables Globales usan 748 bytes (36%) de la memoria dinámica, dejando 1.300 bytes para las variables locales. El máximo es 2.048 bytes.

PROGRAMA3



Hasta pronto.
Juan Galaz


Bibliografía:
https://github.com/adafruit/Adafruit_SSD1306
https://github.com/adafruit/Adafruit-GFX-Library
https://github.com/olikraus/u8glib/
arnok.html
matrixd.html
http://www.instructables.com/id/Monochrome-096-i2c-OLED-display-with-arduino-SSD13/

miércoles, 28 de febrero de 2018

Mando a distancia para puerta III. Modo dialogo con lista.



Mando a distancia para puerta
III
Modo dialogo con lista
Arduino



En los dos anteriores montajes había realizado un mando a distancia con diferente modos de programa.
El primero mandaba los códigos directamente, en el segundo realizaba una negociación entre llave y puerta basada en una formula.
Para este montaje utilizo el mismo circuito, pero ahora negocia los códigos mediante una lista almacenada tanto en la llave y la puerta.
La lista  debe ser la misma tanto en la llave como en la puerta.


Esquema de puerta y mando.


Circuito de la puerta y de la llave.


Diagrama del dialogo entre llave y puerta.

La lista de códigos está almacenada en 2 arrays.
Como no me quería complicar mucho, solo he utilizado 2 arrays de 16 números.
Para hacerlo algo más seguro deberíamos haber creado las arrays  de 256 números.
    byte LISTAcodigo0[15]={12,9,5,11,8,6,13,4,1,0,7,2,14,3,10};
    byte LISTAcodigo1[15]={13,0,5,2,11,9,4,12,6,1,8,10,7,14,3};

El numero de orden en el array  se sacan del tiempo de funcionamiento del arduino.
     time = millis();
    x=time & 0x0F;
    y= 0x0F & (time>>8);

La variable CODIGO2 se saca de los micro-interruptores , como es normal deberá ser el mismo en la llave y en la puerta.
Esta variable es utilizada para modificar el numero de orden.
      x=(x+CODIGO2) & 0x0F;   
      x=LISTAcodigo0[x];
     
      y=(y+CODIGO2) & 0x0F;
      y=LISTAcodigo1[y];

Información de la llave
=======================

Información de la puerta
========================

___LLAVE Lista___12
Pulsado Boton de Apertura
Respuesta a la pregunta
Pulsado Boton de Apertura
Respuesta a la pregunta
___LLAVE Lista___4
Pulsado Boton de Apertura
Respuesta a la pregunta
___LLAVE Lista___12
Pulsado Boton de Apertura
Respuesta a la pregunta

____Puerta Lista____12
Peticion de apertura
CORRECTO
Peticion de apertura
CORRECTO
Peticion de apertura
ERROR
Peticion de apertura
CORRECTO



Tampoco me he metido mucho en asegurar la seguridad ante la fuerza bruta, solo he metido retardos para hacerlo más difícil.
En lo personal prefiero el modo de códigos por fórmula, pero este método es otro mas, y debía realizarlo.

En todo los montajes se podría realizar un registro de entrada y de salida, y horas. Pero eso es otra historia...

PROGRAMA

Hasta pronto.
Juan Galaz

Mando a distancia para puerta II . Modo dialogo con formula .



Mando a distancia para puerta
II
Modo dialogo con formula
Arduino



En el anterior montaje Mando a distancia para puerta , había realizado un mando a distancia en el cual se mandaba los códigos sin ninguna seguridad.
Cualquier que se dedique a escuchar en el canal en el que transmite el mando, podrá descubrir el código.
En este montaje utilizamos el mismo circuito a nivel de llave y de puerta que el anterior, pero el programa se cambia radicalmente.
Ahora se produce un diálogo entre la llave y la puerta, impidiendo que la escucha pueda descubrir el código, los códigos se cambian en cada petición.



Esquema de puerta y mando.


Diagrama del dialogo entre llave y puerta.

Los códigos de pregunta en la puerta se sacan del tiempo de funcionamiento del arduino.
     time = millis();
    x=time & 0xFF;
    y= 0xFF & (time>>8);

Los códigos de respuesta se sacan de una fórmula.
      codigo=x*y*CODIGO2+CODIGO2;
     x= codigo & 0xFF;
     y= codigo>>8 & 0xFF;
La formula se puede cambiar a gusto del programador para hacerla aún más segura.
Esta formula debe ser la misma en la llave y en la puerta.
La variable CODIGO2 se saca de los micro-interruptores , como es normal deberá ser el mismo en la llave y en la puerta.

Información de la llave
=======================

Información de la puerta
========================

__LLAVE Código___
4
Pulsado Botón de Apertura
Respuesta a la pregunta
___LLAVE Código___
12
Pulsado Botón de Apertura
Respuesta a la pregunta

Petición de apertura
Código pregunta 173  47
Respuesta 16  127
Respuesta solicitada 48  125
ERROR
Petición de apertura
Bodigo pregunta 64  98
Respuesta 12  38
Respuesta solicitada 12  38
CORRECTO

Como podemos ver este modo es mucho más seguro que el mandar el código simplemente.
Aseguramos de que si hay alguien escuchando en el canal, no le servirá de nada.
Tampoco me he metido mucho en asegurar la seguridad por fuerza bruta, solo he metido retardos para hacerlo más difícil.

PROGRAMA

Hasta pronto.
Juan Galaz