Paso 4: Módulo receptor Arduino
Vamos a pasar a la parte más difícil, el módulo de receptor de Arduino que llamo a la "madre" Arduino. Realmente no es tan difícil, pero tienes que prestar atención.
Como antes vamos a empezar por el cableado hasta el Arduino. Una vez más usé pin 2 en el Arduino para pin de datos y el pin 3 pin de datos del transmisoral receptor. La Junta de Bluefruit está conectada como sigue (configuración predeterminada):
- CTS en el pin 11
- TXO en pin 10
- RXI en pin 9
- VIN en 5V
- GND a GND
Los pines MOD, RTS y DFU no se utilizan en este ejemplo. Tenga en cuenta que para este ejemplo el Bluefruit Junta debe ajustarse al modo CMD en el pequeño interruptor.
Había conectado 3 LED' s con una resistencia de 220 Ω para cada uno de ellos a los pines 5, 6 y 7. Esto es opcional, pero puede ser útil en algunos casos.
Ahora que el cableado se realiza, podemos comenzar la codificación. Usted necesitará varias bibliotecas para hacerlo funcionar. Las bibliotecas de Arduino.h, SPI.h y SoftwareSerial.h son ya presente en el IDE de Arduino y RH_ASK.h es el que utilizamos en el código anterior. Las bibliotecas de Adafruit_BLE.h, Adafruit_BluefruitLE_SPI.h y Adafruit_BluefruitLE_UART.h pueden descargarse del sitio web de Adafruit. BluefruitConfig.h es un archivo de configuración para el tablero de Bluefruit.
#include < Arduino.h >#include < RH_ASK.h >
#include <SPI.h >
#if no definido (_VARIANT_ARDUINO_DUE_X_) & & no definido (_VARIANT_ARDUINO_ZERO_)
#include <SoftwareSerial. h >
#endif
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"
Aquí están las variables globales utilizadas en este código:
Las variables de nbRooms define el número total de habitaciones, asegúrese de que este cambia si se utiliza más o menos que transmisor 3 Arduinos
Las variables de valores es una matriz de nbRooms de longitud que se utilizará para almacenar los datos recibidos desde el transmisor de Arduinos.
La variable LEDpin es una matriz que contiene los números de pin para el LED.
La variable de límite es una matriz que almacenará los límites de la luminosidad en la cual se consideran las luces encendido o apagado. Tenga en cuenta que me olvide de reemplazar los 3 con la variable nbRooms , lo que debe hacer.
Las variables tiempo y currentTime se utilizan para almacenar valores obtenidos de la función millis .
La variable dataToSend se utiliza para almacenar los datos a lo Smartphone
La variable de peticiones es una matriz de char que contiene el pide que le envíe el transmisor Arduinos. No te olvides de cambiar esto si está utilizando un diverso número de transmisores.
La * solicitud de variable es un puntero a la solicitud a la emisora Arduino.
Los valores booleanos gotResponse, firstRequest y envío serán explicados más adelante.
int valores [nbRooms]; Se utiliza para almacenar los datos recogidos de los transmisores de los
int LEDpin [] = {5, 6, 7}; Pines utilizados para los LEDs
límite de int [3]; Se utiliza para almacenar los límites de luminosidad en el que la luz se considera de
Se utiliza para almacenar los valores millis()
tiempo de unsignedlong;
currentTime unsignedlong;
DataToSend cadena; Se utiliza para almacenar los datos enviados para el Smartphone
char * pide [] = {"a0", "a1", "a2"}; Se utiliza para almacenar los pedidos, no olvide cambiarlo si usa más o menos que transmisor 3 Arduinos
char * solicitar; Se utiliza para almacenar la solicitud a
bool gotResponse = false;
bool firstRequest = true;
bool bleIsConnected = false;
envío de bool = true; Para detener la difusión de BLE
En esta parte creamos los objetos necesarios.
Como antes de crear el objeto RH_ASK llamado driver, pero esta vez necesitará configurar el pin de Ptt a un inusitado pin (o -1) ya que el valor predeterminado es pin 10 que ya es utilizado por la Junta de Bluefruit.
Luego creamos los objetos bluefruitSS y ble . Los parámetros utilizados para estos objetos son los especificados en el archivo BluefruitConfig.h .
Parámetros para el SoftwareSerial y Adafruit_BluefruitLE_UART almacenados en el archivo BluefruitConfig
BluefruitSS SoftwareSerial = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);
Ble de Adafruit_BluefruitLE_UART (bluefruitSS, BLUEFRUIT_UART_MODE_PIN, BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
Siguientes son algunas definiciones de configuración. El primero de ellos especifica si desea que la Junta Bluefruit realizar un factory reset cuando se inicia. El segundo define la versión de firmware mínimo y por último el comportamiento de la red LED en el tablero. Recomiendo tocar esos parámetros.
#define FACTORYRESET_ENABLE 1#define MINIMUM_FIRMWARE_VERSION "0.6.6"
#define MODE_LED_BEHAVIOUR "Modo"
En la parte de configuración se iniciará colocando los pasadores LED a modo de salida . Luego establecemos todos los límites en 0 para que no sean null, que nos impiden hacer cualquier comparación. Que se las cambien en la aplicación móvil más tarde.
voidsetup(void){
para (int i = 0; i < sizeof(LEDpin); i ++)
{
pinMode (LEDpin [i], salida); Pasadores LED inicialización
}
para (int i = 0; i < nbRooms; i ++)
{
límite [i] = 0; Inicializar los límites en 0
}
Serie.begin(9600); Para la depuración
Si (! driver.init()) / / si los módulos de RF se ha podido inicializar
Serie.println ("init error");
Esta parte de la configuración encarga de la configuración del tablero de Bluefruit. La función setupBluefruit se explicará más adelante. El código que cambia el modo de LED de la board (si la versión del firmware es menos 0.6.6) y luego ajuste la Junta a modo de datos, por lo que se puede comunicar con el teléfono inteligente.
setupBluefruit();Serie.println(F("***"));
Comando de actividad LED sólo es compatible de 0.6.6
Si (ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION))
{
Cambiar modo LED de actividad
Serie.println (F ("Actividad cambio LED" MODE_LED_BEHAVIOUR));
ble.sendCommandCheckOK ("AT + HWModeLED =" MODE_LED_BEHAVIOUR);
}
Módulo de sistema a modo de datos
.Println serieF ("conmutación al modo de datos!");
ble.setMode(BLUEFRUIT_MODE_DATA);
Serie.println(F("***"));
}
En la parte del bucle , se encargará de la recepción de los datos desde el transmisor de Arduinos, la transmisión de datos para el Smartphone y la recepción de los límites desde el Smartphone.
Es la parte de recopilación y transmisión de datos dentro de un if expresión que puede detener la difusión de BLE si quiere, que no hice.
Luego recorrer cada habitación, el gotResponse se establece en false y luego enviar una solicitud. Al mismo tiempo empezamos un temporizador asignando un valor a la variable de tiempo con la función millis .
{
Si (envío) / / para detener la difusión de BLE
{
para (int i = 0; i < nbRooms; i ++)
{
gotResponse = false;
Enviar solicitud
tiempo = millis(); Temporizador de arranque
sendRequest(i); Enviar solicitud a transmisor Arduino
Mientras que no hemos recibido ninguna respuesta desde el transmisor de Arduino, almacenar el valor de millis en la variable currentTime para comparar a tiempo. Si la diferencia supera los 500 milisegundos, significa que el mensaje se perdió y que tenemos que enviar otra solicitud. También tenemos que restablecer la variable de tiempo .
Recibir respuestamientras (! gotResponse) / / mientras que no se ha recibido ninguna respuesta
{
currentTime = millis();
Si (currentTime - tiempo > 500) / / Si 0.5 segundos ha pasado sin recibir ninguna respuesta, enviar solicitud
{
tiempo = millis(); Restablecer el temporizador de
Serie.println ("sin respuesta después de 0,5 segundo, solicitud de reenvío");
sendRequest(i);
}
Una vez más creamos un buffer para almacenar los datos recibidos. A la recepción, guardar el mensaje en una variable de cadena y analizar los valores de datos y sala . Si la sala coincide con la esperada, entonces establezca gotResponse en true y almacenar los datos en la matriz de valores .
uint8_t buf [4]; Búfer utilizado para almacenar los datos recibidos, su tamaño se establece en 3 bytes, los datos son: String(room) + valor (ej. 0555)uint8_t buflen = sizeof(buf);
Si (driver.recv (buf & buflen)) / / tras la recepción de los datos
{
Cadena de mensaje = (char *) buf; Almacenamiento de datos en una cadena para el análisis de
Sala int = message.substring (0, 1).toInt(); Analizar el número de habitación
int datos = message.substring(1).toInt(); Análisis de datos
Si (Sala == i) / / si los datos son de la habitación correcta
{
gotResponse = true;
valores [sala] = datos; Almacenar los datos
En esta parte nos encargamos de la iluminación de los LEDs. Esto es opcional.
Encendiendo y apagando LEDSi (valores [sala] > limit[room])
{
digitalWrite (LEDpin [i], alto);
}
otra cosa
{
digitalWrite (LEDpin, [i], LOW);
}
Para la depuración
Serie.print ("datos para el sitio");
Serie.print(room);
Serie.print ("es");
Serie.println(data);
Serie.println("");
}
}
}
Delay(50);
}
Una vez que hemos recibido y verificado los datos desde todas las habitaciones, podemos pasar a la transmisión de los datos para el Smartphone. El mensaje comienza con un "#" y termina con un "*" con el fin de analizar fácilmente en la aplicación de Smartphone. También separamos los valores por una "/".
dataToSend = "#"; Iniciar cadena de datos con # para easyier análisis por la aplicación para Smartphonepara (int i = 0; i < nbRooms; i ++)
{
dataToSend.concat(String(values[i]));
Si (i < nbRooms - 1)
{
dataToSend.concat("/"); Separar los valores con una /
}
}
dataToSend.concat("*"); Poner fin a la cadena de datos con *
Serie.print ("enviando:");
Serie.println(dataToSend);
Serie.println("");
}
El mensaje entonces es almacenado en una matriz de char y enviado a la pizca de Smartphone el método ble.print .
char n, entradas [BUFSIZE + 1]; Utiliza para almacenar datos a SmartphonedataToSend.toCharArray (insumos, BUFSIZE + 1); Copia de cadena de datos en buffer
ble.Print(Inputs); Envío de datos
Procede a la recepción de los límites por el Smartphone. Empezamos por crear una variable de cadena denominada valores (no es el mismo que la matriz int!) que se almacenan los caracteres recibidos a través de la conexión BLE. Una vez que hemos leido el #, es decir, el punto de partida del mensaje, establecemos la variable registro verdadero que permita la concatenación de los siguientes caracteres a la variable de valores , hasta el * se lee. Cuando el mensaje esté completo, que analizar y almacenar los límites utilizando la función de como se explicará más adelante.
Valores de cadena = ""; Vaciar la cadena de datosLectura de datos desde Smartphone
grabación de bool = false;
mientras (ble.available()) / / mientras hay datos en BLE
{
int c = ble.read();
Serie.println((char)c);
Si (grabación) / / si hemos leído la #
{
Si ((char) c! = ' *')
{
Values.concat((Char)c); Como c es diferente del carácter de final *, añadir a la secuencia de datos
}
otra cosa
{
Serie.println(values); setLimits(values);
registro = false; Establecer los límites a los que acaba de recibir
valores = "";
}
}
Si (c (char) == '#') / / iniciar la grabación a la recepción del inicio carácter #
{
registro = true;
}
}
}
Aquí están las funciones utilizadas en el código.
El primero muestra un mensaje de error y detiene la ejecución del programa.
void errores (__FlashStringHelper const * err)
{
Serie.println(err);
mientras (1);
}
Esta función configura el tablero de Bluefruit cuando empieza. Realiza también una fábrica de reiniciar si se ha activado.
void setupBluefruit(){
/ * Inicializar el módulo * /
Serie.print (F ("inicializar el módulo de Bluefruit LE:"));
Si (! ble.begin(VERBOSE_MODE))
{
error (F ("no pudo encontrar Bluefruit, asegúrese de que esté en el modo comando y verifique el alambrado?"));
}
Serie.println (F("OK!"));
Si (FACTORYRESET_ENABLE)
{
/ * Realizar un factory reset para asegurarse de que todo está en un estado conocido * /
Serie.println (F ("realizar un factory reset:"));
Si (! ble.factoryReset()) {}
error F ("no podía restablecer de fábrica");
}
}
/ * Deshabilitar comandos echo de Bluefruit * /
ble.echo(false);
Serie.println ("información de Bluefruit solicitando:");
/ * Imprimir información de Bluefruit * /
ble.info();
ble.verbose(false);
}
Esta función se utiliza para enviar solicitudes al transmisor Arduinos, con el número de identificación de la sala como parámetro.
Enviar una solicitud al correspondiente transmisor de sala (i)void sendRequest(int i)
{
petición = solicitudes de [i];
solicitud de ((uint8_t *) de driver.Send, strlen(request));
driver.waitPacketSent();
Serie.print ("pedido enviado a sala");
Serie.println(i);
Serie.println ("espera respuesta");
Serie.println("");
}
Esta función analiza el mensaje límite recibió desde el Smartphone y almacena los límites de la matriz de límite .
Almacenar los límitesvoid setLimits(String values)
{
para (int i = 0; i < nbRooms; i ++)
{
Si (i < nbRooms - 1)
{
límite [i] = values.substring (4 * i, 3 + 4 * i).toInt(); Pärsing los límites
}
otra cosa
{
límite [i] = values.substring (4 * i).toInt(); Análisis del límite último
}
}
}