I am measuring power(watt) with a non invasive sensor SF-SEN-11005 30A.

After calibrating on 150 watt it works fine. When I disconnect the sensor I expect a zero value, which is not the case. The value is around 15 watt.

By higher power the value decrease relative to the real power and increase relative to the real power.

All the information I found by googling.

Here is my code and wiring.

#!/usr/bin/env python

# just some bitbang code for testing all 8 channels
import math
import RPi.GPIO as GPIO, time, os
#import urllib2
import time

apike = "yourapikey"
emoncmspath = ""
interval = 1 # 1 sec

# this function is not used, its for future reference!
def slowspiwrite(clockpin, datapin, byteout):
    GPIO.setup(clockpin, GPIO.OUT)
    GPIO.setup(datapin, GPIO.OUT)
    for i in range(8):
        if (byteout & 0x80):
            GPIO.output(datapin, True)
            GPIO.output(datapin, False)
        byteout <<= 1
        GPIO.output(clockpin, True)
        GPIO.output(clockpin, False)

# this function is not used, its for future reference!
def slowspiread(clockpin, datapin):
    GPIO.setup(clockpin, GPIO.OUT)
    GPIO.setup(datapin, GPIO.IN)
    byteout = 0
    for i in range(8):
        GPIO.output(clockpin, False)
        GPIO.output(clockpin, True)
        byteout <<= 1
    if (GPIO.input(datapin)):
        byteout = byteout | 0x1
        return byteout

# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
    if ((adcnum > 7) or (adcnum < 0)):
        return -1
    GPIO.output(cspin, True)
    GPIO.output(clockpin, False)  # start clock low
    GPIO.output(cspin, False)     # bring CS low
    commandout = adcnum
    commandout |= 0x18  # start bit + single-ended bit
    commandout <<= 3    # we only need to send 5 bits here
    for i in range(5):
        if (commandout & 0x80):
            GPIO.output(mosipin, True)
            GPIO.output(mosipin, False)
        commandout <<= 1
        GPIO.output(clockpin, True)
        GPIO.output(clockpin, False)
    adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
    for i in range(12):
        GPIO.output(clockpin, True)
        GPIO.output(clockpin, False)
        adcout <<= 1
        if (GPIO.input(misopin)):
            adcout |= 0x1
    GPIO.output(cspin, True)
    adcout /= 2       # first bit is 'null' so drop it
    return adcout

# change these as desired
SPICS = 25

# set up the SPI interface pins

# Note that bitbanging SPI is incredibly slow on the Pi as its not
# a RTOS - reading the ADC takes about 30 ms (~30 samples per second)
# which is awful for a microcontroller but better-than-nothing for Linux

#RMS calcule fonction
def CalcIrms(cts):
    ICAL = 58.5
    sumI = 0
    sampleI = 512
    filteredI = 0
    for n in range (0, NUMBER_OF_SAMPLES):
        lastSampleI = sampleI
        sampleI = readadc(cts, SPICLK, SPIMOSI, SPIMISO, SPICS)
        #print sampleI
        lastFilteredI = filteredI
        filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI)
        sqI = filteredI * filteredI
        sumI += sqI
    I_RATIO = ICAL * ((SUPPLYVOLTAGE/1000.0) / 1023.0)
    Irms = I_RATIO * math.sqrt(sumI / NUMBER_OF_SAMPLES)
    sumI = 0
    return Irms
# mcp3008 input
ct1_adc = 0
#ct2_adc = 1
#ct3_adc = 2
#ct4_adc = 3
# Convert the reading value in RMS

# ct1 and ct2 monitor my 2 pole 240v main power 
while True:
    ct1 = CalcIrms(ct1_adc)*120 #ct1 and ct2 are added by emoncms 
#   ct2 = CalcIrms(ct2_adc)*120
#   ct3 = CalcIrms(ct3_adc)*240
#   ct4 = CalcIrms(ct4_adc)*240
    print "ct1: %.2f watt" % ct1
#   print "ct2: %.2f watt" % ct2
#   print "ct3: %.2f watt" % ct3
#   print "ct4: %.2f watt" % ct4
#   urllib2.urlopen("http://"+emoncmspath+"/input/post.json?node=8&csv="+str(ct1)+","+str(ct2)+","+str(ct3)+","+str(ct4)+ "&apikey=" + apike)

fritzing image

  • 1
    This probably isn't part of the problem but you could use the SPI hardware (via the spidev module) rather than bit banging SPI. Are you sure the filter (CalcIrms) isn't the problem? What happens if you just use the raw values? – joan Jan 22 '18 at 14:09

This is due to the fact that you are computing RMS (Root Mean Square). There is nothing you can do against that and it will always be (unless you opt for a different type of circuit).

To have the resulting RMS equal to zero means the signal coming from the CT is a perfect straight line. However there is always a tiny current change on the divider that you made. This sums up into the RMS computation.

I saw you are using 120V to compute power. So you are only reading 0.125A without CT connected. Not that bad considering the cheap setup.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.