This is a simple home automation system which communicates with a Bluetooth app to control home systems such as HVAC and lighting. This was done for El-Sharkaway's ECE595 Class
Dependencies: DHT EthernetInterface M2XStreamClient Servo jsonlite mbed-rtos mbed nRF24L01P
Fork of nRF24L01P_Hello_World by
main.cpp
- Committer:
- haircules
- Date:
- 2017-05-05
- Revision:
- 2:19aff72aeb30
- Parent:
- 1:5be2682710c6
File content as of revision 2:19aff72aeb30:
#include "mbed.h" #include "DHT.h" #include "nRF24L01P.h" /*RF Module*/ #include "M2XStreamClient.h" /*AT&T M2X*/ #include "EthernetInterface.h" /*Ethernet*/ #include <stdlib.h> #include <stdio.h> /*************** Base Board Code **********************/ /* -- All revisions made by Nigel Leitzell for ECE595 final project -- */ /* This code allows for communication between the Mobile Board and Bluetooth App */ /* to the Base Board for Smart Home Automoation. Values logged from sensors will */ /* be collected and sent to the cloud via Ethernet from the Base Board. The Base */ /* Board should allow the user to control aspects of their home (i.e. lighting- */ /* and air temperature). However, only the Mobile Board or Bluetooth App may be- */ /* used at any one time. Selection of board which assumes control of the Base- */ /* Board is determined using buttons on the Base Board or the Bluetooth App. */ /*********************************************************************************/ /************************ Definitions ***************************/ #define PWM_PERIOD 20 /************** Communications ***************************/ #define TRANSFER_SIZE 15 /*********************************************************************************/ /************** Pin Declarations ****************************/ Serial pc(USBTX, USBRX);// (tx, rx) Serial TFT_LCD(PTC17, PTC16); // (tx, rx) Serial port for TFT LCD nRF24L01P my_nrf24l01p (PTD6,PTD7,PTD5,PTD4,PTB20,PTC18);// (mosi, miso, sck, csn, ce, irq) DigitalOut RED(LED1); DigitalOut GREEN(LED2);//Mobile Board Control DigitalOut BLUE(LED3); //Base Board Control DigitalOut Fan_En(PTD2); //Fan Enable Line DigitalIn sw2(SW2); //Mobile Board select button DigitalIn sw3(SW3); //Bluetooth App select button Serial HC06(PTC15,PTC14);//BT TX,RX (Bluetooth module declaration) //InterruptIn HC06_Int(PTC14);//Install Interrupt on Rx Pin for Bluetooth Module //Ticker Timer1; //Timer for updating current temp PwmOut Fan_PWM(PTD1); PwmOut Fan_Servo(PTD0); DHT tempSensor(PTC4,DHT22); /*********************************************************************************/ /************** Function Prototypes ************************/ void unpack(int &x,int &y,int &z,char *b); /*unpacketize the buffer*/ void initEthernet(EthernetInterface eth); /*Initialize Ethernet*/ void InitBT(void);/*print Bluetooth Stuff*/ void Rx_Interrupt(void);/*Interrupt Routine for Bluetooth Rx Events*/ void Timer1_Interrupt(void);/*Function Handler for Timer1*/ /*********************************************************************************/ /************** Globals ***********************/ /*************** Set Sensor Stream details (AT&T M2X stuff) **********************/ char deviceId[] = "81c5ecb0ac94aad592ad558ead689321"; // Device you want to push to char streamX[] = "acc_x"; // Stream you want to push to char streamY[] ="acc_y"; // Stream you want to push to char streamZ[] ="acc_z"; // Stream you want to push to char m2xKey[] = "b2c3795c7022a811a3c4de49095b26ec"; // Your M2X API Key or Master API Key uint8_t snd[512],rcv[1000];//send and recieve buffer for Bluetooth /*********************************************************************************/ /******************************************************************************/ /* User Level #define Macros */ /******************************************************************************/ /******************************************************************************/ /* User Definitions */ /******************************************************************************/ #define SECURITY_LIGHTS_ADDR 0x00 #define INDOOR_LIGHTS_ADDR 0x01 #define SMART_LIGHT_ADDR 0x02 #define CUR_TEMP_ADDR 0x03 #define HEAT_SET_TEMP_ADDR 0x04 #define COOL_SET_TEMP_ADDR 0x05 #define HEAT_STATE_ADDR 0x06 #define COOL_STATE_ADDR 0x07 #define FAN_STATE_ADDR 0x08 #define FAN_DIR_UD_ADDR 0x09 #define FAN_DIR_LR_ADDR 0x0A #define ARM_STATE_ADDR 0x0B #define MODE_ADDR 0x0C #define CONNECTION_STATE_ADDR 0x0D #define FAN_SPEED_ADDR 0x0E #define ARDUINO_ADDR 0xFF #define CONNECTED 1 //Connection state for bluetooth #define NUM_OF_EVENTS 15 //Number of events to handle typedef struct SmartHomeStruct { bool security_lights_state; bool indoor_lights_state; bool smart_light_state; uint8_t cur_temp; uint8_t heat_set_temp; uint8_t cool_set_temp; bool heat_state; bool cool_state; bool fan_state; uint8_t fan_speed; uint8_t fan_dir_ud; uint8_t fan_dir_lr; bool arm_state; uint8_t mode; bool connection_state; }SmartHome; typedef union { uint8_t Flags; struct { uint8_t RPF : 1, /* Received Packet Flag set when packet received */ RAPF : 1, /* Received Address Packet Flag set when address packet received (must be cleared to receive data packet) */ RDPF : 1, /* Received Data Packet Flag set when data packet received (RAPF must be cleared to receive data packet)*/ RUT : 1, /* Request Update Temperature Flag set when UpdateCurTemp() is called, cleared once temperature is updated */ USF : 1, /* Update Servo Flag is set after 20ms period required to send pulse to update position, cleared after 2ms */ spare2 : 1, /* Unused */ spare1 : 1, /* Unused */ spare0 : 1; /* Unused */ }; } SmartFlags; /*Typedef for function pointer type event_ptr*/ typedef void (*event_ptr)( uint8_t ); /*Create event_ptr array of size NUM_OF_EVENTS*/ event_ptr event_ptr_array[NUM_OF_EVENTS]; SmartHome SmartHomeData; //struct for SmartHome Data SmartFlags SmartHomeFlags; /******************************************************************************/ /* User Function Prototypes */ /******************************************************************************/ void InitSmartHomeApp(void); /* I/O and Peripheral Initialization */ void InitBluetoothApp(void); /* Initialize values in the Bluetooth App */ void InitAppFlags(void); /* Initialize Flags for SmartHome */ void SecurityLights(uint8_t data); /* Security Lights Handler */ void IndoorLights(uint8_t data); void SmartLight(uint8_t data); void CurrentTemp(uint8_t data); void HeatSetTemp(uint8_t data); void CoolSetTemp(uint8_t data); void HeatState(uint8_t data); void CoolState(uint8_t data); void FanState(uint8_t data); void FanDirUD(uint8_t data); void FanDirLR(uint8_t data); void ArmState(uint8_t data); void Mode(uint8_t data); void ConnectionState(uint8_t data); void FanSpeed(uint8_t data); void UpdateCurTemp(void); void CheckTempSettings(void); void SyncLCD(void); void RefreshServos(void); void CurrentTemp_LCD(uint8_t data); void HeatSetTemp_LCD(uint8_t data); void CoolSetTemp_LCD(uint8_t data); void HeatState_LCD(uint8_t data); void CoolState_LCD(uint8_t data); void FanState_LCD(uint8_t data); int main() { uint8_t Address; uint8_t Data; InitSmartHomeApp(); InitAppFlags(); InitBT(); SyncLCD(); /*RF Module (Mobile Board) variables/buffers */ char txData[TRANSFER_SIZE], rxData[TRANSFER_SIZE];//tx,rx buffers for RF int txDataCnt = 0; int rxDataCnt = 0; int x,y,z;/*x,y,z axis variables for Mobile Board Accelerometer Data*/ /*Bluetooth variables/buffers*/ int mode = 1; // Mode 1 for Bluetooth App control int timer = 0;//Timer for Entering the default control mode int init = 0; //determine whether mode has been initialized (1 yes, 0 no) RED=GREEN=BLUE=1; //LEDs are off //my_nrf24l01p.powerUp();/*Power Up RF module*/ // Display the (default) setup of the nRF24L01+ chip //pc.printf( "nRF24L01+ Frequency : %d MHz\r\n", my_nrf24l01p.getRfFrequency() ); //pc.printf( "nRF24L01+ Output power : %d dBm\r\n", my_nrf24l01p.getRfOutputPower() ); //pc.printf( "nRF24L01+ Data Rate : %d kbps\r\n", my_nrf24l01p.getAirDataRate() ); //pc.printf( "nRF24L01+ TX Address : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() ); //pc.printf( "nRF24L01+ RX Address : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() ); //pc.printf( "Type keys to test transfers:\r\n (transfers are grouped into %d characters)\r\n\n\n", TRANSFER_SIZE ); /* Initialize RF Module */ //my_nrf24l01p.setTransferSize( TRANSFER_SIZE ); //my_nrf24l01p.setReceiveMode(); //my_nrf24l01p.enable(); /* Intialize Ethernet connection*/ //EthernetInterface eth; //initEthernet(eth); /* Initialize the M2X client */ //Client client; //M2XStreamClient m2xClient(&client, m2xKey); pc.printf( "Preparing to startup..\r\n"); //Timer1.attach(&Timer1_Interrupt, 10); //Service Timer1_Int every 1 sec uint32_t tempCounter = 0; while(1) { /*If byte(s) available to read from HC06*/ if(HC06.readable()) { Rx_Interrupt(); } /* If packet has been received, handle it*/ if(SmartHomeFlags.RPF) { /*Assumptions: Bluetooth App will only send 2 bytes at a time (Address + Data)*/ Address = rcv [0]; Data = rcv [1]; event_ptr_array[Address](Data); //call the appropriate function passing it data SmartHomeFlags.RPF = 0; // Clear received packet flag //HC06_Int.enable_irq(); //Enable UART RX interrupt } tempCounter++; } }/*end main()*/ void unpack(int &x,int &y,int &z,char *b){ /*This function is resposible for unpacketizing a buffer that has been transmitted wirelessly by distributing data to variables passed by reference appropriately.*/ char buffer[5];/*buffer used to unpack data from packet*/ for(int i = 0; i < TRANSFER_SIZE; i++){ buffer[i%5] = b[i]; if(i == 4){/*buffer contains x*/ x = atoi(buffer); } else if(i == 9){/*buffer contains y*/ y = atoi(buffer); } else if(i == 14){/*buffer contains z*/ z = atoi(buffer); }/*end if*/ }/*end for*/ }/*end unpack()*/ void initEthernet(EthernetInterface eth){ /*This function handles the ethernet initialization upon being passed a pointer to an EthernetInterface object*/ eth.init();/*initialize DHCP*/ printf("Initialized DHCP! Preparing to connect...\r\n"); eth.connect();/*connect eth to internet*/ printf("Success. Connected!. Device IP Address is %s\r\n", eth.getIPAddress()); }/*end initEthernet()*/ void InitBT(void) { /*Attach Interrupt for Rx Events to HC06 Bluetooth Module*/ //HC06.attach(&Rx_Interrupt, Serial::RxIrq); //HC06_Int.fall(&Rx_Interrupt); //HC06_Int.enable_irq(); }/*end initBT()*/ /*Function Handler for HC06 Rx Interrupts*/ void Rx_Interrupt(void) { /*Temporarily Disable Rx Interrupts*/ //HC06_Int.disable_irq(); SmartHomeFlags.RPF = 1; //Set received packet flag char buffer[100]; char address[10]; char data[10]; char c; uint8_t t_address = 0; uint8_t t_data = 0; uint8_t index = 0; uint8_t num_index = 0; uint8_t eCount = 0; memset(buffer, 0, sizeof(buffer));/*flush buffer*/ memset(address, 0, sizeof(address));/*flush buffer*/ memset(data, 0, sizeof(data));/*flush buffer*/ HC06.gets(buffer,100);/*if so, get it.*/ /*Parse buffer*/ c = buffer[index]; while(c != '\n') { index++; c = buffer[index]; if(c == '=') { eCount++; //equal sign count++ index += 2; //skip space c = buffer[index]; //get data while(c != ' ') { if(eCount == 1) { address[num_index] = c; //fill num buffer } else if(eCount == 2) { data[num_index] = c; } num_index++; index++; c = buffer[index];//get next char } num_index = 0; //reset num_index } } /*Assign ASCII representation to integer representation*/ sscanf(address, "%d", &t_address); sscanf(data, "%d", &t_data); rcv[0] = t_address; rcv[1] = t_data; //pc.puts(address); //pc.printf("\n\r"); //pc.puts(data); //pc.printf("\n\r"); //pc.puts(buffer); //pc.printf("\n\r"); pc.printf( "Address: %d \r\n",rcv[0]); pc.printf( "Data: %d \r\n",rcv[1]); } void Timer1_Interrupt(void) { pc.printf("Checking Temp..\n\r"); UpdateCurTemp(); /*Update Values on App and LCD*/ CurrentTemp(SmartHomeData.cur_temp); pc.printf("Done..\n\r"); } /******************************************************************************/ /* User Functions */ /******************************************************************************/ void InitSmartHomeApp() { /*Initialize variables*/ SmartHomeData.security_lights_state = 0; //Initial security lights state SmartHomeData.indoor_lights_state = 0; //Initial indoor lights state SmartHomeData.smart_light_state = 0; //Initial SmartLight state SmartHomeData.cur_temp = 0; //Initial current temperature SmartHomeData.heat_set_temp = 80; //Initial heat set temperature SmartHomeData.cool_set_temp = 55; //Initial cool set temperature SmartHomeData.heat_state = 0; //Initial heat state SmartHomeData.cool_state = 0; //Initial cool state SmartHomeData.fan_state = 0; //Initial fan state SmartHomeData.fan_speed = 0; //Initial fan speed SmartHomeData.fan_dir_ud = 0; //Initial up/down fan direction SmartHomeData.fan_dir_lr = 0; //Initial left/right fan direction SmartHomeData.arm_state = 0; //Initial arm state SmartHomeData.mode = 0; //Initial mode SmartHomeData.connection_state = 0; //Initial bluetooth connection state /*Initialize Function Pointers*/ event_ptr_array[0] = SecurityLights; event_ptr_array[1] = IndoorLights; event_ptr_array[2] = SmartLight; event_ptr_array[3] = CurrentTemp; event_ptr_array[4] = HeatSetTemp; event_ptr_array[5] = CoolSetTemp; event_ptr_array[6] = HeatState; event_ptr_array[7] = CoolState; event_ptr_array[8] = FanState; event_ptr_array[9] = FanDirUD; event_ptr_array[10] = FanDirLR; event_ptr_array[11] = ArmState; event_ptr_array[12] = Mode; event_ptr_array[13] = ConnectionState; event_ptr_array[14] = FanSpeed; /************** Port Direction Setup ********************/ /************ Initialize peripherals ******************/ Fan_PWM.period_ms(PWM_PERIOD); FanSpeed(SmartHomeData.fan_speed); Fan_En = SmartHomeData.fan_state; Fan_Servo.period_ms(PWM_PERIOD); Fan_Servo.pulsewidth_us((SmartHomeData.fan_dir_lr * 20) + 500 ); //Green_Led = 0; //(Off) //Red_Led = 0; //(Off) //Heat_LED = 0; //(Off) //Cool_LED = 0; //(Off) //TRIP_EN = 0; //(Off) /***************** Enable Interrupts *******************/ /************ Initialize SmartHome Data ****************/ UpdateCurTemp(); } void InitBluetoothApp() /*This function synchronizes the SmartHome device and SmartHome Bluetooth App*/ { /*Send Security Lights State*/ HC06.putc(SECURITY_LIGHTS_ADDR); HC06.putc(SmartHomeData.security_lights_state); /*Send Indoor Lights State*/ HC06.putc(INDOOR_LIGHTS_ADDR); HC06.putc(SmartHomeData.indoor_lights_state); /*Send SmartLight State*/ HC06.putc(SMART_LIGHT_ADDR); HC06.putc(SmartHomeData.smart_light_state); /*Send Current Temperature*/ HC06.putc(CUR_TEMP_ADDR); HC06.putc(SmartHomeData.cur_temp); /*Send Heat Set Temperature*/ HC06.putc(HEAT_SET_TEMP_ADDR); HC06.putc(SmartHomeData.heat_set_temp); /*Send Cool Set Temperature*/ HC06.putc(COOL_SET_TEMP_ADDR); HC06.putc(SmartHomeData.cool_set_temp); /*Send Heat State*/ HC06.putc(HEAT_STATE_ADDR); HC06.putc(SmartHomeData.heat_state); /*Send Cool State*/ HC06.putc(COOL_STATE_ADDR); HC06.putc(SmartHomeData.cool_state); /*Send Fan State*/ HC06.putc(FAN_STATE_ADDR); HC06.putc(SmartHomeData.fan_state); /*Send Fan Speed*/ HC06.putc(FAN_SPEED_ADDR); HC06.putc(SmartHomeData.fan_speed); /*Send Fan Up/Down Direction*/ HC06.putc(FAN_DIR_UD_ADDR); HC06.putc(SmartHomeData.fan_dir_ud); /*Send Fan Left/Right Direction*/ HC06.putc(FAN_DIR_LR_ADDR); HC06.putc(SmartHomeData.fan_dir_lr); /*Send Arm State*/ HC06.putc(ARM_STATE_ADDR); HC06.putc(SmartHomeData.arm_state); /*Send Mode*/ HC06.putc(MODE_ADDR); HC06.putc(SmartHomeData.mode); } void InitAppFlags() { SmartHomeFlags.Flags = 0x00; // Clear All Flags } void SecurityLights(uint8_t data) { SmartHomeData.security_lights_state = data; if(SmartHomeData.security_lights_state == 1) { GREEN = 0; //ON } else { GREEN = 1; //OFF } } void IndoorLights(uint8_t data) { SmartHomeData.indoor_lights_state = data; if(SmartHomeData.indoor_lights_state == 1) { BLUE = 0; //ON } else { BLUE = 1; //OFF } } void SmartLight(uint8_t data) { SmartHomeData.smart_light_state = data; if(SmartHomeData.smart_light_state == 1) { RED = 0; //ON } else { RED = 1; //OFF } } void CurrentTemp(uint8_t data) { SmartHomeData.cur_temp = data; /*Send Current Temperature to App*/ HC06.putc(CUR_TEMP_ADDR); HC06.putc(SmartHomeData.cur_temp); /*Send Current Temperature to LCD*/ CurrentTemp_LCD(SmartHomeData.cur_temp); } void HeatSetTemp(uint8_t data) { SmartHomeData.heat_set_temp = data; HeatSetTemp_LCD(SmartHomeData.heat_set_temp); } void CoolSetTemp(uint8_t data) { SmartHomeData.cool_set_temp = data; CoolSetTemp_LCD(SmartHomeData.cool_set_temp); } void HeatState(uint8_t data) { SmartHomeData.heat_state = data; HeatState_LCD(SmartHomeData.heat_state); } void CoolState(uint8_t data) { SmartHomeData.cool_state = data; CoolState_LCD(SmartHomeData.cool_state); } void FanState(uint8_t data) { /*Turn fan on*/ if(data == 1) { SmartHomeData.fan_state = 1; //Set Fan State Fan_En = SmartHomeData.fan_state;//Turn Fan On } /*Turn fan off*/ else { SmartHomeData.fan_state = 0; //Set Fan State Fan_En = SmartHomeData.fan_state;//Turn Fan Off } FanState_LCD(SmartHomeData.fan_state); } void FanDirUD(uint8_t data) { SmartHomeData.fan_dir_ud = data; } void FanDirLR(uint8_t data) { SmartHomeData.fan_dir_lr = data; Fan_Servo.pulsewidth_us((SmartHomeData.fan_dir_lr * 20) + 500 ); } void ArmState(uint8_t data) { SmartHomeData.arm_state = data; } void Mode(uint8_t data) { SmartHomeData.mode = data; } void ConnectionState(uint8_t data) { SmartHomeData.connection_state = ((bool)data); if(SmartHomeData.connection_state == (!CONNECTED)) { SmartHomeData.connection_state = CONNECTED; HC06.putc(CONNECTION_STATE_ADDR); HC06.putc(SmartHomeData.connection_state); InitBluetoothApp(); } } void FanSpeed(uint8_t data) { /*Low Speed*/ if(data == 0) { Fan_PWM.pulsewidth_ms(PWM_PERIOD >> 2); //25% Duty Cycle } /*Medium Speed*/ else if(data == 1) { Fan_PWM.pulsewidth_ms(PWM_PERIOD >> 1); //50% Duty Cycle } /*High Speed*/ else if(data == 2) { Fan_PWM.pulsewidth_ms((PWM_PERIOD >> 2) + (PWM_PERIOD >> 1)); //75% Duty Cycle } /*Ultra-High Speed*/ else { Fan_PWM.pulsewidth_ms(PWM_PERIOD); //100% Duty Cycle } } void UpdateCurTemp(void) { SmartHomeFlags.RUT = 1; //Set Request Update Temperature Flag //int error = 0; /*Wait for tempSensor data to be ready*/ //error = tempSensor.readData(); //while(0 != error) //{ // error = tempSensor.readData(); //} //SmartHomeData.cur_temp = (int)tempSensor.ReadTemperature(FARENHEIT); } void CheckTempSettings(void) { /*If Heat State is On*/ if(SmartHomeData.heat_state == 1) { /*Turn on heat if current temp is below Heat Setting*/ if(SmartHomeData.cur_temp < SmartHomeData.heat_set_temp) { //Turn on Heat(Red LED) //Heat_LED = 1; } else { //Heat_LED = 0; } //Cool_LED = 0; } /*If Cool Sate is On*/ else if(SmartHomeData.cool_state == 1) { /*Turn on cool if current temp is above Cool Setting*/ if(SmartHomeData.cur_temp > SmartHomeData.cool_set_temp) { //Turn on Cool (Blue LED) //Cool_LED = 1; } else { //Cool_LED = 0; } //Heat_LED = 0; } /*Heat and Cool are off, turn off LED's*/ else { //Heat_LED = 0; //Cool_LED = 0; } } void SyncLCD(void) { /*Sync All Data*/ CurrentTemp_LCD(SmartHomeData.cur_temp); //wait_us(10); HeatSetTemp_LCD(SmartHomeData.heat_set_temp); //wait_us(10); CoolSetTemp_LCD(SmartHomeData.cool_set_temp); //wait_us(10); HeatState_LCD(SmartHomeData.heat_state); //wait_us(10); CoolState_LCD(SmartHomeData.cool_state); //wait_us(10); FanState_LCD(SmartHomeData.fan_state); } void RefreshServos(void) { /*wait should be between 500us - 2500us*/ /*500us (-90 degree position)*/ /*1500us ( 0 degree position)*/ /*2500us ( 90 degree position)*/ //set pins high //LR_SERVO = 1; //wait 500-2500us //wait_us((SmartHomeData.fan_dir_lr*20) + 500); //set pins low //LR_SERVO = 0; } void CurrentTemp_LCD(uint8_t data) { /*Update LCD*/ TFT_LCD.putc(2); TFT_LCD.putc(CUR_TEMP_ADDR); TFT_LCD.putc(SmartHomeData.cur_temp); } void HeatSetTemp_LCD(uint8_t data) { /*Update LCD*/ TFT_LCD.putc(2); TFT_LCD.putc(HEAT_SET_TEMP_ADDR); TFT_LCD.putc(SmartHomeData.heat_set_temp); } void CoolSetTemp_LCD(uint8_t data) { /*Update LCD*/ TFT_LCD.putc(2); TFT_LCD.putc(COOL_SET_TEMP_ADDR); TFT_LCD.putc(SmartHomeData.cool_set_temp); } void HeatState_LCD(uint8_t data) { /*Update LCD*/ TFT_LCD.putc(2); TFT_LCD.putc(HEAT_STATE_ADDR); TFT_LCD.putc(SmartHomeData.heat_state); } void CoolState_LCD(uint8_t data) { /*Update LCD*/ TFT_LCD.putc(2); TFT_LCD.putc(COOL_STATE_ADDR); TFT_LCD.putc(SmartHomeData.cool_state); } void FanState_LCD(uint8_t data) { /*Update LCD*/ TFT_LCD.putc(2); TFT_LCD.putc(FAN_STATE_ADDR); TFT_LCD.putc(SmartHomeData.fan_state); }