Project tutorial
Smart Buoy - Scheduling Power to the System

Smart Buoy - Scheduling Power to the System © CC BY-NC-SA

Controlling power to the system using alarms based on voltages!

  • 748 views
  • 0 comments
  • 1 respect

Components and supplies

Apps and online services

About this project

And so to the next challenge - how to control the power for the smart buoy!

The buoy doesn’t need to constantly make measurements - a few at regular intervals is more than enough and significantly better than the current coverage. This makes powering it slightly easier, because it can be off occasionally. Another thing which simplifies the powering process is that the buoy and its sensors are pretty small - this means that we can use small solar panels which are low power. However, having low power means we need to take steps to manage it more effectively to ensure the buoy can produce regular measurements, without leaving large portions of the day without measurements. We decided that we wanted to schedule the power to the buoy based on how much energy there is in the battery.

Supplies:

For this build, you will need:

Step 1: Powering the Buoy

The smart buoy is powered by a 18650 battery which is charged by four, 5V, 60mA solar panels in parallel. In our design, the four solar panels sit around the top of the buoy, capturing maximum sunlight.

We put in some blocking diodes to prevent reverse current into the panels. We used a charge controller to control the battery output and charge from the solar panels. The charge controller output isn’t high enough to power the system stably, so we use a buck booster to increase the voltage to about 6V.

As a solely solar-powered device, it’s unlikely the buoy would make it through the night with enough power to continue taking measurements. To ensure it always has enough power to operate the sensors, we used a real-time clock module to turn the system on and off. This module operates using the battery but uses a super low amount of current so it can run for years.

We programmed the real-time clock module to have an alarm, set based on how much power is in the battery. This value is inferred based on the battery voltage which is measured using a power monitor module. When the alarm is triggered, it changes the alarm pin from high to low. We can use this to turn on a transistor, which allows power to the arduino. The system makes its measurements and turns off by clearing the alarm, changing the pin back to high, which turns the transistor off.

Step 2: Controlling Power Using the RTC Alarms

Here’s an example of how to programme an alarm to control power to the Arduino. In this example, we’ll use an Arduino to turn on an LED for three seconds and set an alarm for 15 seconds and then turn itself off. Once 15 seconds have passed, the alarm will trigger, the LED will turn on again and the cycle will repeat.

(We explain the code in this video - https://youtu.be/5guIB8_YIGQ)

#include <DS3232RTC.h>#include <Adafruit_INA219.h>
#include  <Wire.h>int led = LED_BUILTIN; // INA219 - Power Monitor
Adafruit_INA219 ina219;  
void setup() {
  Wire.begin();
  pinMode(led, OUTPUT);
  
  // initialise INA219 - Power Monitor
  ina219.begin();
  ina219.setCalibration_32V_1A();
}void loop() {
  digitalWrite(led, HIGH);
  delay(3000);
  reset_alarm();
}void reset_alarm(){
  RTC.alarmInterrupt(ALARM_1, true);
  RTC.squareWave(SQWAVE_NONE);
  setTime(0, 0, 0, 0, 0, 1970); 
  RTC.set(now());
  int wait_time = get_wait_time_from_voltage();
  // set new alarm
  RTC.setAlarm(ALM1_MATCH_MINUTES, 0, wait_time, 0, 0);
  // clear old alarm flag - turning off system
  RTC.alarm(ALARM_1);
}int get_wait_time_from_voltage(){
  float shuntvoltage = ina219.getShuntVoltage_mV();
  float busvoltage = ina219.getBusVoltage_V();
  float loadvoltage = busvoltage + (shuntvoltage / 1000);  // Samsung 18650 % capacity at a given voltage
  // batt_voltages            0.0, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.5
  // batt_percentages           0,   0,   9,  22,  52,  64,  75,  84,  93, 100, 100
  int wait_time;
  if (loadvoltage < 3.6) wait_time = 55;
  else if (loadvoltage < 3.8) wait_time = 25;
  else if (loadvoltage < 4.0) wait_time = 15;
  else if (loadvoltage < 4.1) wait_time = 10;
  else wait_time = 3;
  
  return wait_time;
}

Step 3: Monitoring Power

This is how we monitored battery voltage and current usage using the INA219 DC current monitor. This module communicates using I^2C - refer to the schematic for the connections you need to make. A nice library for talking to the module already exists, making this process really easy.

(We explain the code in this video - https://youtu.be/5guIB8_YIGQ)

#include <Wire.h>#include <Adafruit_INA219.h>// INA219 - Power Monitor
Adafruit_INA219 ina219;
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;void setup() {
  Serial.begin(115200);
  while (!Serial) {
      delay(1);
  }  // initialise INA219 - Power Monitor
  ina219.begin();
  ina219.setCalibration_32V_1A();
  
}void loop() {
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA);  Serial.println(" mA");
  Serial.print("Power:         "); Serial.print(power_mW);    Serial.println(" mW");
  Serial.println();
  delay(1000);
}

Step 4: Using the Power Monitor to Set the Next RTC Alarm

Finally, this is how we used the voltage to predict the optimal duration between alarms. The method is a bit crude - if anyone has any better ideas, please let us know in the comments below.

(We explain the code in this video - https://youtu.be/5guIB8_YIGQ)

#include <DS3232RTC.h>#include <Adafruit_INA219.h>
#include  <Wire.h>int led = LED_BUILTIN; // INA219 - Power Monitor
Adafruit_INA219 ina219;  
void setup() {
  Wire.begin();
  pinMode(led, OUTPUT);
  
  // initialise INA219 - Power Monitor
  ina219.begin();
  ina219.setCalibration_32V_1A();
}void loop() {
  digitalWrite(led, HIGH);
  delay(3000);
  reset_alarm();
}void reset_alarm(){
  RTC.alarmInterrupt(ALARM_1, true);
  RTC.squareWave(SQWAVE_NONE);
  setTime(0, 0, 0, 0, 0, 1970); 
  RTC.set(now());
  int wait_time = get_wait_time_from_voltage();
  // set new alarm
  RTC.setAlarm(ALM1_MATCH_MINUTES, 0, wait_time, 0, 0);
  // clear old alarm flag - turning off system
  RTC.alarm(ALARM_1);
}int get_wait_time_from_voltage(){
  float shuntvoltage = ina219.getShuntVoltage_mV();
  float busvoltage = ina219.getBusVoltage_V();
  float loadvoltage = busvoltage + (shuntvoltage / 1000);  // Samsung 18650 % capacity at a given voltage
  // batt_voltages            0.0, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.5
  // batt_percentages           0,   0,   9,  22,  52,  64,  75,  84,  93, 100, 100
  int wait_time;
  if (loadvoltage < 3.6) wait_time = 55;
  else if (loadvoltage < 3.8) wait_time = 25;
  else if (loadvoltage < 4.0) wait_time = 15;
  else if (loadvoltage < 4.1) wait_time = 10;
  else wait_time = 3;
  
  return wait_time;
}

Step 5: Goodbye

Thanks for following us through our journey to making our smart buoy! Our next tutorial will show you how we made the buoy’s casing and where we decided to launch it.

Code

control_power_with_rtc_alarm.inoArduino
Error opening file.
monitor_power.inoArduino
Error opening file.
control_power_with_rtc_based_on_monitoring.inoArduino
Error opening file.
Code snippet #1Plain text
#include <DS3232RTC.h>#include <Adafruit_INA219.h>
#include  <Wire.h>int led = LED_BUILTIN; // INA219 - Power Monitor
Adafruit_INA219 ina219;  
void setup() {
  Wire.begin();
  pinMode(led, OUTPUT);
  
  // initialise INA219 - Power Monitor
  ina219.begin();
  ina219.setCalibration_32V_1A();
}void loop() {
  digitalWrite(led, HIGH);
  delay(3000);
  reset_alarm();
}void reset_alarm(){
  RTC.alarmInterrupt(ALARM_1, true);
  RTC.squareWave(SQWAVE_NONE);
  setTime(0, 0, 0, 0, 0, 1970); 
  RTC.set(now());
  int wait_time = get_wait_time_from_voltage();
  // set new alarm
  RTC.setAlarm(ALM1_MATCH_MINUTES, 0, wait_time, 0, 0);
  // clear old alarm flag - turning off system
  RTC.alarm(ALARM_1);
}int get_wait_time_from_voltage(){
  float shuntvoltage = ina219.getShuntVoltage_mV();
  float busvoltage = ina219.getBusVoltage_V();
  float loadvoltage = busvoltage + (shuntvoltage / 1000);  // Samsung 18650 % capacity at a given voltage
  // batt_voltages            0.0, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.5
  // batt_percentages           0,   0,   9,  22,  52,  64,  75,  84,  93, 100, 100
  int wait_time;
  if (loadvoltage < 3.6) wait_time = 55;
  else if (loadvoltage < 3.8) wait_time = 25;
  else if (loadvoltage < 4.0) wait_time = 15;
  else if (loadvoltage < 4.1) wait_time = 10;
  else wait_time = 3;
  
  return wait_time;
}
Code snippet #2Plain text
#include <Wire.h>#include <Adafruit_INA219.h>// INA219 - Power Monitor
Adafruit_INA219 ina219;
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;void setup() {
  Serial.begin(115200);
  while (!Serial) {
      delay(1);
  }  // initialise INA219 - Power Monitor
  ina219.begin();
  ina219.setCalibration_32V_1A();
  
}void loop() {
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA);  Serial.println(" mA");
  Serial.print("Power:         "); Serial.print(power_mW);    Serial.println(" mW");
  Serial.println();
  delay(1000);
}
Code snippet #3Plain text
#include <DS3232RTC.h>#include <Adafruit_INA219.h>
#include  <Wire.h>int led = LED_BUILTIN; // INA219 - Power Monitor
Adafruit_INA219 ina219;  
void setup() {
  Wire.begin();
  pinMode(led, OUTPUT);
  
  // initialise INA219 - Power Monitor
  ina219.begin();
  ina219.setCalibration_32V_1A();
}void loop() {
  digitalWrite(led, HIGH);
  delay(3000);
  reset_alarm();
}void reset_alarm(){
  RTC.alarmInterrupt(ALARM_1, true);
  RTC.squareWave(SQWAVE_NONE);
  setTime(0, 0, 0, 0, 0, 1970); 
  RTC.set(now());
  int wait_time = get_wait_time_from_voltage();
  // set new alarm
  RTC.setAlarm(ALM1_MATCH_MINUTES, 0, wait_time, 0, 0);
  // clear old alarm flag - turning off system
  RTC.alarm(ALARM_1);
}int get_wait_time_from_voltage(){
  float shuntvoltage = ina219.getShuntVoltage_mV();
  float busvoltage = ina219.getBusVoltage_V();
  float loadvoltage = busvoltage + (shuntvoltage / 1000);  // Samsung 18650 % capacity at a given voltage
  // batt_voltages            0.0, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.5
  // batt_percentages           0,   0,   9,  22,  52,  64,  75,  84,  93, 100, 100
  int wait_time;
  if (loadvoltage < 3.6) wait_time = 55;
  else if (loadvoltage < 3.8) wait_time = 25;
  else if (loadvoltage < 4.0) wait_time = 15;
  else if (loadvoltage < 4.1) wait_time = 10;
  else wait_time = 3;
  
  return wait_time;
}

Comments

Similar projects you might like

@Tiny85 Sleep Controller : Low Power Embedded System

Project tutorial by Shahariar

  • 5,345 views
  • 0 comments
  • 11 respects

Smart Buoy - [Making Wave and Temperature Measurements]

Project tutorial by T3ch Flicks

  • 1,405 views
  • 0 comments
  • 3 respects

Smart Garbage Monitoring System Using Arduino 101

Project tutorial by Technovation

  • 32,692 views
  • 10 comments
  • 49 respects

The hydroMazing Smart Garden System

Project tutorial by Cory Potter

  • 31,770 views
  • 14 comments
  • 136 respects

Smart Plug

Project tutorial by xXarduino_11Xx

  • 4,525 views
  • 11 comments
  • 15 respects

Alexa Smart Power Strip with Temperature

Project tutorial by Muhammad Afzal

  • 1,691 views
  • 0 comments
  • 9 respects
Add projectSign up / Login