Introduction: LightBlue Bean+ Thermostat

LightBlue Bean+ Thermostat

I made an example thermostat using a LightBlue Bean+, various external Grove sensors, and the built-in temperature sensor. The "thermostat" reacts to changes in a rotary knob to set the set point temperature, and when the measured temperature is out of range, it notifies via a vibration motor. To signal on/off functionality, the vibration motor vibrates 3 times to notify on state, and 1 time to notify off state. The thermostat supports heating mode, cooling mode, and an off mode.

Step 1: Items Needed

You will need the following items to create this project:

Step 2: Assembly - Attach Grove Extender

Attach the Grove Extender to the Bean+, making sure the orientation is correct. The text on the extender should face the same direction as the text on the Bean+ board.

Step 3: Assembly - Button

Plug one end of the Grove connector cable into the button, and plug the other end into the D1/D2 slot on the Grove expansion board.

Step 4: Assembly - Vibration Motor

Plug in one end of the Grove connector cable into the vibration motor, and plug the other end of the cable into the D2/D3 slot on the Grove expansion board.

Step 5: Assembly - Rotary Angle Sensor

Plug in one end of the Grove connector cable to the rotary angle sensor, and plug the other end of the cable into the A1/A2 slot on the Grove connector board.

Step 6: Programming

In order to program your LightBlue Bean+ with the thermostat code, you must install the:

  • Arduino IDE
  • BeanLoader Client

Once installed, you can open the thermostat project in the Arduino IDE, and open the BeanLoader to connect to your Bean+ to program it.

Step 7: The Code

Here is the code for this project:

// PinChangeInt handles pin change interrupts
#include

/** * Momentary switch - Digital Pin 1 */ #define BUTTON 1

/** * Vibration motor - Digital Pin 2 */ #define VIBRATE 2

/** * Potentiometer - Analog Pin 1 */ #define POTENT A1

#define ADC_REF 5 //reference voltage of ADC is 5v.If the Vcc switch on the seeeduino

#define GROVE_VCC 5

/** * Heating/cooling modes */ #define MODE_COOL 2 #define MODE_HEAT 1 #define MODE_OFF 0

/** * Range mapping for potentiometer */ #define MIN_VAL 0 #define MAX_VAL 300 #define MIN_TEMP 0 #define MAX_TEMP 60

/** * The current heating/cooling mode * 0 = off * 1 = heat * 2 = cool */ volatile int8_t currentMode = 0;

int reading = 0;

/** * The heat/cool setpoints */ int8_t setpointHeat = 0; int8_t setpointCool = 0;

boolean notifiedOff = false;

void setup() { // Reset the LED Bean.setLed(0, 0, 0);

// Begin serial communication Serial.begin(9600);

pinMode(BUTTON, INPUT); pinMode(POTENT, INPUT); pinMode(VIBRATE, OUTPUT);

attachPinChangeInterrupt(BUTTON, pin_ISR, CHANGE); }

/** * Program loop */ void loop() { updateSetpoint(); updateTemperature(); Bean.sleep(2000); }

/** * Updates the setpoint based on the potentiometer. */ void updateSetpoint() { int sensor = analogRead(POTENT); float voltage = (float) sensor * ADC_REF / 1023; float reading = (voltage * MAX_VAL) / GROVE_VCC;

// Handle heating/cooling modes if (currentMode == MODE_COOL) { setpointCool = map(reading, MIN_VAL, MAX_VAL, MIN_TEMP, MAX_TEMP);

int color = map(setpointCool, MIN_TEMP, MAX_TEMP, 255, 0);

// Update the LED brightness to indicate where the temperature is Bean.setLed(0, 0, color); } else if (currentMode == MODE_HEAT) { setpointHeat = map(reading, MIN_VAL, MAX_VAL, MIN_TEMP, MAX_TEMP); int color = map(setpointHeat, MIN_TEMP, MAX_TEMP, 0, 255); Bean.setLed(color, 0, 0); } }

/** * Updates the heating mode visually based on the current system state. */ void updateHeatingMode() { switch (currentMode) { case MODE_OFF: Bean.setLed(0, 0, 0); break; case MODE_HEAT: Bean.setLed(255, 0, 0); break; case MODE_COOL: Bean.setLed(0, 0, 255); break; } }

/** * Updates the temperature. */ void updateTemperature() { // get the current temperature int8_t currTemp = Bean.getTemperature();

Serial.print("Temperature is "); Serial.print(currTemp); Serial.println(" degrees Celsius");

// Nothing to update it's off if (currentMode == MODE_OFF) { return; }

// Handle heating mode changes if (currentMode == MODE_HEAT) { // Enable heating if (setpointHeat > currTemp) { Serial.println("Heating being enabled. Setpoint exceeded."); Serial.print("Setpoint: "); Serial.print(setpointHeat); Serial.print("; Temperature: "); Serial.println(currTemp);

startMode(MODE_HEAT); } else { Serial.println("Heating being disabled."); Serial.print("Setpoint: "); Serial.print(setpointHeat); Serial.print("; Temperature: "); Serial.println(currTemp); stopMode(MODE_HEAT); } } else if (currentMode == MODE_COOL) { // Enable heating if (setpointCool < currTemp) { Serial.println("Cooling being enabled. Setpoint exceeded."); Serial.print("Setpoint: "); Serial.print(setpointCool); Serial.print("; Temperature: "); Serial.println(currTemp);

startMode(MODE_COOL); } else { Serial.println("Cooling being disabled."); Serial.print("Setpoint: "); Serial.print(setpointCool); Serial.print("; Temperature: "); Serial.println(currTemp);

stopMode(MODE_COOL); } } }

/** * Start a control mode. * Provides vibration feedback. * int mode - the mode to start */ void startMode(int8_t mode) { if (mode == MODE_HEAT) { vibrateMotor(3); } else if (mode == MODE_COOL) { vibrateMotor(3); }

notifiedOff = false; }

/** * Stop a control mode * int mode - the mode to stop */ void stopMode(int8_t mode) { if (notifiedOff) { return; } if (mode == MODE_HEAT) { vibrateMotor(1); } else if (mode == MODE_COOL) { vibrateMotor(1); }

notifiedOff = true; }

/** * Vibrates the motor * int times - the number of times to vibrate */ void vibrateMotor(int8_t times) { for (int8_t i = 0; i < times; i++) { digitalWrite(VIBRATE, HIGH); delay(200); digitalWrite(VIBRATE, LOW); delay(200); } }

/** * Handle the ISR for the momentary button to change heat/cool modes */ void pin_ISR() { int8_t state = digitalRead(BUTTON);

if (state == HIGH) { if (currentMode == MODE_COOL) { currentMode = MODE_OFF; } else { currentMode++; }

updateHeatingMode(); } }

Step 8: Final Product

Here is a video of the final working version of the LightBlue Bean+ Thermostat.