Rexxer

Some tips for me and other

Arduino + Energy Monitoring

Recently I’ve built a device for monitoring power consuption from http://openenergymonitor.org/emon/buildingblocks/how-to-build-an-arduino-energy-monitor

I used: Nokia 5110 display for Arduino, sensor SCT-013, power adapter AC-AC 9v.

I bought a cheap current sensor with LCD to calibrate my device (emon1.current(5, 28);).

I used Adafruit library because others didn’t work correctly.

My sketch for it:

#include “EmonLib.h”                   // Include Emon Library
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
EnergyMonitor emon1;                   // Create an instance
// Software SPI (slower updates, more flexible pin options):
// pin 7 – Serial clock out (SCLK)
// pin 6 – Serial data out (DIN)
// pin 5 – Data/Command select (D/C)
// pin 4 – LCD chip select (CS)
// pin 3 – LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 11, 12);

void setup()
{

Serial.begin(9600);
// init
display.begin();
display.setContrast(60);
//demo
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0,0);
//  delay(1000);
display.clearDisplay();

//  display.display();
// Calibration
emon1.voltage(4, 234.26, 1.7);
emon1.current(5, 28);             // Current: input pin, calibration.
}

void loop()
{
double Irms = emon1.calcIrms(1480);  // Calculate Irms only 1480
emon1.calcVI(20,2000); // Voltage

float realPower       = emon1.realPower;        //extract Real Power into variable
float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
float powerFactor     = emon1.powerFactor;      //extract Power Factor into Variable
float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
//float Irms            = emon1.Irms;             //extract Irms into Variable

//double Volt = emon1.readVcc();
//emon1.serialprint();
double Watt = Irms*supplyVoltage;
Serial.print(Watt);           // Apparent power
Serial.print(” “);
Serial.print(Irms);               // Irms
Serial.print(” “);
Serial.print(supplyVoltage);
Serial.print(” “);
Serial.print(realPower);
Serial.print(” “);
Serial.print(apparentPower);
Serial.println(” “);
//Display
display.print(“A=”);
display.println(Irms);
display.print(“W=”);
display.println(Irms*220);
display.print(“V=”);
display.println(supplyVoltage);
display.print(“RP=”);
display.println(realPower);
display.print(“AP=”);
display.println(apparentPower);
display.print(“PF=”);
display.println(powerFactor);
display.display();
delay(2000);
display.clearDisplay();

}

In the beginning my RRD graphs were strange – voltage and power looked like 0V, 23V, 180V, and so on. After some investigations I found the cause – 2 scripts asks USBtty and conflict with each other. So I composed them into a script:

#!/bin/bash
# Путь к исполнимому файлу rrdtool
RRDTOOL=/usr/bin/rrdtool

# Путь к базе, в которой храниться температура
DATABASE=/usr/local/rrd/power.rrd
DATABASEV=/usr/local/rrd/voltage.rrd

# Периодичность поступления данных в базу (сек) – соответственно должен быть настроен CRON
PERIOD=60

# Команда для получения текущей температуры с датчика!
DATASTR=`sed -n ‘n;n;p;q;’ < /dev/ttyUSB0` # omit 2 lines from tty because the first line contains not full data and the second line is empty
SENSOR=`echo $DATASTR | awk ‘{print $1}’`
SENSORV=`echo $DATASTR | awk ‘{print $3}’`
#SENSOR=`sed -n ‘n;n;p;q;’ < /dev/ttyUSB0 | awk ‘{print $1}’`
#SENSORV=`sed -n ‘n;n;p;q;’ < /dev/ttyUSB0 | awk ‘{print $3}’`
echo Power=$SENSOR Voltage=$SENSORV
# Путь к папке, в которой будут лежать изображения с графиками зависимости, каталог web-сервера.
IMAGE_PATH=/var/www/power

# Горизонтальная надпись в заголовке графика
TITLE_TEXT=’Электроэнергия’

# Горизонтальная надпись в легенде под графиком
UNDER_TEXT=’Статистика потребления электроэнергии’

# ========= ШАГ 1. Запись в базу данных полученных значений температуры ======

# Проверяем, присутствует ли вообще база для температуры. Если нет – создаём

if ! [ -f $DATABASE ]
then
$RRDTOOL create $DATABASE -s $PERIOD DS:input:GAUGE:600:U:U \
RRA:AVERAGE:0.5:1:576 \
RRA:AVERAGE:0.5:6:672 \
RRA:AVERAGE:0.5:24:732 \
RRA:AVERAGE:0.5:144:1460
fi
if ! [ -f $DATABASEV ]
then
$RRDTOOL create $DATABASE -s $PERIOD DS:input:GAUGE:600:U:U \
RRA:AVERAGE:0.5:1:576 \
RRA:AVERAGE:0.5:6:672 \
RRA:AVERAGE:0.5:24:732 \
RRA:AVERAGE:0.5:144:1460
fi

$RRDTOOL update $DATABASE N:$SENSOR
$RRDTOOL update $DATABASEV N:$SENSORV

# ============================================================================

# Функция для построения зависимости температуры от времени

function DRAW_GRAPHIC
{

# Определяем время, во сколько генерируется график
NOW_HOUR=`date +%H`
NOW_MIN=`date +%M`
NOW_SEC=`date +%S`

# На основе параметра 2, переданного функции вычисляем какой комментарий написать
case $2 in
day)
TIME_TEXT=”за последние 24 часа”
;;
week)
TIME_TEXT=”за последнюю неделю”
;;
month)
TIME_TEXT=”за последний месяц”
;;
year)
TIME_TEXT=”за последний год”
;;
esac

$RRDTOOL graph $IMAGE_PATH/$1 \
-s -1$2 \
-e now \
-a PNG \
-v $4 \
-t “$TITLE_TEXT $TIME_TEXT” \
-r \
-E \
-i \
-R light \
–zoom 1 \
-w 500 \
-h 150 \
–font DEFAULT:10:/usr/local/share/rrdtool/fonts/ARIAL8.TTF \
DEF:input=$3:input:AVERAGE \
LINE2:input#C0140E \
GPRINT:input:LAST:’Текущая\:%2.1lf’\
GPRINT:input:MIN:’Мин\:%2.1lf’ \
GPRINT:input:MAX:’Макс\:%2.1lf’ \
GPRINT:input:AVERAGE:’Средняя\:%4.1lf’
}

# ========= ШАГ 2. Отрисовка графиков зависимости температуры от времени ========
DRAW_GRAPHIC ‘power_d.png’ ‘day’ $DATABASE ‘Ватт’
DRAW_GRAPHIC ‘power_w.png’ ‘week’ $DATABASE ‘Ватт’
DRAW_GRAPHIC ‘power_m.png’ ‘month’ $DATABASE ‘Ватт’
DRAW_GRAPHIC ‘power_y.png’ ‘year’ $DATABASE ‘Ватт’

DRAW_GRAPHIC ‘volt_d.png’ ‘day’ $DATABASEV ‘Вольт’
DRAW_GRAPHIC ‘volt_w.png’ ‘week’ $DATABASEV ‘Вольт’
DRAW_GRAPHIC ‘volt_m.png’ ‘month’ $DATABASEV ‘Вольт’
DRAW_GRAPHIC ‘volt_y.png’ ‘year’ $DATABASEV ‘Вольт’

Some photos:

 

1. The sensor has a burden resistor already.

2. Calibration and comparison.

3. The bad image on the LCD with non-Adafruit library.

4. RRDtool graphs.

IMG_20141113_115730 IMG_20141118_183058 Untitledtemp

 

Comments are currently closed.