Difference between revisions of "Sensorino"
Dario Salvi (Talk | contribs) (→Avances: añadida sección de sleep) |
Dario Salvi (Talk | contribs) (→Avances: cambiado las pruebas a sub seccion) |
||
Line 124: | Line 124: | ||
====Avances==== | ====Avances==== | ||
− | + | =====Pruebas 14/9/2013:===== | |
− | + | ||
Hemos testeado 4 módulos [[nRF24L01]] con dos Arduinos, uno ha fallado, pero los otros tres se ha conectado etnre si. | Hemos testeado 4 módulos [[nRF24L01]] con dos Arduinos, uno ha fallado, pero los otros tres se ha conectado etnre si. | ||
Line 143: | Line 142: | ||
− | + | =====Pruebas 26/9/2013:===== | |
Hemos montado el Atmega328p en la breadboard. | Hemos montado el Atmega328p en la breadboard. | ||
Line 174: | Line 173: | ||
Todos: resolver el problema de los 8MHz. Comprar socket para los chips. Construir primer prototipo. | Todos: resolver el problema de los 8MHz. Comprar socket para los chips. Construir primer prototipo. | ||
− | + | =====Pruebas 3/10/2013===== | |
A veces el ATMega cuando envía un paquete imprime dos tipos de mensajes distintos: | A veces el ATMega cuando envía un paquete imprime dos tipos de mensajes distintos: | ||
Line 223: | Line 222: | ||
− | + | =====Pruebas 26/10/2013:===== | |
Hemos probado a alimentar el ATMega con 3.3 V -> no funciona. A partir de 4.5 parece que funcione. | Hemos probado a alimentar el ATMega con 3.3 V -> no funciona. A partir de 4.5 parece que funcione. | ||
Line 229: | Line 228: | ||
− | + | =====Pruebas 27/10/2013:===== | |
Bozo consigue enviar datos por serial a partir de una tensión de 2.3 voltios. | Bozo consigue enviar datos por serial a partir de una tensión de 2.3 voltios. | ||
Line 243: | Line 242: | ||
− | + | =====Pruebas 28/10/2013:===== | |
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. | 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. | ||
Line 254: | Line 253: | ||
− | + | =====Pruebas 23/11/2013:===== | |
Line 314: | Line 313: | ||
000225652886a777078500125b5755bb87d967762000000000000000010054330000000000000000000000000000000000000000000000000000000000000000 | 000225652886a777078500125b5755bb87d967762000000000000000010054330000000000000000000000000000000000000000000000000000000000000000 | ||
− | + | =====Pruebas del 11/12/2013 al 17/12/2013:===== | |
He hecho una larga serie de pruebas con distintas combinaciones inlcuyendo: | He hecho una larga serie de pruebas con distintas combinaciones inlcuyendo: | ||
Line 341: | Line 340: | ||
* un condensador de capacidad mayor no mejora las cosas, de hecho las empeora | * un condensador de capacidad mayor no mejora las cosas, de hecho las empeora | ||
− | + | =====Pruebas 23/1/2014:===== | |
Despues de haber perdido la cabeza con la librería de Maniacbug, y con la variante de Copeland, probé la [http://www.airspayce.com/mikem/arduino/NRF24/ librería de Mike] y me funcionó perfectamente. | Despues de haber perdido la cabeza con la librería de Maniacbug, y con la variante de Copeland, probé la [http://www.airspayce.com/mikem/arduino/NRF24/ librería de Mike] y me funcionó perfectamente. | ||
Line 354: | Line 353: | ||
Resultado: | Resultado: | ||
− | * funciona ! | + | * 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 | * 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:===== | |
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. | 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 | + | 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 | + | 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 | * $ avrdude -F -p atmega328p -P /dev/ttyUSB0 -c arduino -b 57600 -U eeprom:w:0x73,0x6c,0x30,0x73,0x6c,0x31:m | ||
Line 369: | Line 368: | ||
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. | 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:===== | |
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. | 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. | ||
Line 383: | Line 382: | ||
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. | 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:===== | |
− | He subido el | + | 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. | 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. | ||
Line 401: | Line 400: | ||
* 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.) | * 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:===== | |
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. | 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. | ||
Line 411: | Line 410: | ||
* 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%). | * 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:===== | |
Estoy intentando poner el PIC a dormir y despertarlo con el watchdog o los interrupts externos. | Estoy intentando poner el PIC a dormir y despertarlo con el watchdog o los interrupts externos. |
Revision as of 20:03, 13 February 2014
Contents
- 1 Nombre proyecto
- 1.1 Objetivo
- 1.2 Motivación
- 1.3 Antecedentes
- 1.4 Métodos y técnicas utilizadas
- 1.5 Detalles
- 1.5.1 Low power
- 1.5.2 Ideas para el Hardware
- 1.5.3 Ideas para el SW
- 1.5.4 Avances
- 1.5.4.1 Pruebas 14/9/2013:
- 1.5.4.2 Pruebas 26/9/2013:
- 1.5.4.3 Pruebas 3/10/2013
- 1.5.4.4 Pruebas 26/10/2013:
- 1.5.4.5 Pruebas 27/10/2013:
- 1.5.4.6 Pruebas 28/10/2013:
- 1.5.4.7 Pruebas 23/11/2013:
- 1.5.4.8 Pruebas del 11/12/2013 al 17/12/2013:
- 1.5.4.9 Pruebas 23/1/2014:
- 1.5.4.10 Pruebas 26/1/2014:
- 1.5.4.11 Pruebas 4/2/2014:
- 1.5.4.12 Pruebas 5/2/2014:
- 1.5.4.13 Pruebas 7/2/2014:
- 1.5.4.14 Pruebas 13/2/2014:
Nombre proyecto
ESTADO: PRIMERAS PRUEBAS
Miembros: User:Dario_Salvi, User:Bozo, User:Roberto Zabala
Objetivo
construir una red de sensores compatibles con el IDE de Arduino y que cuesten menos que 5 € con todo incluido.
Motivación
Hay muchas aplicaciones donde lo que queremos es simplemente un medio de enviar y recibir información sencilla sin tener pero 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
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
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
Estamos buscando alternativas, abajo hay una recopilación de posibilidades.
Detalles
Low power
https://www.sparkfun.com/tutorials/309 http://www.gammon.com.au/forum/?id=11497
Ideas para el Hardware
De momento nos centramos en un ATmega328 y en el chip nRF24L01 de Nordic. El coste de los dos puede llegar a ser inferior a 1 €. Placas micro compatibles Arduino (de donde poder copiar el diseño): femtoduino, Arduino mini pro
Asignación de pines 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
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.
Pinouts: ATMega328P, nrf24l01
Otros:
- 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
Queremos la compatibilidad con Arduino, por eso nos centramos en chips AVR. Hay unas cuantas librerías para controlar el chip radio:
- mirf, licencia tipo GPL, es la oficial de Arduino playground
- RF24 de maniacbug, GPL V2
- NRF24 de Mike, GPL V2
- fork de Greg Copeland de RF24, GPL V2, mas reciente que el original
- fork de Stanley Seow de RF24, GPL V2, que incluye soporte para RaspberryPi
- fork de Arco van Geest que incluye soporte para RaspberryPi
Y unos posts sobre el tema:
- MUY BUEN POST sobre las librerías que hay hasta ahora para nRF24L01
- ejemplos de Mirf
- ejemplos de RF24
- post sobre fork de Stanley Seow
- soporte en google groups para NRF24
A esto podemos añadir:
- enrutamiento (VER Apuntes sobre enrutamiento con nrf24l01):
- SARA
- algoritmo hecho para nrf24 de maniacbug con su entrada de blog
- este otro que parece mas prototipal
- este que parece muy bueno!
- la librería de ATmel?
- algoritmo de encriptación: TEA o su version mas avanzada XTEA
- IP en Arduino con SLIP?
- compatibilidad con el stack IETF 6LoWPAN/IPv6 + RPL + CoAP? aqui
- un sistema operativo embedded? RTOS o Contiki
- sensores "internos" del ATmega. Flipas. voltimetro y termometro
Del lado "servidor" o sea el colectore de todas las medidas y generador de aplicaciones domoticas se puede usar:
- OpenHab
- domotichome
- Emoncms para la parte energetica
- [www.souliss.ne Souliss] aunque parece suportar solo Ethernet o Wifi
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
Avances
Pruebas 14/9/2013:
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:
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.
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
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:
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:
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:
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:
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:
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
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:
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:
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:
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:
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:
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:
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 que programar una ISR
ISR( WDT_vect ) { //codigo aquí }
y habilitar el watchdog y su interrupción y que no resetee el PIC:
MCUSR &= ~(1 << WDRF); WDTCSR |= (1 << WDCE) | (1 << WDE); WDTCSR = (1<< WDP0) | (1 << WDP3); WDTCSR |= _BV(WDIE);
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