ADS1015

fernando_g

Senior Member
I am studying the popular 4 channel, 12 bit A/D, the ADS1015 and how could I use it with a Picaxe.

The ADS1015 output register contains a word formatted as follows:

bit11: bit10: bit9: bit8: bit7: bit6: bit5: bit4: bit3: bit2: bit1: bit0: 0: 0: 0: 0

Would this mean that to be compatible with standard Picaxe maths, I would have to first shift it four times (divide by 16), prior to further use?

I believe the answer is yes.
 
Would this mean that to be compatible with standard Picaxe maths, I would have to first shift it four times (divide by 16), prior to further use?
Yes (or, if you are using an X2, shift right by 4 bits).
I used two ADS1015s in my Picaxe-based Power Monitor for measuring mains current and voltage (I am avoiding "smart" meters for as long as possible). I suspect mine were clones, because the negative option didn't work, so I had to shift everything up, and ended up with 11 bits rather than 12.

(Not the most brilliant picture - I think the screen is too bright for the rest to show up properly).
 

Attachments

  • PowerMonitor.png
    PowerMonitor.png
    319.6 KB · Views: 13
Thanks for your reply.

One question about your power monitor: to calculate the power, did you use a straight multiplication of the volts and amps, or did you also took into account the power factor and THD?
 
This monitors the incoming mains (and used to do the photovoltaic panels as well, until their connection point was moved) rather than a particular piece of equipment. It is "simply" multiplying volts by amps (32- or 48-bit arithmetic to handle the size of numbers in total kWh).
 
Hi,

For ac Power, you don't need to "know" the Power Factor as such, you can just multiply the instantaneous Voltage by instantaneous Current perhaps every millisecond and accumulate (sum) the power over a known time. However, the V , I and multiplication must all be signed (Two's Complement) but that should be coming from the ADC, then you can multiply with * and ** operators to give a 32-bit result which needs to be complemented (subtracted from zero) if I and V were of opposite polarity. Normal PICaxe addition (extended to 32 , 48 or whatever bits) works fine with two's complement numbers (remembering to "Extend the sign" of long, negative numbers), but if the final accumulated sum is negative (MS Bit is a 1), then you need to complement the sum and display with a "-" prefix.

I don't know the necessary sampling rate, but you should be able to Low-Pass Filter the I and V if necessary (using Hardware), ensuring that the two filters have identical Phase Shifts and negligible/corrected attenuation at the Line Frequency (and any desired harmonic content).

Cheers, Alan.
 
My version reads V,A,A,V as a set, then averages the two Vs and the two As to get (approximately) values for the same instant. Going as fast as storing the data is possible (into scratchpad) it manages around 30 measurements per 50Hz cycle.
 
Aries and Allycat;
I am familiar with the sample by sample multiplication of the two waveforms will provide true power, which intrinsically takes into consideration the power factor. I have seen this done on raw PICs running compiled languages.

But my understanding is that the Picaxe doesn’t have neither the speed nor the bit depth necessary for such calculations.
Would you please elaborate on how to circumvent these Picaxe constraints?
 
These are a few extracts from my own code. The principle is to grab as much data as fast as possible (first loop). Then do the calculations (second loop). There is much more to it in the details, but these are the bare bones. The whole thing samples the mains about once every 2-3 seconds and calculates an average wattage each minute, which accumulates to kWh. There is a division by 16 (shift 4 bits right) but it's not in the sections I have included below.

AllyCat has a set of 32-bit code snippets (https://picaxeforum.co.uk/threads/a...rd-division-subroutine-32-bits-16-bits.21502/ and https://picaxeforum.co.uk/threads/3...-bmp280-and-bme280-atmospheric-sensors.30367/ for example). Mine are shown at the end of the code below.

Code:
    do
        hi2cin [I2cVoltageSlave],(b1,b0)        ' AC first in w0
        hi2cin [I2cCurrentSlave],(b3,b2)        ' current second in w1
        hi2cin [I2cCurrentSlave],(b7,b6)        ' current again in w3
        hi2cin [I2cVoltageSlave],(b5,b4)        ' AC last in w2
        w0 = w0 + w2                                                ' total of values
        w1 = w1 + w3
        @ptrinc = b0                                                ' store voltage first
        @ptrinc = b1
        @ptrinc = b2                                                ' then current
        @ptrinc = b3                                                ' and store
    loop until ptr > VAareaEndMinus4
'--------------------------------------------------------------------------
    do
        gosub GetVAvalues
        gosub MultiplyW8W9    ' multiply into (w3,w2)
        gosub Add32                ' accumulate total
    loop until ptr > w14
'--------------------------------------------------------------------------
GetVAvalues:
    b16 = @ptrinc                ' first value in w8
    b17 = @ptrinc
    b18 = @ptrinc                ' second in w9
    b19 = @ptrinc
    return
'--------------------------------------------------------------------------
' multiply w8 by w9 return result in (w3,w2)
' sign extend w8, w9 if required
MultiplyW8W9:
    w2 = w8 * w9                                            ' LO1 * LO2 (->LO)
    w3 = w8 ** w9                                            ' LO1 ** LO2 (->HI)
    w3 = w8 >> 15 * $FFFF * w9 + w3        ' HI1 * LO2 (->HI)
    w3 = w9 >> 15 * $FFFF * w8 + w3        ' LO1 * HI2 (->HI)
    return
'--------------------------------------------------------------------------
' Add two 32 bit numbers (w1..w0) and (w3..w2)
' returns result in (w1..w0)
Add32:
    w0 = w0 + w2
    if w0 < w2 then
        w1 = w1 + 1
    endif
    w1 = w1 + w3
    return
'--------------------------------------------------------------------------
' Multiply two 32 bit numbers (w1..w0) and (w3..w2)
' USES w4-w5
' returns 32-bit result in (w1..w0)
' ignores 32-bit overflow
Multiply32by16:                        ' multiply (w1..w0) by (0..w2)
    w3 = 0
Multiply32:
    S_W0 = w0 * w2                    ' LO1 * LO2 (->LO) in w0
    S_W1 = w0 ** w2                    ' LO1 * LO2 (->HI) in w1
    S_W1 = w1 * w2 + S_W1            ' HI1 * LO2 (->HI) in w1
    w1 = w0 * w3 + S_W1            ' LO1 * HI2 (->HI) in w1
    w0 = S_W0
    return
 
Hi,

I've never written a PICaxe program to measure mains (ac) power, nor examined the ADS1025 data sheet, but I have paid some attention to maximising the speed of PICaxe programs. Obviously, the speed can't compare with custom Assembler or Pre-Compiled code, but here are a few tips to achieve the best from a PICaxe. The 08M2 is the fastest M2 (because it has less memory and pins to access) and although the X2s can run at twice the clock speed, they have longer "Tokens" (because they have more instructions, more pins and more memory) so they might not be much faster. Also, some of the more "advanced" instructions are actually "System-Created Macros" which may be slower than writing equivalent functions yourself.

There is no speed penalty in using Word Variables instead of Bytes in calculations, but storing data is limited to byte-width. However, there is no additional time penalty when adding the Auto-increment (address) in @BPTRINC Reads and Writes. Similarly READADC10 is always performed (and truncated for READADC), taking a similar time to most other PICaxe instructions. But it has its own clock which I believe does not fully implement SETFREQ (but a POKESFR could fix that). However, it appears that the fastest way to transfer data with a PICaxe is via HI2CIN/OUT, which is (potentially) faster than PEEKs and POKEs, particularly of multi-variable strings. But probably the greatest weakness of the PIC(axe) ADC is that it's unsigned, thus likely to add complications to any Hardware and Software implementation.

For the architecture, three consecutive Reads , e.g. V,I,V seem sufficient for each sample, or better I,V,I where the ADC current range could be halved to reduce power losses in the current-sensing resistor. PICaxe Basic can create a 32-bit product using the * and ** operators consecutively on the same word values, but a 16-bit result may well be sufficient if up to 16 or 20 instantaneous values are being accumulated over each single mains cycle. I suspect that the primary issues concerning the accuracy of any "Power" measurements, is the accuracy of the ADC Reference, the value/calibration of the current-sensing resistor(s) and of course the zero reference point.

Well, that's about all that I can think of that might be relevant at the moment. BTW the link above to my first Code Snippet appears to be broken, but it should be HERE.

Cheers, Alan.
 
Thanks Alan, I wasn’t aware that the 08M2 was the fastest Picaxe for the reason you outlined.

I will take that for consideration in my future projects.
 
Thanks Aries, for your code snippet. I can’t claim that I fully understand it.
I will paste it into PE6 and step through it while watching the variables table to understand it.
 
Back
Top