Med hjälp av sensorer, 433Mhz RF moduler och Adafruit's BLE Bluefruit chip för att samla uppgifter om Smartphone med Evothings Studio (4 / 6 steg)
Steg 4: Arduino mottagare modul
Låt oss gå över till svåra, Arduino mottagare modul som jag kallar "modern" Arduino. Det är faktiskt inte så svårt, men du måste betala uppmärksamhet.
Som innan vi börjar med kabeldragning upp Arduino. Återigen använde jag stift 2 på Arduino för mottagarendata pin och pin 3 för sändarendata stift. Bluefruit styrelsen är ansluten enligt följande (standardkonfiguration):
- CTS på stift 11
- TXO på stift 10
- RXI på pin 9
- VIN på 5V
- GND på GND
MOD, RTS och DFU stiften används inte i det här exemplet. Observera att det här exemplet Bluefruit styrelsen har till vara sätta till CMD läge på den lilla switchen.
I samband 3 LEDs med en 220 Ω motstånd för var och en av dem till stift 5, 6 och 7. Detta är valfritt, men kan vara användbart i vissa fall.
Nu när ledningarna är gjort, kan vi börja kodning. Du behöver flera bibliotek för att få det att fungera. Arduino.h, SPI.h och SoftwareSerial.h biblioteken är är redan närvarande på Arduino IDE och RH_ASK.h den som vi använde i föregående kod. Adafruit_BLE.h, Adafruit_BluefruitLE_SPI.h och Adafruit_BluefruitLE_UART.h bibliotek kan laddas ner från Adafruits hemsida. BluefruitConfig.h är en konfigurationsfil för Bluefruit styrelsen.
#include < Arduino.h >#include < RH_ASK.h >
#include <SPI.h >
#if inte definierats (_VARIANT_ARDUINO_DUE_X_) & & inte definierats (_VARIANT_ARDUINO_ZERO_)
#include <SoftwareSerial.h >
#endif
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"
Här är de globala variabler som används i den här koden:
NbRooms variabler definierar det totala antalet rum, se till att du ändrar den här om du använder mer eller mindre än 3 sändare Arduinos
Variablerna som värden är en matris med längd nbRooms som används för att lagra de uppgifter som mottagits från sändaren Arduinos.
Variabeln LEDpin är en matris som innehåller pin-koder för lysdioderna.
Gräns -variabeln är en vektor som lagrar gränserna för luminositet där lamporna anses på eller av. Observera att jag glömde att ersätta 3 med variabeln nbRooms , som du bör göra.
Variablerna tid och currentTime används för att lagra värden som erhålls från funktionen millis .
Variabeln dataToSend används för att lagra data som ska skickas till Smartphone
Begäran om variabeln är en char array som innehåller en begäran om att skicka till sändaren Arduinos. Glöm inte att ändra detta om du använder olika antal sändare.
Den * begäran variabel är en pekare till den begäran som ska skickas till sändaren Arduino.
Den booleska värden gotResponse, firstRequest och Skicka kommer att förklaras senare.
int värden [nbRooms]; Används för att lagra de uppgifter som samlats in från den sändarna
int LEDpin [] = {5, 6, 7}; Stift för lysdioderna
int gräns [3]. Används för att lagra luminositet gränserna som ljuset betraktas av
Används för att lagra värdena som millis()
unsignedlong tid.
unsignedlong currentTime;
Sträng dataToSend; Används för att lagra data som skickas till Smartphone
char * begär [] = {"a0", "a1", "a2"}; Används för att lagra förfrågningarna, glöm inte att ändra det om du använder mer eller mindre än 3 sändare Arduinos
char * begär; Används för att lagra begäran skickas
bool gotResponse = false;
bool firstRequest = sant;
bool bleIsConnected = false;
bool skicka = sant; För att stoppa den BLE sändningen
I denna del skapar vi de nödvändiga objekt.
Som innan vi skapa RH_ASK -objektet heter föraren, men denna gång måste du ställa in Ptt pin en oanvända pin (eller pin -1) eftersom standard är pin 10 som redan används av Bluefruit styrelsen.
Sedan skapar vi i bluefruitSS och ble -objekten. De parametrar som används för dessa objekt är de som anges i filen BluefruitConfig.h .
Parametrar för SoftwareSerial- och Adafruit_BluefruitLE_UART lagras i BluefruitConfig fil
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);
Adafruit_BluefruitLE_UART ble (bluefruitSS, BLUEFRUIT_UART_MODE_PIN, BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
Nästa är några inställningen definitioner. Den första som anger om du vill Bluefruit styrelsen att utföra en fabriksåterställning när det börjar. Den andra en definierar den lägsta firmware versionen och den sista beteendet hos röda ledde i styrelsen. Jag rekommenderar lämnar dessa inställningar orörd.
#define FACTORYRESET_ENABLE 1#define MINIMUM_FIRMWARE_VERSION "0.6.6"
#define MODE_LED_BEHAVIOUR "MODE"
I installationen del startar vi genom att ställa in LED stift utdataläge . Vi satt sedan alla gränser till 0 så att de inte är null, som skulle hindra oss från att göra någon jämförelse. De kommer att ändras på mobila app senare.
voidsetup(void){
för (int jag = 0; jag < sizeof(LEDpin); i ++)
{
pinMode (LEDpin [i], OUTPUT); Initiera LED stift
}
för (int jag = 0; jag < nbRooms; i ++)
{
Limit [i] = 0; Initiera gränserna vid 0
}
Seriella.begin(9600); För felsökning
om (! driver.init()) / / om RF-moduler strandat till starta
Seriella.println ("init misslyckades");
Denna del av installationen hanterar konfigurationen av Bluefruit styrelse. Funktionen setupBluefruit kommer att förklaras senare. Koden efter det ändrar styrelsens LED läge (om den firmware versionen är minst 0.6.6) och anger sedan styrelsen till data-läge, så att den kan kommunicera med Smartphone.
setupBluefruit();Seriella.println(F("***"));
LED aktivitet kommandot stöds endast från 0.6.6
om (ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION))
{
Ändra läge LED verksamhet
Seriella.println (F ("Ändra LED aktivitet till" MODE_LED_BEHAVIOUR));
ble.sendCommandCheckOK ("AT + HWModeLED =" MODE_LED_BEHAVIOUR);
}
Ställ in modulen till DATA-läge
Seriella.println F ("koppla till Dataläge!").
ble.setMode(BLUEFRUIT_MODE_DATA);
Seriella.println(F("***"));
}
I loop delen, kommer att vi hantera mottagning av data från sändaren Arduinos, överföringen av dessa uppgifter till Smartphone och mottagning av gränserna från Smartphone.
Det data insamling och överföring är inuti en om uttryck så att du kan stoppa den BLE sändningen om du vill, vilket jag inte gjorde.
Vi kommer sedan loopa igenom alla rum, ange gotResponse till false och skicka en förfrågan. Samtidigt börjar vi en timer genom att tilldela ett värde till variabeln tid med funktionen millis .
{
om (skicka) / / för att stoppa den BLE sändningen
{
för (int jag = 0; jag < nbRooms; i ++)
{
gotResponse = false;
Skicka förfrågan
tid = millis(); Start timer
sendRequest(i); Skicka begäran till sändaren Arduino
Medan vi inte har fått något svar från sändaren Arduino, lagrar vi millis värdet i variabeln currentTime för att jämföra det med tiden. Om skillnaden överstiger 500 millisekunder, innebär det att meddelandet var förlorat och att vi måste skicka en annan begäran. Vi måste också återställa variabeln tid .
Får svarmedan (! gotResponse) / / även om inget svar har inkommit
{
currentTime = millis();
om (currentTime - tid > 500) / / om 0,5 sekunder har gått utan att något svar, skicka förfrågan
{
tid = millis(); Reset timer
Seriella.println ("inget svar efter 0,5 sekund, skicka begäran");
sendRequest(i);
}
Återigen skapar vi en buffert för att lagra mottagna data. Vid mottagandet, vi lagrar meddelandet i en strängvariabel och tolka värdet rum och data . Om rummet matchar den förväntade, vi sedan ange gotResponse till true och lagrar data i matrisen värden .
uint8_t buf [4]. Buffert används för att lagra mottagna data, dess storlek är inställd på 3 byte data är: String(room) + värde (t.ex. 0555)uint8_t buflen = sizeof(buf);
om (driver.recv (buf, och buflen)) / / vid mottagandet av data
{
Sträng meddelande = (char *) buf; Lagra data i en sträng tolkning
int rum = message.substring (0, 1).toInt(); Parsning rumsnummer
int data = message.substring(1).toInt(); Analysera data
om (rum == jag) / / om uppgifterna är från rätt rummet
{
gotResponse = sant;
värden [rum] = data; Lagra data
I denna del hanterar vi blixten av lysdioder. Detta är frivilligt.
Slå lysdioder på och avom (värden [rum] > limit[room])
{
digitalWrite (LEDpin [i], hög);
}
annat
{
digitalWrite (LEDpin [i], låg);
}
För felsökning
Seriella.print ("Data för rum");
Seriella.print(room);
Seriella.print ("är");
Seriella.println(data);
Seriella.println("");
}
}
}
Delay(50);
}
När vi har mottagit och kontrollerat data från alla rum, kan vi gå vidare till överföringen av dessa uppgifter till Smartphone. Meddelandet inleds med ett "#" och avslutas med en "*" för att tolka det enkelt i Smartphone app. Vi också avgränsar du värdena med ett "/".
dataToSend = "#"; Starta datasträng med # för easyier tolkning av Smartphone appför (int jag = 0; jag < nbRooms; i ++)
{
dataToSend.concat(String(values[i]));
om (jag < nbRooms - 1)
{
dataToSend.concat("/"); Avgränsar du värdena med ett /
}
}
dataToSend.concat("*"); Avsluta datasträng med *
Seriella.print ("Skicka:");
Seriella.println(dataToSend);
Seriella.println("");
}
Meddelandet lagras i en char array sedan och skickade till Smartphone whit metoden ble.print .
char n, ingångar [BUFSIZE + 1]; Används för att lagra data som ska skickas till SmartphonedataToSend.toCharArray (ingångar, BUFSIZE + 1); Kopiera datasträng till buffert
ble.Print(inputs); Skicka data
Därefter kommer mottagande av de gränser som skickas av Smartphone. Vi börjar med att skapa en strängvariabel kallas värden (inte samma som int matrisen!) som kommer att lagra tecken tas emot via BLE connexion. När vi har läst #, dvs utgångspunkten för meddelandet, vi anger du variabeln inspelning sann som kommer att möjliggöra sammanfogning av följande tecken till variabeln värden , tills den * läses. När meddelandet är klar, vi tolka och lagra de gränser med funktionen setLimits som kommer att förklaras senare.
Strängvärden = ""; Tömma strängLäsa data från Smartphone
bool inspelning = false;
samtidigt (ble.available()) / / medan det finns data från BLE
{
int c = ble.read();
Seriella.println((char)c);
om (inspelning) / / om vi har läst #
{
om ((char) c! = ' *')
{
values.concat((Char)c); Så länge c är olika från slutet tecknet *, lägga till strängen data
}
annat
{
Seriella.println(values); setLimits(values);
inspelning = false; Sätta gränser till de som vi just fått
värden = "";
}
}
om ((char) c == '#') / / starta inspelningen vid mottagandet av start tecknet #
{
inspelning = sant;
}
}
}
Här finns de funktioner som används i koden.
Den första visar ett felmeddelande och stoppar körningen av programmet.
makulera fel (const __FlashStringHelper * err)
{
Seriella.println(err);
samtidigt (1).
}
Den här funktionen konfigurerar Bluefruit styrelsen när det börjar. Det utförs även en fabriksåterställning om den har aktiverats.
void setupBluefruit(){
/ * Initiera modulen * /
Seriella.print (F ("initiera modulen Bluefruit LE:"));
om (! ble.begin(VERBOSE_MODE))
{
fel (F ("kunde inte hitta Bluefruit, kontrollera att den är i kommando-läge & Kontrollera ledningar?"));
}
Seriella.println (F("OK!"));
om (FACTORYRESET_ENABLE)
{
/ * Utföra en fabriksåterställning för att kontrollera att allt är i ett känt tillstånd * /
Seriella.println (F ("utför en factory reset:"));
om (! ble.factoryReset()) {
fel F ("kunde inte fabriksåterställning").
}
}
/ * Inaktivera kommandot echo från Bluefruit * /
ble.ECHO(false);
Seriella.println ("begär Bluefruit information:");
/ * Skriva ut Bluefruit information * /
ble.info();
ble.Verbose(false);
}
Denna funktion används för att skicka förfrågningar till sändaren Arduinos, med ett rum identifieringsnummer som parameter.
Skicka en begäran till motsvarande rum sändaren (i)void sendRequest(int i)
{
begäran = begäran [i];
driver.send ((uint8_t *) begäran, strlen(request));
driver.waitPacketSent();
Seriella.print ("begäran skickas till rum").
Seriella.println(i);
Seriella.println ("Awaiting svar");
Seriella.println("");
}
Här fungerar tolkar gräns meddelandet som mottogs från Smartphone och lagrar gränserna i matrisen gräns .
Lagra gränsernavoid setLimits(String values)
{
för (int jag = 0; jag < nbRooms; i ++)
{
om (jag < nbRooms - 1)
{
Limit [i] = values.substring (4 * i, 3 + 4 * i).toInt(); Pärsing gränser
}
annat
{
Limit [i] = values.substring (4 * i).toInt(); Analysera den sista gränsen
}
}
}