Project – DC Power and Efficiency Meter

Donations

Anything would help really. My goal is to have this website ad free and so you can enjoy my content without having to look at ads. Thank you

$0.25

TABLE OF CONTENTS

1. Introduction
2. Bill of Materials
3. Schematic
4. Code
5. ME Cad design
6. Final Thoughts
7. Download Original files

 

 INTRODUCTION

This is a fun little project that actually took me awhile to put together.  What makes this project interesting and useful is that it will display your voltage, current, and power of any device you plug it into.  What also makes this project useful is that it will calculate the efficiency of your device for example a dc dc converter.

The heart of this project is two INA219 high side current sensors from Texas Instruments.  With this sensor you can measure up to 26V DC and up to +/-3.2A with a 0.1ohm shunt resistor (if you swap out the shunt with a 0.01ohm shunt you can measure up to +/-32A)

BILL OF MATERIALS

Click Here for bill of materials

BLOCK DIAGRAM

Here you can see a block diagram showing how I connected the different boards to create this project. Since I used my CNC machine to create the boards, it’s always much easier to separate the circuits into different boards for routing.

The main board consist of an arduino pro mini to keep the footprint as small as I can and also host a 5V boost converter being power from the 18650 lithium ion battery.  In order to charge the battery without having to remove it from the enclosure, I decided to add a lithium ion charger board that connects in parallel with the battery.  Its powered by a 5V USB mini connector and can be bought on amazon.

The second board host x2 INA219 high side I2C current, voltage, and power sensor by Texas Instrument.  This IC is an amazing little thing because it takes a lot of the number crunching away from the Arduino and just sends the data over I2C that you need.

The final piece of this is the I2C liquidcrystal display for the arduino.  I used this library here for the display.  Make sure you connect the display and run an i2c address scanner on the examples for arduino because sometimes the displays have a different address than the default one listed.

SCHEMATIC

CODE

/*
 * Name: Steven Guzman
 * Date: 2018/03/18
 * Description: This is a DC power meter that measures input and output
 *              power and calculates the efficiency of the system.
 *              It can also measure voltage and current of one or two
 *              voltage sources
*/
#include 
#include 
#include 

LiquidCrystal_I2C lcd(0x3F,20,4); // Set the LCD address

/*
 * Below are the array values to store the measurements
 * and then used to convert float to string
 */
char float_volt1[8];  // voltage 1 array
char batt0[21];
char float_volt2[8];  // voltage 2 array
char batt1[21];
char float_current1[8]; // current 1 array
char curr1[21];
char float_current2[8]; // current 1 array
char curr2[21];
char float_eff[8];  // efficiency variable array
char line6[21];
char float_batt[6]; // battery voltage array
char line5[21];

// Analog sampling number
int sample = 20;

// Inialize current sensors.
// ina219_A default address is 0x40
Adafruit_INA219 ina219_A;
Adafruit_INA219 ina219_B(0x43);

// Variables to store current sensor data
float busvoltage1 = 0;
float busvoltage2 = 0;
float current_mA1 = 0;
float current_mA2 = 0;

float batt = 0.00;

void setup()
{
  Serial.begin(115200);
  while(!Serial)
  {
    delay(1);
  }

  ina219_A.begin();
  ina219_B.begin();

  lcd.init();
  lcd.init();
  lcd.backlight();

}

void loop()
{
  float xbat = 0.00;

  for(int x=0;x<sample;x++)
  {
    batt = analogRead(A0);
    xbat = xbat + batt;
  }
  // Read voltage levels from the voltage address
  // of the IN219 on both ICs
  busvoltage1 = ina219_B.getBusVoltage_V();
  busvoltage2 = ina219_A.getBusVoltage_V();

  // Read current levels from the current address
  // of the IN219 on both ICs
  current_mA1 = ina219_B.getCurrent_mA();
  current_mA2 = ina219_A.getCurrent_mA();

  // Average out the analog measurements
  // for the lithum ion battery voltage
  // sensing
  xbat = xbat/sample;
  float battery = xbat * (5.00/1024);
  dtostrf(battery,4,2,float_batt);
  sprintf(line5, "Battery:%-5s",float_batt);
  char temp3[] = "V";
  strcat(line5,temp3);

  // Convert float values into an char array to
  // better update on the lcd screen without
  // having to use the lcd.clear function
  dtostrf(busvoltage1,4,2,float_volt1);
  sprintf(batt0, "V1:%-5s",float_volt1);
  char temp2[] = "V";
  strcat(batt0, temp2);

  dtostrf(busvoltage2,4,2,float_volt2);
  sprintf(batt1, "V2:%-5s",float_volt2);
  char temp1[] = "V";
  strcat(batt1, temp1);

  // Convert mA to A readings
  float C1 = current_mA1/1000;
  float C2 = current_mA2/1000;

  dtostrf(C1,4,2,float_current1);
  sprintf(curr1, "C1:%-5s",float_current1);
  char temp4[] = "A";
  strcat(curr1, temp4);

  dtostrf(C2,4,2,float_current2);
  sprintf(curr2, "C2:%-5s",float_current2);
  char temp5[] = "A";
  strcat(curr2, temp5);

  float power1 = busvoltage1 * C1;
  float power2 = busvoltage2 * C2;

  float eff = (power2/power1)*100;

  dtostrf(eff,5,2,float_eff);
  sprintf(line6, "Efficiency:%-7s",float_eff);

  /*
   * Display on LCD screen all the values.
   * I used char arrays to update the values on the
   * screen.  Using the lcd.clear caused flickering
   * and was annoying.  With char array you can include
   * the units and it will update properly and not
   * overright the units.
   */
  lcd.setCursor(0,0);
  lcd.print(batt0);

  lcd.setCursor(11,0);
  lcd.print(batt1);

  lcd.setCursor(0,1);
  lcd.print(curr1);

  lcd.setCursor(11,1);
  lcd.print(curr2);

  lcd.setCursor(0,2);
  lcd.print(line6);

  lcd.setCursor(0,3);
  lcd.print(line5);

  delay(500);

}

There might be some issues with how wordpress displays the arduino code but I attached the original files at the end this tutorial.

As mentioned before, the libraries used here I obtained from other sources:

  1. Liquid crystal display library
  2. INA219 adafruit library

ME CAD DESIGN

I designed the enclosure in fusion 360 and printed the both with matterhackers pro series PETG red.  I used a monoprice maker select v2 to print this enclosure.

Here is the step file for the enclosure

FINAL THOUGHTS

This was one of my favorite projects yet because the design alone makes me feel accomplished learning everything on my own.  I still feel like I can make some upgrades to how I mount the internals and to be honest, I really rushed this part because I wanted to finish it.

Some upgrades I’m considering is using the arduinos internal 1.1V reference with a voltage divider to measure the battery voltage because it wasn’t as accurate as I wanted it to be.

Thank you for visiting and reading my project. if you have any questions or comments or suggestions please don’t hesitate to ask.

DOWNLOAD ORIGINAL FILES 

Original files

Electronics: FTDI USB TO UART

Donations

Anything would help really. My goal is to have this website ad free and so you can enjoy my content without having to look at ads. Thank you

$0.25

 

 

TABLE OF CONTENTS

1. Introduction
2. Bill of Materials
3. Schematic
4. Oshpark
5. Final Thoughts
6. Download Original files

INTRODUCTION

With the Arduino mini, there is a need for a USB to UART controller to upload your sketches and this could also be used for the ESP8266.

This project is inspired and based off the Sparkfun’s FT231X breakout board design.  I’ve created this project because 1. I like designing and soldering electronics 2. Try to create a cheaper alternative to the popular FT232RL and also add 1 or 2 features to the current FT231X breakout board.

BILL OF MATERIALS

For the bill of materials, its pretty straight forward.  I’ve attached links to digikey for each component as I find them easier to order from but you could also get the parts from arrow or mouser as well.

 

 

Component Description Part number Quantity Link
47pF, 0603, 50V C1608C0G1H470J080AA 2 Digikey
0.1uF, 0603, 25V CGA3E2X7R1E104K080AA 4 Digikey
10uF, 0805, 6.3V TCJN106M006R0250 1 Digikey
Micro B Connector 10118192-0001LF 1 Digikey
6-pin Header M20-7910642R 1 Digikey
N-Channel FET BSS84-FDICT-ND 1 Digikey
27 ohm, 1206 RC1206JR-0727RL 2 Digikey
10k, 0603 RT0603DRD0710KL 2 Digikey
FT231X, SSOP-20 FT231XS-U 1 Digikey

SCHEMATIC

Below I’ve attached an image of the schematic but i’ve also attached the original kicad files and a PDF version of the schematic at the end of the post.

OSHPARK

If you feel like you want to get this board made, I’ve attached a link to my oshpark project.  With oshpark, I find they make great quality boards at a great price for small sized boards.

Order from OSH Park

FINAL THOUGHTS

I know this was a short post and project but I found it important to share another option for those’s who want to find a cheaper solution and want to learn along the way.  You can find a lot cheaper solutions on amazon that are china made but i’ve read stories in some cases that they were not genuine FT232RL ICs.  If you wish to build your own, its very easy and rewarding at the same time.

In the next revision I will add LEDS for TX and RX indication as for this version I eliminated to save some cost and space.

Hope you enjoyed this post, THANK YOU 🙂

DOWNLOAD ORIGINAL FILES

https://app.box.com/s/50ap9obq89ucydbqqn54tye6ae3xiu34

 

Arduino: WiFi Temperature Data Logger

Introduction

Lets build a WiFi temperature data logger!!  The reason this project came to mind was because I needed to monitor the temperature of an outside enclosure box that will eventually house a couple of lithium ion batteries.  Can’t have the box get too hot or else we will end up having a nice backyard campfire.

This temperature data logger consist of three sections:

  1. The WiFi web server
  2. The temperature sensor
  3. The sleep controller

Lets get into the project now 🙂

Schematics, PCB, Arduino Libraries can be downloaded Here

Bill of Materials

  • x1 ESP8266 – Link
  • x1 Barometric (BMP180) – Link
  • x1 Atmega328P-PU – Link
  • x1 FTDI to Serial Converter – Link
  • x1 2N7002 – Link
  • x1 DMG2305UX-7 – Link
  • x7 10k Resistor 1206 – Link
  • x3 0.1uF Capacitor 1206 – Link
  • Female Headers – Link
  • x1 28 pin DIP Socket – Link
  • x1 PCB Terminal block – Link
  • x1 3.3V Boost Converter – Link

Hardware/Schematic/Assembly

I’ve designed this project to consist of two microcontrollers.  Its not the most efficient way of doing it but it is effective.  The heart of this project is the ESP8266-ESP01 IC.  It will take in the data from the BMP180 sensor over I2C and send the data over to a web hosting site Thingspeak.com

Schematic:

Webserver - Schematic

The schematic is not that all complicated but it is very effective at trying to save as much battery as possible and deliver my data for viewing purposes.

In order to have this be powered by 2x AA batteries and last longer then a couple of days or weeks, I needed a couple of things to make this possible which is where the second microcontroller comes into play.

First, we need to make sure we have a stable power supply that can provide up to at least 0.3A and have a minimum quiescent current in the low uA range.

Thingspeak.com

Before we get started into writing the code on the ESP8266 we need to set up an account at thingspeak.

Blog - Thingspeak

Click on the signup and fill out the information:

Blog - Thingspeak_2

Click on new channel:

Blog - Thingspeak_3

The most important information to fill out is the fields, in our case we will fill out field 1 and type in temperature.  The name could be any name you want, for this purpose we will write Temperature Data Logger. Once finish, scroll down and click save.

Blog - Thingspeak_4Blog - Thingspeak_5

The final piece of information we need is the API key, for this just click on the API Keys button and copy the Write API Key.

Blog - Thingspeak_6

Now we can move on to the code.

Click here for step by step on installing the ESP8266 arduino addon.[3]

ESP8266 Code

//////////////////////////////////////////////////////////////////////////////////
// Name: Steven Guzman                                                          //
// Date: 4/4/2017                                                               //
// Description: Temperature webserver that will update every 30 minutes to      //
//              thinkspeak with data that shows the temperature of the inside   //
//              of the enclosure.                                               //
//////////////////////////////////////////////////////////////////////////////////

#include <ESP8266WiFi.h&>
#include <Wire.h>
#include <SFE_BMP180.h>

SFE_BMP180 pressure;

char status;
double t, tf;

// Replace with your channel's thingspeak API key
String apiKey = "";

// Enter your wifi information below
const char* ssid = "";
const char* password  = "";

const char* server = "api.thingspeak.com";

WiFiClient client;
void setup()
{
Serial.begin(115200);
delay(10);
// Pin 0 = SDA
// Pin 2 = SCL
Wire.begin(0,2);

WiFi.begin(ssid,password);

Serial.println();
Serial.println();
Serial.print("Connecting to ");

while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.println("WiFi Connected");

// Initialize the sensor
if (pressure.begin())
{
Serial.println("BMP180 init success");
}
else
{
Serial.println("BMP180 init fail\n\n");
//while(1);
}

// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}

void loop()
{
// This starts the BMP180 sensor and takes a reading
status = pressure.startTemperature();
if (status !=0)
{
delay(status);
status = pressure.getTemperature(t);
}
// Converts Celsius into Farenheid
tf = (9.0/5.0)*t+32.0,2;
if(client.connect(server,80))
{
char t_buffer[10];

// This will convert the double variable into a string
String temp=dtostrf(tf,0,5,t_buffer);
String postStr = apiKey;
postStr +="&field1=";
postStr += String(temp);
postStr +="\r\n\r\n";

client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKapiKey: "+apiKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);

Serial.print("Temperature: ");
Serial.println(t);
Serial.println((9.0/5.0)*t+32.0);
Serial.println(temp);
}

client.stop();

Serial.println("Waiting...");
delay(20000);
}

Arduino Code

///////////////////////////////////////////////////////////////////////////////////////////
/// Title:  Auto Garden Project                                                          //
/// Author: Steven Guzman                                                                //
/// Date:   4/6/17                                                                      //
/// Description: This project will automatically water a plant when the sensor reads low //
///              water levels in the soil.  If sensor reads low water, it will turn on   //
///              boost converter that controls the solenoid valve and then turn on the   //
///              solenoid valve control circuit to allow water to flow into the soil.    //
///////////////////////////////////////////////////////////////////////////////////////////

#include <LowPower.h>

int ESP1 = 2;          // Turns on sensor; set to low for battery consumption purposes (Active High)

void setup()
{

pinMode(ESP1,OUTPUT);     // Configure sensor control as output
digitalWrite(ESP1,LOW);   // Setup as low output
delay(100);
}

void loop()
{

digitalWrite(ESP1,HIGH);  // Turns on the ESP8266
delay(15000);             // 15 second delay
digitalWrite(ESP1,LOW);   // Turns off the ESP8266

// Loops the 8 second internal to extend the sleep state
// 15 = 2 minutes
// 37 = 5 minutes
// 75 = 10 minutes
// 112 = 15 minutes
// 255 = 30 minutes

for(int x = 0; x <= 255; x++)
{
LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
}

}

Programming

ESP8266-ESP01

First things first, we will upload the code to the ESP8266-ESP01.  This one is a little bit tricky but after awhile you’ll get the hang of it.

You need to make sure your settings are correct under the Arduino IDE.

See image below:

Arduino ESP8266 settings

Here’s the wiring diagram for connecting the FTDI programmer to the ESP8266:

Blog - ESP8266_WIRING

Now that your settings are correct, this is were it gets a little tricky to upload the code, you need to follow the steps below in order to upload correctly and successfully

Before hitting upload:

  1. Ground GPIO0 (hold down the push button JP2)
  2. Reset by pulling RST pin to ground (Press and release JP1 button)
  3. Once it restarts, hit the upload sketch icon
  4. When you see compiling sketch switch to uploading, then release the GPIO0 pin
  5. uploading should begin
ATMEGA328P-PU (ARDUINO LILYPAD)

Next, we will upload the second code into the ATmega328 which has the lilypad bootloader installed ( Click HERE [2] for tutorial on flashing ATMEGA328P-PU with bootloader).

See image below for settings:

Blog - ESP8266

Final Thoughts and Future updates

And now the final product:

Blog - Thingspeak_graph

Its not the most elegant but I actually used my CNC machine to make these boards, in the future I might get them professionally made but for now its perfect for me.

Future Updates:

  1. Replace the ATMEGA328P-PU IC with a smaller ATTINY85 which can also be flashed with the Arduino bootloader
  2. Connect the Arduino to the I2C communication lines to expand its data logging capability
  3. Since this is running on 2x AA NiMH batteries, it would be great to monitor battery capacity.  We can use one of the analog pins on the arduino to read the data and send it over I2C to the ESP8266

1. Arduinesp
2. ATMEGA328 Bootloader
3. ESP8266 installation