Sensorino

From Wiki Makespace Madrid
Revision as of 12:10, 22 October 2015 by 195.55.253.226 (Talk) (MCU)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

El proyecto Sensorino tiene varios sub-proyectos que en conjunto facilitan construccion de redes de sensores / actuadores baratas. La parte software presenta una solucion completa que sin embargo necesita que el usuario por su cuenta complete y conecte todo el hardware necesario para su caso de uso.

Esta pagina recoge discusiones y consideraciones tempranas que ocurrierion antes de empezar el desarrollo de software o hardware Sensorino actual. Actualmente se mantiene la documentacion tecnica del proyecto en Github en el wiki asociado al sub-proyecto de firmware Sensorino y los sitios enlazados ahi. El canal de comunicacion es la lista de correo mencionada en el wiki de Github.

Sensorino[edit]

Estado: Software funcional, usa hardware off-the-shelf, desarrollo de placas propias abandonado

Miembros: User:Dario_Salvi, User:Bozo, User:Roberto Zabala, Andrew Zaborowski


Objetivo[edit]

construir una red de sensores compatibles con el IDE de Arduino y que cuesten menos que 5 € con todo incluido.

Milestone 0[edit]

Fecha: 15 Mayo 2013

  • HW:
    • placa base con ATMega con patas gordas y nrf24 modulo chino, todo hecho a mano. Por lo menos 5 unidades.
      • Sensores/actuadores: luz, temperatura, interruptor/botón, Luz RGB, Relé
    • placa BASE, con conexiones al ordenador (o shield para Arduino). Un par de unidades.
    • placa PL (powerline) con transformador incluido, logica 5V y DC converter. Por lo menos 3.
    • Shield para progrmar el ATMega y hacer algún test
  • FW:
    • Versión base de librerías Sensorino con algunos servicios hechos
    • Update del firmware remoto
  • SW:
    • Visualización basica
    • Actuación
    • comunicación con base
    • servicios Sensorino base implementados
  • Promo:
    • Primer evento Sensorino en Makespace
    • Primer Wordpress basico montado

Milestone 1[edit]

Fecha: ?

  • HW:
    • Placas PCB hechas y estables para versiones mini, PL y base con ATMega con pines gordos y nrf chino
    • primeros intentos con SMD
    • Shield de apoyo para producción rapida de ATMega
  • FW:
    • Gestión energía estable y probada
    • Algun intento para creare un nivel de red, por lo menos un repeater
    • Update del firmware fiable (?)
  • SW:
    • Prototipos de Reglas
    • Integración con servicios online de SMS y otros
  • Promo:
    • Web mas madura con blog, mailing list, Foro (?), Wiki (?), en Esp y Engl
    • Eventos fuera del Makespace
    • 4 Demonstradores en casas
    • Mega demonstrador en Makespace

Motivación[edit]

Hay muchas aplicaciones donde lo que queremos es simplemente un medio de enviar y recibir información sencilla sin tener que cablear toda el entorno. Un ejemplo es la casa, por ejemplo nos interesa saber que puertas o ventanas están abiertas, queremos apagar o encender tal luz o electrodoméstico etc.

Antecedentes[edit]

Hay muchos proyectos para redes de sensores y productos comerciales, pero ninguno hasta ahora verdaderamente barato (es decir <5€), ver Plataformas IOT.

El proyecto mas parecido al nuestro de momento es este, quitandole quizas los LEDs para ahorrar. Otro proyecto muy parecido es este.

Métodos y técnicas utilizadas[edit]

Requisitos:

  • cada nodo tiene una MCU y una conexión RF
  • el nodo base tiene que ser muy barato: < 5€
  • se tiene que poder programar con el IDE de Arduino
  • se tiene que poder alimentar con una pila de tipo botón o dos AA por un año


Funcionalidades que queremos:

  • recibe mensajes de la red de sensores a través de un nrf24 (probablemente conectado a través de un Arduino)
  • almacena historial de datos (BBDD)
  • permite controlar dispositivos actuadores (encender/apagar etc...)
  • lanza reglas del tipo if(...) then... mejor si definidas con un lenguaje alto nivel interpretado
  • almacena "escenarios de uso", por ejemplo: "escenario me voy de vacaciones": todo se apaga y se activa al alarma
  • que se conecte a servicios web externos tipo "enviar SMS" o "hacer un tweet"
  • la interfaz:
    • mejor si web, aunque se pueden pensar alternativas (movil, PC) etc.
    • que permita ver el estado de los dispositivos
    • que tenga gráficos para ver tendencias, explorar patrones etc.
    • que permita "actuar los actuadores" (pulso ON y se enciend la luz)
    • que permita crear escenarios de uso y activarlos
    • que permita definir reglas


Ideas para el Hardware[edit]


MCU[edit]

De momento nos centramos en un ATmega328. El coste puede llegar a ser inferior a 1 €. Placas micro compatibles Arduino (de donde poder copiar el diseño): femtoduino, Arduino mini pro

Pinout del ATMeag328: ATMega328P, nrf24l01

Alternativas son, para la MCU:

  • el ATtiny24 o 84 aunque sus capacidades son limitadas y no hay plena compatibilidad con Arduino. El precio de un Attiny24 es de medio euro.
  • Hay un tipo que ha conseguido conectar un ATTiny85 dejando tres pins libres ! Perfecto para hacer llaveros o super mini sensores.

MCU+RF24L01 producto final: http://www.mysensors.org/hardware/micro

Radio[edit]

Apostamos para el chip nRF24L01 de Nordic. Nos gusta porqué es lo mas barato que hay en el mercado.

Conexión de pines entre ATMega328 y el nrf24 según la librería de maniacbub (ver articulo original):

  • PD2 -> IRQ
  • PB0 -> CS
  • PB5 -> SCK
  • PB4 -> MISO
  • PB3 -> MOSI
  • PB1 -> CE
  • GND -> GND
  • VCC -> VCC

Antenas[edit]

Este post en hackaday puede ser una fuente muy interesante a la hora de hacer antenas


good pratices/usefull resource[edit]

Measure battey voltage with very low drain

pcb assemblers

pcb and stencils assemblers

Consejos para sensores[edit]

Tiempo[edit]

Presencia[edit]

  • PIR versión 3V
    • este modelo es una posibilidad: Supply current:DC3V-15V, Current drain :< 1mA, Voltage Output: High/Low level signal :3V

Movimiento[edit]

  • Accelerometros (a partir de 2€ e aliexpress)
  • Tilt, con estos se pueden crear sensores de movimiento baratos (por pocos centimos en aliexpress)

Plantas[edit]

Otras cosas[edit]

  • Una Application Note de Atmel sobre deteccion de zero-crossing en la corriente AC - se usaria si quisiesemos graduar el brillo de luces, y es un esquema muy simple comparado con el tipico basado en los TRIAC.

Ideas para el SW[edit]

Queremos la compatibilidad con Arduino, por eso nos centramos en chips AVR. Hay unas cuantas librerías para controlar el chip radio:

Y unos posts sobre el tema:


A esto podemos añadir:

Del lado "servidor" o sea el colectore de todas las medidas y generador de aplicaciones domoticas se puede usar:

Ideas para la red[edit]

Enrutamiento (VER Apuntes sobre enrutamiento con nrf24l01):

Avances[edit]

Estado Tareas[edit]

HW[edit]

  • elegir el programador adecuado
    • responsables: Dario
    • estado: pruebas hechas con distintos chips, ninguno me ha convencido al 100% todavia
  • crear la versión PL (power line)
    • responsables: ?
    • estado: ?
  • crear sensor temperatura
    • responsables: Dario
    • estado: algunas opciones recopiladas: termistor, pull ups, DHT. Falta montar uno.
  • crear Rele
    • responsables: ?
    • estado: ?
  • crear interruptor/botón
    • responsables: ?
    • estado: ?
  • crear luz RGB
    • responsables: Dario
    • estado: una versión ya existe, falta decidir si activarla con botón

FW[edit]

  • adaptar el protcolo a servidor
    • responsables: Dario, Bozo
    • estado: hecha implementación con JSON, parser JSON rudimental para Arduino completo
  • crear servicios para Temperatura, botón/interruptor, luz RGB
    • responsables: Dario
    • estado: codigo completo, falta testear
  • Bootloader, crear hardware Arduino compatible
    • responsable: Andrew
    • estado: en marcha

SW[edit]

  • crear primeros ejemplos
    • responsables: Bozo
    • estado: en marcha

Promo[edit]

  • comprar hosting PHP
    • responsables: Bozo (y los demas dan dinero)
    • estado: 0
  • montar primer Wordpress
    • responsables: ? (Dario se ofrece)
    • estado: nada

Log pruebas y reuniones[edit]

Pruebas 14/9/2013[edit]

Hemos testeado 4 módulos nRF24L01 con dos Arduinos, uno ha fallado, pero los otros tres se ha conectado etnre si. Hemos los cogidos de ejemplo de la librería RF24 que parece ser la mejor hecha. Hemos probado la conexion estrella y ha funcionado.

Decisiones: para la semana que viene vamos a intentar conectar un Atmega328p directamente a un modulo nRF24L01 en una placa de prototipado. Queremos producir 4 nodos e ir haciendo experimentos. Experimentos posibles:

  • mejor tipo de baterías, 2 AA? 1 de moneda de 3V ?
  • aguante de baterías
  • alcance de la comunicación
  • ir haciendo pruebas con el SW

objetivo final que hemos visualizado: una placa integrada con modulo radio y atmega, super pequeña, de bajo coste (<5€), con un kit de SW para redes de sensores. Como SW se considera incluso hacer un porting del stack 6loWPAN.


Pruebas 26/9/2013[edit]

Hemos montado el Atmega328p en la breadboard. Para programar el ATMega desde Arduino hemos seguido este tutorial. Hay dos fases: en una cargas el bootloader en el ATmega virgen. Para ello se necesita un Arduino que envíe el firmware por los pines del SPI. RECORDAR de cargar el sketch Arduino as ISP de la carpeta de los ejemplos !

En la segunda fase puedes cargar tus sketch, en este caso se usa el puerto serie, y se puede usar un Arduino quitandole el chip O un cable USB-to-serial (FTDI chip) si lo hay.

Primer prototipo

Para ir probando la comunicación con el nRF24L01 hemos cargado un sketch para usar el chip Nordic. Hemos utilizado la librería de maniacbug aquí y el codigo de ejemplo GettingStarted.

Para cargar el sketch en el ATmega hemos utilizado un cable FTDI y NO HA FUNCIONADO, no sabemos porqué. Entonces hemos usado el Arduino SIN MCU y HA FUNCIONADO. Hemos conectado el nRF24L01 según este esquema, cuidado con hacer el mapeado entre los pines de Arduino y los del Atmeg328 (ver aquí)!

El Atmega ve el chip y es capaz de enviar paquetes pero no de recibirlos. No sabemos porqué pero sospechamos que es por tener el clock a 8MHz en lugar de 16.Hay indicios de que afecta de alguna manera. El chip puede comunicar hasta 10 Mhz en el bus SPI. En la libreria tenemos SPI.setClockDivider(SPI_CLOCK_DIV4); Entonces con un un atmega328 @ 8 Mhz, 8/4 = 2 mbs , no debería haber problema. Otra posible causa pueden ser los delays().


Pasos a seguir:

Dario: va a enviar un correo al creador de la librería RF24 preguntandole cual es la mas actualizada y si el ve algún problema en tener un Arduino a 8MHz en lugar de 16Mhz.


Roberto: se encarga de ver los sockets e intenta programar el ATMega con el cable FTDI

Todos: resolver el problema de los 8MHz. Comprar socket para los chips. Construir primer prototipo.

Pruebas 3/10/2013[edit]

A veces el ATMega cuando envía un paquete imprime dos tipos de mensajes distintos:

  Now sending 22333...failed.
  Failed, response timed out.

o

  Now sending 23609...ok...Failed, response timed out.


La diferencia entre la primera linea y la segunda esta en este codigo (GettingStarted.pde):

  // First, stop listening so we can talk.
  radio.stopListening();
  
  // Take the time, and send it.  This will block until complete
  unsigned long time = millis();
  printf("Now sending %lu...",time);
  bool ok = radio.write( &time, sizeof(unsigned long) );
  if (ok)
    printf("ok...");
  else
    printf("failed.\n\r");


Pruebas hechas:

  • seteado SPI_CLOCK_DIV2 en RF24.cpp de la libreria RF24 de Maniacbug: NINGUN CAMBIO
  • comentado linea SPI_CLOCK_DIV en RF24.cpp: NINGUN CAMBIO
  • metiendo un condensador de 10 microF entre pin 3.3v y tierra: AHORA SOLO DA Now sending 23609...ok...Failed, response timed out.
  • metiendo 500 ms en lugar de 200 en esperar la respuesta: NINGUN CAMBIO
  • comprobado que los delay() y millis() sean buenos: son buenos (los segundos son segundos)

Al final hemos encontrado el problema: eran unos cables mal conectados entre el Arduino (no el Atmega) y la placa nfr (culpa de Roberto). CUIDADO con las librerías (maniacbug o mirf o Mike) que tienen distintos cableados !!!

Hemos quitado el condensador y la mitad de los paquetes se perdían.


Conclusiones:

  • la comunicación funciona entre los dos
  • meter condensador de 10microF es suficiente para no perder paquetes

Observacion: el modulo nrf24L01 tiene un oscilador a 16MHz, en una placa integrada se podría aprovechar también para el ATMega Para compartir el cristal, los CI tienen que estar cerca, un CI excita el crstal, mientras el otro solo "lee" la salida: http://forum.arduino.cc/index.php?topic=78584.0 .


Para la próxima: ir probando con baterías distintas, diseñar el prototipo


Pruebas 26/10/2013[edit]

Hemos probado a alimentar el ATMega con 3.3 V -> no funciona. A partir de 4.5 parece que funcione. Hemos intentado quitandole el brownout como sugiere este post(settings a 0xFF), pero nada.


Pruebas 27/10/2013[edit]

Bozo consigue enviar datos por serial a partir de una tensión de 2.3 voltios. Con 2.1 voltios funciona pero no arranca bien.

El circuito está hecho con una fuente regulable sin condensadores y un parpadeo de led. El .hex fue generado seleccionando "atmega 328 on bread board" como tipo de placa

  avrdude: Device signature = 0x1e950f
  avrdude: safemode: lfuse reads as E2
  avrdude: safemode: hfuse reads as D8
  avrdude: safemode: efuse reads as 7


Pruebas 28/10/2013[edit]

Roberto también consigue hacerlo funcionar. No he identificado el problema del otro día. Probado con dos pilas AA a 2.8v sin ningún problema. Con la salida de 3.3v de Arduino también funciona.

El valor de los fuses utilizados son los que proponía kerry Wong sin modificar el brown-out que de momento no ha sido necesario.

  low_fuses=0xE2
  high_fuses=0xDA
  extended_fuses=0x05


Pruebas 23/11/2013[edit]

Prueba de Dario para montar una placa integrada. Dado que no quiere esperar los zocalos se ha soldado PIC y chip radio todo juntos, como NO hay que hacer.


Conexión de pines:

ATMEGA -> NRF24L01:
PIN 4 PD2 -> PIN 8 NRF24 (IRQ)
PIN 15 PB1 -> PIN 3 NRF24 (CE)
PIN 16 PB2 -> PIN 4 NRF24 (CSN)
PIN 17 PB3 -> PIN 6 NRF24 (MOSI)
PIN 18 PB4 -> PIN 7 NRF24 (MISO)
PIN 19 PB5 -> PIN 5 NRF24 (SCK)


además hay que tener en consideración los pines de alimentación y para programar el PIC:

ATMEGA:
PIN 1 PC6 -> Reset
PIN 2 PD0 -> TX
PIN 3 PD1 -> RX
PIN 7 VCC -> 3V
PIN 8 GND -> GND
PIN 20 AVCC -> 3V (cuidado, es necesario cuanto el pin 7 !!)

NRF24:
PIN 1 GND -> GND
PIN 2 VCC -> 3V

Pruebas hechas:

  • con un sketch normal de Arduino (AnalogReadSerial) -> OK
  • con sketch de ejemplo de nrf24l01 (GettingStaretd) -> Parece que OK, me imprime:
  STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
  RX_ADDR_P0-1 = 0xf0f0f0f0d2 0xf0f0f0f0d2
  RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
  TX_ADDR = 0xf0f0f0f0d2
  RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
  EN_AA = 0x3f
  EN_RXADDR = 0x03
  RF_CH = 0x4c
  RF_SETUP = 0x07
  CONFIG = 0x0f
  DYNPD/FEATURE = 0x00 0x00
  Data Rate = 1MBPS
  Model = nRF24L01+
  CRC Length = 16 bits
  PA Power = PA_HIGH
  • con sketch scanner -> parece que OK, me imprime:
  RF24/examples/scanner/
  00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777777
  0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
  0001345696647c456565200279978c7ba66777960000000000000000000101310000000000000000000000000000000000000000000000000000000000000000
  000025457b9774b883663002674ca9987799b6863000000000000000066761022110000000000000000000000000000000000000000000000000000000000000
  000225652886a777078500125b5755bb87d967762000000000000000010054330000000000000000000000000000000000000000000000000000000000000000

Pruebas del 11/12/2013 al 17/12/2013[edit]

He hecho una larga serie de pruebas con distintas combinaciones inlcuyendo:

  • 1 placa casera con ATMega 328p + nrf24 y un Arduino sin PIC como lector serial
  • Arduino UNO con nrf24
  • Arduino Diecimila con nrf24
Segundo prototipo

Variables probadas:

  • alimentación del chip radio con el pin 3.3V de Arduino
  • alimentación del chip radio por 2 pilas AA
  • presencia (o no) de un condensador entre polos + y - como reserva de energía
  • canal de transmisión estandar y canal 100

ambos PICs programados con el sketch Getting Started de ManiacBug Los dos Arduinos estan conectados a mi ordenadro a traves de dos cables USB mientras puedo ver los puertos serie con un programita (RealTerm) abierto dos veces.


Resultados que he encontrado:

  • conviene siempre, por cada prueba, resetear los Arduinos para tenerlo todo listo
  • a veces, aunque el sketch Getting started debería empezar en modo 'R', en realidad no funciona, por lo cual es mejora pasar primero por una fase 'T' y luego volver a una fase 'R'
  • la alimentación 3.3V proporcionada por el Arduino no es suficiente, con un condensador mejora un poco, pero no del todo. Si alimentado con dos pilas funciona bien, incluso sin condensador (con pilas cargadas)
  • un condensador de capacidad mayor no mejora las cosas, de hecho las empeora

Pruebas 23/1/2014[edit]

Despues de haber perdido la cabeza con la librería de Maniacbug, y con la variante de Copeland, probé la librería de Mike y me funcionó perfectamente.

Hardware:

  • placa ad-hoc con Atmega328,NRF24 y un LED RGB conectado al PIC
  • Arduino Diecimila montado a un NRF24 y a tres potenciometros

Codigo:

  • la placa con LED se pone en escucha de 3 bytes en el pipe 1. Si los recibe modula los PWM de los tres colores del LED (analogWrite)
  • el Arduino con potenciometros lee el valor de ellos y si ha cambiado envía un paquete con 3 bytes con los tres valores correspondientes mapeados de 0 a 255

Resultado:

  • funciona ! prácticamente se realiza un mando a distancia del LED, la placa ad-hoc funciona también estando completamente aislada, es decir con sus pilas y sin conectar a nada mas
  • analizando la traza en el puerto serie del Arduino se puede ver que alrededor de 1/3 o 1/4 de los paquetes no reciben ACK

Pruebas 26/1/2014[edit]

Pruebas de Andrés (Andrew) tras recibir unos clones de Arduinos Pro Mini y módulos nRF24L01+ de China y soldar las conecciones entre los módulos y los Arduinos. Los Arduinos son de 5V y no tienen salidas 3.3V, se han usado 3 diodos en cada modulo para que este pueda ser alimentado con 5V, el voltaje baja unos 1.9V. Los demas pines del nRF24 son compatibles con 5V.

Despues de muchas pruebas conseguí transmisiones entre dos placas conectadas a diferentes puertos USB de una maquina. El programa simula una conexión serie - lo que recibe del puerto serie lo envía por radio, lo que recibe por radio lo devuelve por puerto serie. Por ahora no usa interrupciones, sin embargo usa la opcion "Dynamic Payload Size" del nRF24L01+ por lo que no es compatible con el chip nRF24L01 (sin el mas).

El programa lee los primeros 6 bytes del EEPROM del atmega, y usa los primeros 3 bytes como direccion propia, y los siguientes tres como dirección de destino de sus paquetes. Eso es porque al parecer ni los chips Atmega, ni los nRF24 contienen un numero serie unico que se pueda acceder desde el software, para asignar direcciones. Las direcciones las grabe al eeprom con el siguiente comando, en este ejemplo 73 6c 30 ("sl0" en ascii) es la direccion priopia y 73 6c 31 ("sl1") es la del destino,

  • $ avrdude -F -p atmega328p -P /dev/ttyUSB0 -c arduino -b 57600 -U eeprom:w:0x73,0x6c,0x30,0x73,0x6c,0x31:m

En otra ocasion corrijo algo en el codigo y empiezo a meter en github. El objetivo por ahora es que ese mismo codigo lo pueda usar el programa de arranque optiboot, para poder flashear las placas por radio.

Pruebas 4/2/2014[edit]

Andres consigue subir por radio el programa "Blink" de los ejemplos de Arduino mediante una version modificada de optiboot. Importante: La comunicacion todavia no es fiable y la mayoria de la veces la programacion falla en algun momento del proceso.

El hardware consiste en dos placas Arduino con dos modulos nRF24L01+ a distancia de ~50cm y conectadas con adapadores serie-USB a una maquina. El arduino A corre un programa "flasher" que principalmente hace de adaptador entre puerto serie y el nRF24L01+. El arduino B corre una version modificada de optiboot. El portatil corre avrdude. Por ahora el arduino B lo estoy reiniciando dandole al boton RESET a mano para que inicie optiboot. Avrdude se comunica con la placa A, sus comandos se envian tal cual a la placa B por radio, donde el optiboot las interpreta, enviando respuestas a placa A.

Creados dos repositorios,

  • https://github.com/balrog-kun/optiboot contiene la version de optiboot con sus modificaciones. Realmente el codigo nuevo es poco, pero depurarlo me ha costado bastante. Ademas del soporte nRF24L01+ tiene alguna mejoras mas, aunque cada opcion cuesta un incremento del tamaño. Con todo habilitado pesa 1.4kB mientras que el optiboot estandar solo 450 bytes (aun sigue siendo menos que el bootloader Arduino por defecto, de 2kB).
  • https://github.com/balrog-kun/lights contiene los programas "flasher" y "passthrough", luego tambien podra tener la version "puro C" del controlador de los Sensor Nodes / controladores de luz y/o electrodomesticos. "passthrough" es simplemente una pasarela entre puerto serie y nRF - con dos placas puede simular una coneccion serie. "flasher" es casi lo mismo, con la diferencia que antes de enviar cualquier dato envia un paquete consitente de solamente un byte 0xff, que se supone que va a forzar la otra placa que se reinicie (eso tendra que hacerlo el programa que va a correr en esa placa porque), y despues de 100ms un paquete de 3 bytes que contienen la direccion nRF24 a la que el optiboot va a responder.

Falta investigar porque a veces se pierde algun paquete... jugando con las dos placas en modo "pasarela" nunca me pierde ningun paquete. Eso a distancia de 50cm.

El problema de resetear el controlador "remoto" es complicado porque cada programa subido tendra que tener la posibilidad de reiniciar la placa por radio. Si en algun momento se sube codigo que no lo puede hacer (p.e. se cuelga), habra que reiniciarlo posiblemente con el interruptor general de la luz, en caso de alimentacion de la red, y en caso de alimentacion por bateria, a mano. Se puede usar el Watchdog Timer del AVR para reducir la probabilidad de que pase eso.

Pruebas 5/2/2014[edit]

He subido el código a mi repositorio github: https://github.com/dariosalvi78/Sensorino

1) he ido refinando y debugeando la libreria de base NRF24. La verdad es que me está costando, pero en cada avance que hago soluciono cosas que había. Me lo vais a agradecer.

2) he empezado a montar dos abstracciones de nivel superior: Sensorino y Base. Sensorino abstrae los medios de comunicación haciendo algunas asunciones que luego os explico. Base es lo mismo, solo que se supone que funciona como gateway hacia Internet y añade un protocolo por serial para hablar con el PC.

3) he empezado a montar protocolos de aplicación encima. De momento he montado y probado un protocolito para sincronizar el reloj de los Atmegas. Esto nos viene muy útil para marcar el tiempo en el cual se toman medidas, especialmente si tenemos que almacenar localmente medidas.

asunciones hechas:

  • las direcciones son de 4 bytes, tipo las IPs de IPv4
  • pipe 0 es de broadcast, es decir tiene una dirección compartida entre todos y no tiene ACKs
  • pipe 1 es el canal por defecto para comunicación unicast. Es un pipe compartido, por lo cual me ha sido necesario añadir una capa donde el remitente pueda especificar su dirección
  • los niveles superiores, o servicios, son identificados por un entero de 16 bits
  • hay tres tipos de "servicios": los en broadcast, para cuestiones de configuración de la red, los en unicast hacia la base, para enviar datos de medidas, y los unicast hacia los sensorinos, para activar cosas (tipo interruptores, actuadores etc.)

Pruebas 7/2/2014[edit]

Corregidos los problemas con fallos aleatorios durante programacion de Arduino por nRF24L01 pero hace falta comprobar si otros modulos se comportan de la misma manera ya que uno de los errores era muy raro - ocurria siempre que habia exactamente tres transmisiones seguidas y luego recepcion.

He hecho unas pocas pruebas muy poco cientificas de la tasa de fallos intentando flashear el mismo programa a la placa remota con avrdude. El programa de prueba tiene 4900 bytes, con lo cual avrdude envia cerca de 5400 bytes y recibe otros 5100 bytes (ya que siempre despues de escribir la memoria flash la vuelve a leer). Se transmiten y reciben alrededor de 550 paquetes, de tamaños entre 1 y 32 bytes. El nRF24 estaba configurado para tasa 1Mbps y hasta 15 retransmisiones. No tuve en cuenta la orientacion y polarizacion de las antenas, aunque todas antenas son direccionales.

  • a distancias < 5m la comunicacion parecia fiable, se pudo programar la placa remota 20 seguidas sin fallo.
  • a 5m a traves de una pared fallaba la mayoria de veces, pero algunas programaba bien.
  • a 9m a traves de dos paredes fallaba en promedio en el momento de haber subido 30-40% del programa, que seria despues de haber transmitido ~150-200 paquetes sin fallo, o sea que la tasa de error todavia debe ser baja (~1%).

Pruebas 13/2/2014: sleep, pin interrupt y watchdog[edit]

Estoy intentando poner el PIC a dormir y despertarlo con el watchdog o los interrupts externos.

Sleep: para el maximo ahorro se utiliza el SLEEP_MODE_PWR_DOWN

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();

En principio podríamos llegar a tener un consumo de solo 1uA !

Wakeup con watchdog: hay muchas guias que explican como funciona aqui, aqui o aqui.

Primero hay que habilitar el watchdog y su interrupción y que no resetee el PIC:

  MCUSR &= ~(1 << WDRF);
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = (1<< WDP1) | (1 << WDP2);
  WDTCSR |= _BV(WDIE);

Explicación: el registro WDTCSR se encarga de configurar el watchdog. Hay 8 bits: WDIF WDIE WDP3 WDCE WDE WDP2 WDP1 WDP0, según los configuremos obtendremos distintos comportamientos:

  WDE   WDIE       Mode              Action on Time-out
   0     0       Stopped                  None
   0     1      Interrupt               Interrupt
   1     0     System Reset              Reset
   1     1   Interrupt System Reset interrupt then go to system reset

Los tiempos se setean con el prescaler (WDP3 WDP2 WDP1 WDP0):

  WDP3 WDP2 WDP1 WDP0  Time-out at
   0    0    0    0     16 ms
   0    0    0    1     32 ms
   0    0    1    0     64 ms
   0    0    1    1     0.125 s
   0    1    0    0     0.25 s
   0    1    0    1     0.5 s
   0    1    1    0     1.0 s
   0    1    1    1     2.0 s
   1    0    0    0     4.0 s
   1    0    0    1     8.0 s

Y luego hay que programar una ISR:

  ISR( WDT_vect ) {
  //codigo aquí
  }

en la ISR conviene deshabilitar el watchdog para que no toque los huevos hasta que nos durmamos otra vez

Wakeup con interrupt en pin: una buena guía es esta. el problema es que si utilizamos el "External Interrupt Request" en modo sleep PWR_DOWN solo funciona cuando el pin va a LOW, además solo podemos utilizarlo para los pines 2 y 3. Entonces he utilizado los itnerrupts de pin change (PCINT0_vect, PCINT1_vect y PCINT2_vect), pero para programarlos hay que meter un poco de codigo porqué el API de Arduino no los incluye. Me he basado en esta documentación.

  //Programamos las ISR (no hacen nada y valen para todo tipo de pin)
  ISR(PCINT0_vect){
  }
  ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
  ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));

Luego es necesario identificar, en pase al pin en concreto, cual es el PCINT a utilizar en la mascara, para ello me he hecho una función:

  byte pinToInt(byte pin){
    if(pin <=7)
      return PCINT16 + pin;
    else if(pin >=8 && pin <=13)
      return PCINT0 + (pin-8);
    else return PCINT8 + (pin -14);
  }

Y el PCIE para habilitar el interrupt (se habilitan grupos de pines juntos, en 3 grupos):

  byte pinToIE(byte pin){
    if(pin <=7)
      return PCIE2;
    else if(pin >=8 && pin <=13)
      return PCIE0;
    else return PCIE1;
  }

y habilitamos:

  PCICR |= (1 << pinToIE(pinInt));
    if(pinInt <=7)
      PCMSK2 |= (1 << pinToInt(pinInt));
    else if(pinInt >=8 && pinInt <=13)
      PCMSK0 |= (1 << pinToInt(pinInt));
    else PCMSK1 |= (1 << pinToInt(pinInt));

Para una panoramica de como se nombran los pines y la correspondencia entre numero de pin, mascara, y registro para habilitarlos mirar este dibujo:

                      +-\/-+
   PCINT14      PC6  1|    |28  PC5 (AI 5)PCINT13
   PCINT16(D 0) PD0  2|    |27  PC4 (AI 4)PCINT12
   PCINT17(D 1) PD1  3|    |26  PC3 (AI 3)PCINT11
   PCINT18(D 2) PD2  4|    |25  PC2 (AI 2)PCINT10
   PCINT19(D 3) PD3  5|    |24  PC1 (AI 1)PCINT9
   PCINT20(D 4) PD4  6|    |23  PC0 (AI 0)PCINT8
                VCC  7|    |22  GND
                GND  8|    |21  AREF
   PCINT6       PB6  9|    |20  AVCC
   PCINT7       PB7 10|    |19  PB5 (D 13)PCINT5
   PCINT21(D 5) PD5 11|    |18  PB4 (D 12)PCINT4
   PCINT22(D 6) PD6 12|    |17  PB3 (D 11)PCINT3
   PCINT23(D 7) PD7 13|    |16  PB2 (D 10)PCINT2
   PCINT0 (D 8) PB0 14|    |15  PB1 (D 9) PCINT1
                      +----+
  
  pin  PICINT PCMSK
  0      16    2
  1      17    2
  2      18    2
  3      19    2
  4      20    2
  5      21    2
  6      22    2
  7      23    2
  8      0     0
  9      1     0
  10     2     0
  11     3     0
  12     4     0
  13     5     0
  PB5    6     0
  PB7    7     0
  A0(14) 8     1
  A1(15) 9     1
  A2(16) 10    1
  A3(17) 11    1
  A4(18) 12    1
  A5(19) 13    1
  PC6    14    1
  
  
  pin   -> PCINT -> PCMSK
  0-7   -> 16-23 ->  2
  8-13  -> 0-5   ->  0
  14-19 -> 8-13  ->  1

Pruebas 18/2/2014[edit]

Intentando desesperadamente usar mi board FTDI con una placa con ATMega 328 que he preparado. Mi board FTDI es como esta, está basada en el chip FT232 como la de Sparkfun, pero tiene que puedo elegir 5 y 3 voltios (por eso la preferí a otras). Uso los esquemas de esta web o {http://www.psyelmer9.info/3/post/2012/05/may-17th-2012.html esta] y nada, recibo solo caracteres NULL.

Que estará pasando?

Pruebas 23/2/2014[edit]

Diseño de base de un sensorino con reles listo para la cortadora laser del espacio
Base para montar placas de reles, arduino, nRF24, alimentador 220VAC -> 5V y regletas para coneccion de cables

La semana pasada consegui mejorar bastante la resistencia del bootloader a fallos de transmision y puse en el repositorio de optiboot todas las instrucciones de compilacion y uso. Con este nivel de resistencia a fallos ya lo veo listo para usar en el desarrollo de software. Hice pruebas a distancia de 12m entre los dos enchufes mas lejanos de mi casa, y a traves de muchas paredes. La fiabilidad se puede mejorar un poquito mas cambiando algunos parametros con el coste de hacer la comunicacion mas lenta, pero la distancia maxima ahora (es decir las condiciones minimas del entorno de radio) creo que es cercana a distancia maxima absoluta a la que dejan de llegar paquetes con el hardware dado y ninguna modificacion de software lo puede remediar.

He investigado lo de antenas PCB por un lado para entender un poco para cuando posiblemente diseñemos placas Sensorino propias, por otro lado para entender las propiedades de las antenas que usan los modulos que utilizamos por ahora (los mas populares de ebay). Texas Instrumens tiene una guia para seleccion de antenas PCB. De las que se presentan, la de nRF24 es mas parecida a la Meandered Inverted-F Antena (MIFA), la que se describe en mas detalle en este doc. El patron de radiacion es bastante mas irregular que en las antenas simples tipicas, se acerca mas a isotropico pero es tan complejo que seria dificil orientar las antenas exactamente para mejorar distancias. El doc tambien dice que en los interiores la cantidad de reflexiones hace que la polarizacion no sea importante, la conclusion es que no vale pena tomar en cuenta ni la polarizacion ni orientacion de las placas.

Con la ayuda de Mac hemos preparado una base para el sensorino de control de luces en mi casa. El fichero fuente es un SVG de Inkscape con dos capas, la de corte y la de grabado, se podria usar con madera (contrachapado) o acrilico. Todos los elementos se han convertido a Paths para que el MoshiDraw lo lea correctamente. Estoy progresivamente montando los elementos en la placa cortada en acrilico. El tamaño es el de una caja de distribucion de las que estan en las paredes.

Hoy implemente la opcion FORCE_WATCHDOG=1 en el optiboot con la cual el watchdog queda habilitado antes de arrancar la aplicacion de usuario, con el timeout de 4s. Esta opcion es la ultima que considero necesaria para desarrollo remoto. La aplicacion puede deshabilitar o reconfigurar el watchdog si lo necesita para otros usos, pero es recomendable que no lo toque, para que la placa automaticamente vuelva al bootloader en caso de que la aplicacion falle/muera/no responde etc. para no tener que reiniciarla a mano lo que podria ser dificil o imposible si es empotrada (si se alimenta de la red, se puede reiniciar con el interruptor general de casa). La implementacion fue dificil porque optiboot internamente usa el watchdog y se tiene que distinguir entre un reinicio del watchdog dentro de bootloader (el normal) y dentro de aplicacion (el no deseado) y mi primera idea no funciono por un truco que usa GCC para reducir el tamaño de codigo.

Reunión 24/2/2014[edit]

Hemos hablado del proyecto en general y hemos acordado que merece la pena lanzar primero una comunidad open source y luego plantearse lo del Kickstarter. Hemos fijado cuatro planos de trabajo:

  • HW: el diseño de las placasa
  • FW: el software para los conrtoladores, incluido bootloader, librerías y sketches
  • SW: el servidor que corre en casa
  • Promo: promoción, eventos, documentación

De momento los milestones quedan fijados así:

Milestone 0

Fecha: 15 Mayo

  • HW:
    • placa base con ATMega con patas gordas y nrf24 modulo chino, todo hecho a mano. Por lo menos 5 unidades.
      • Sensores/actuadores: luz, temperatura, interruptor/botón, Luz RGB, Relé
    • placa BASE, con conexiones al ordenador (o shield para Arduino). Un par de unidades.
    • placa PL (powerline) con transformador incluido, logica 5V y DC converter. Por lo menos 3.
    • Shield para progrmar el ATMega y hacer algún test
  • FW:
    • Versión base de librerías Sensorino con algunos servicios hechos
    • Update del firmware remoto
  • SW:
    • Visualización basica
    • Actuación
    • comunicación con base
    • servicios Sensorino base implementados
  • Promo:
    • Primer evento Sensorino en Makespace
    • Primer Wordpress basico montado

Milestone 1

Fecha: ?

  • HW:
    • Placas PCB hechas y estables para versiones mini, PL y base con ATMega con pines gordos y nrf chino
    • primeros intentos con SMD
    • Shield de apoyo para producción rapida de ATMega
  • FW:
    • Gestión energía estable y probada
    • Algun intento para creare un nivel de red, por lo menos un repeater
    • Update del firmware fiable (?)
  • SW:
    • Prototipos de Reglas
    • Integración con servicios online de SMS y otros
  • Promo:
    • Web mas madura con blog, mailing list, Foro (?), Wiki (?), en Esp y Engl
    • Eventos fuera del Makespace
    • 4 Demonstradores en casas
    • Mega demonstrador en Makespace


Pruebas 28/2/2014[edit]

1) he medido el valor de la resistencia de pull up interna del pina anlogico 0 de mi Arduino. Para ello he puesto una resistencia de 100K entre el pin y tierra.

Según la formula, Rpu = 100000 ((1023/v)-1)

He cogido unas 150 muestras (una por segundo):

  • Media: 38433.62
  • STD: 309.20 que es el 0.8% de la media
Relación temperatura interna externa

2) he medido la temperatura externa usando un termistor que me he comprado y midiendo la resistencia con un partidor con 10K, Rt = 10000 ((1023/v)-1) y aplicando la formula de Steinhart–Hart.

He comparado los valores medidos con los de un termometro a mercurio y parecen coincidir.

También he repetido las medidas con el termistor puesto con el pull up interno del ATMega y hay una variación de 1 grado mas o menos. En este caso la formula a aplicar es distinta: R = Rpu/((1023/v)-1)

3) he medido la temperatura interna del ATMega con este codigo y he puesto en relación el valor del ADC con la temperatura medida con el termistor externo.

La relación es lineal, pero hay algo de margen de error.


4) Quiero hacer un sensor de luz binario, o sea uno que me avise cuando la luz esté encendida o apagada. La idea es utilizarlo para, por ejemplo, la nevera. Quiero entonces que el sensor esté apagado todo el tiempo, hasta que no detecte el cambio.

Como lo hago? Con un fototransistor ! he comprado este.

Lo he conectado en configuración de divisor de tensión con un pin digital, por la resistencia de pull down he observado que cuanto mas grande la resistencia, mas sensible es la detección. Al final para mi foto transistor, y un Arduino UNO a 5V me he decantado para 560K. No se si valdría lo mismo con tensiones mas bajas. Si a alguno de vosotros se os ocurre la manera de calcularlo de hecho os doy un premio.


Pruebas 3/3/2014[edit]

he creado un proto-parser para JSON para la base. Puede buscar un dato, parsear enteros, doubles y booleanos y puede separar cadenas en un array (util para sacar la dirección de un Sensorino).

He montado los servicios de:

  • LightService (para sensores de luz)
  • RGBService (para luces RGB)
  • TempHumService (para sensores de temperatura/humedad)
  • SwitchService (para botones/interruptores/switches)

con sus paquetes y sus comandos JSON. Falta testearlos.

Pruebas 12/3/2014[edit]

He ido probando convertidores USB -> serial para programar el ATMega 328. He comprado unos cuantos basados en tres chips: FT323, CP2102 y PL2303HX. Son todos distintos ! los pines no se coinciden en ningún caso, por lo cual una vez elegido el que mejor funcione, habrá que soldar los pines de manera apropiada.

1) FTDI Basic Program Downloader USB to TTL FT232 for Arduino

es igualito igualito que otro que tengo que no funciona ni para atrás:

  • 3V? si
  • puerto reconocido en Windows: si
  • upload del sketch: funciona
  • monitor puerto serie: funciona, pero necesita un condensador y una resistencia entre el pin y Vcc según pone este esquema


2) USB to TTL CP2102 Module for STC Download

necesita driver (por lo menos en Windows)

  • 3V? si
  • puerto reconocido en Windows: si
  • upload sketch: hay que resetearlo a mano
  • monitor puerto serie: si

he podido observar que el reset en realidad no funciona, porqué al reabrir el monitor serie de Arduino el chip no se reiniciaba

3) PL2303HX USB to TTL Converter Module

no tiene pin de reset

  • 3V? si
  • puerto reconocido en Windows: si
  • upload sketch: si, pero tengo que hacer el reset a mano
  • monitor puerto serie: si, recibe


4) PL2303HX Converter USB to TTL USB to COM Cable Module (Black, 1m)

no tiene pin de reset

  • 3V? ni idea
  • puerto reconocido en Windows: si
  • upload sketch: va, pero con un reset manual
  • monitor puerto serie: si, recibe por lo menos


Hay un video que lo explica todo muy bien: http://www.youtube.com/watch?v=Vawhrr4COjI

  • con el ft323 se necesita el condensador extra. El Arduino mini lo tiene ya puesto.
  • las placas basadas en cp2102 estandar necesitan soldar un pin a mano (por lo menos las que se venden por ahi)
  • las basadas en PL2303HX tienen algún problema de driver, ademas la mía no tiene pin de reset ni siquiera

el tipo del video al final se decanta para una placa basada en cp2102 con reset montado, he intentado buscarla en aliexpress y hay unas cuantas como esta. Lo que no sabemos es si sigue siendo necesario añadir el condensador y la resistencia, pero yo me temo que si.


Opciones para Sensorino:

  1. añadimos condensador y resistencia en nuestra placa y hacemos que sean programables por FT232 sin nada mas
  2. no añadimos nada, y pedimos al usuario que enchufe el Sensorino cuando el programador avr esté listo para subir el código, esto hace que sea compatible con la mayoría de programadores
  3. si con la placa cp2102 NO fuera necesario añadir condensador y resistencia, usaríamos esta y punto