1
\$\begingroup\$

I need to sample 50Hz voltage signals from four CT current sensors and compare the waveforms to a voltage signal from the mains (stepped-down and offset for ADC) to accurately measure power consumption of four devices.

I would like to get at least 360 samples for each waveform per period, meaning 1800 total samples per second. Since the signal frequency is 50Hz, this means a reading speed of 90kHz.

I have an MCP3008 10-bit ADC available which uses an SPI interface, an Arduino Uno board, and a Raspberry Pi 2.

The MCP3008 has a max sampling rate of 200ksps (datasheet).

The Arduino Uno analogue input pins can be read at 10kHz (official docs).

The Raspberry Pi can work with SPI interfaces at 20kHz using the standard Linux driver, as mentioned here, although by bypassing the standard Linux driver it can supposedly work faster (I don't know how much faster - there are a lot of different numbers being thrown around online).

The Arduino Uno can work with SPI interfaces at much higher speeds than the Raspberry Pi.

From what I can gather, there are three setups to choose from:

  1. Reading the 5 values directly using analogueRead() of the Arduino (clearly won't work)
  2. Using the MCP3008 ADC with the Raspberry Pi (is it possible to make it fast enough with some modifications?)
  3. Using the MCP3008 ADC with the Arduino

Can the required speed be achieved using any of the above-mentioned setups? If not, what would likely be the maximum speed that can be achieved?

\$\endgroup\$
14
  • 1
    \$\begingroup\$ Your statement of the needed sampling rate is less than clear, perhaps you mean 360 samples per period? Anyway, 10 bits at 200 KSPS implies a minimum of a 2 MHz SPI clock. I'm not sure you can get the Arduino linked to the pi faster than about 1 MBPs asynchronous serial, unless you figure out some way to do a parallel interface, so that may be a bottleneck. You might want to look at something like an FT2232 USB interface engine, or an ARM Cortex MCU, perhaps the STM32F303 which has USB, an ADC far faster than you need and more available ram for buffering. \$\endgroup\$ Commented Mar 10, 2016 at 23:44
  • 1
    \$\begingroup\$ I wouldn't rule out the arduino ADC that quickly. The μC in the uno is the ATmega328, which has a 10-bit ADC that takes 13 ADC clock cycles for each sample in free running mode. While the 10 bit precision is only valid when the ADC clock frequency is between 50 and 200 kHz, you could clock the ADC at 1 MHz, allowing for 76.9 kSa/s at about 8 bits of precision. For changing the ADC channel, you would use the ADC conversion complete interrupt. \$\endgroup\$
    – jms
    Commented Mar 11, 2016 at 0:03
  • 2
    \$\begingroup\$ @M.Hassaan - I would not recommend trying to acquire the samples with the pi - unless you have hard evidence that it is possible and with low clock jitter, realtime sampling is generally a task that is a much better fit for a stand alone micro with a DMA-capable SPI engine or internal ADC. \$\endgroup\$ Commented Mar 11, 2016 at 0:07
  • 2
    \$\begingroup\$ Reducing the accuracy requirement to 8 bits would make the ATmega buffering problem simpler, too. Even better would be if you determine that you don't have to sample all of the channels interleaved at the same time, but if you could just gather a full block of data for each (or each and the reference) in turn, as that would cut both your sampling rate and storage requirement. \$\endgroup\$ Commented Mar 11, 2016 at 0:10
  • 1
    \$\begingroup\$ Then you could set the ADC prescaler to 32, giving you an ADC clock frequency of 500 kHz from the 16 MHz clock. 500 kHz / 13 = 38.5 kSa/s, but with substantially less noise at the least significant bits than you would get with a 1 MHz ADC clock frequency. If you only need the 8 most significant bits, you can set the ADLAR bit (ADC left adjust result) in the ADMUX register, which shifts the 8 most significant bits to the ADCH register eliminating the need for bit shifting and masking operations in your code. \$\endgroup\$
    – jms
    Commented Mar 11, 2016 at 0:38

2 Answers 2

2
\$\begingroup\$

If you can get the scaled signal voltage swing within 1Vpp you probably can just use the sound card of your computer. Three USB sound cards that each supports 192kHz sampling rate and you are good to go.

\$\endgroup\$
7
  • \$\begingroup\$ Smart :) I like it! But there is a need to have 5 channels, I am unsure if it is easy to find a sound card with 5 channel input capability. Of course multiple sound cards might be a solution :) I like this idea since voltage and current measurement is precisely in sync on a stereo input. \$\endgroup\$
    – Gee Bee
    Commented Mar 11, 2016 at 13:23
  • \$\begingroup\$ @GeeBee Each sound card have 3 input channels, one in microphone, two in line in. Also there is nothing preventing you from attaching multiple cheap USB sound cards to one computer. \$\endgroup\$ Commented Mar 11, 2016 at 13:26
  • \$\begingroup\$ I am afraid there is only one stereo ADC. Even though you have multiple inputs, you can not ADC all of them at the same time. The problem with multiple cards is to keep them in sync with practically zero jitter. A jitter less than 55 microseconds is acceptable. Although I had the fun of programming sound cards in assembly in the past and set up the DMA channels, I really feel that keeping multiple sound cards in this hard sync would be a real challenge. Do you have a solution for that? \$\endgroup\$
    – Gee Bee
    Commented Mar 11, 2016 at 17:30
  • \$\begingroup\$ @GeeBee You can still use more than one USB sound cards on one computer. \$\endgroup\$ Commented Mar 12, 2016 at 9:29
  • 1
    \$\begingroup\$ Since you have 4 outlets, you can use 4 USB sound cards' line in signals. All left channels are paralleled, used as the voltage sense signal; and right channels are used as current sense for each outlet. This gives you 4 independent phase-matched digital reading sets. By the way, since you are already using a computer, you can let the GPU do the multiplication (and FFT if you need to) as it is massively parallel and have no branching. \$\endgroup\$ Commented Mar 12, 2016 at 21:48
1
\$\begingroup\$

What about using a meterig chip such as MCP3909?

There is a good set of information on this topic at http://www.microchip.com/design-centers/utility-metering-solutions/electric-meter/overview

Proper power metering is not an easy topic. You don't only need to measure both power and current at a very high sampling rate and resolution, but you also need to do the multiplications in real-time. These dedicated utility metering chips will do this all for you, and some of them also provide additional power info such as power factor.

\$\endgroup\$
9
  • \$\begingroup\$ Unfortunately I don't have the time to order them at this point. Will take too long to ship to United Arab Emirates. \$\endgroup\$
    – Hassaan
    Commented Mar 11, 2016 at 0:53
  • 1
    \$\begingroup\$ A dedicated chip could indeed be worth considering absent that shipment issue (especially as the possibility of a pi points to this being a one-off or low-volume rather than cost optimized project). However, the comment about realtime multiplication is incorrect. What is needed is to multiply voltage and current readings from the same point in time, however the actual computation can be done asynchronously at a later point as long as the values are collected, stored and multiplied in a way that maintains their time correspondence. \$\endgroup\$ Commented Mar 11, 2016 at 1:02
  • 1
    \$\begingroup\$ Well... the problem is at the same time. You can't measure current and voltage at the same time with multiplexed input ADCs - this itself may yield to some (minimal) measurement errors. Storing the measurements may be more problematic than doing the mulitplication. 10 kilobytes needed for 1 second of data, and if we need more data we have to go to some flash, or external ram (writing that serially is actually slower than doing the multiplication, no?) \$\endgroup\$
    – Gee Bee
    Commented Mar 11, 2016 at 1:09
  • \$\begingroup\$ @M.Hassaan, can you give up something from the specs? For example, if the load is resistive (or has a power factor correction) then you will see nice sine waves both on current and voltage. You can then make acceptable measurements with much smaller smaling rate, e.g. 100 samples per 20mS period, or even less. In fact if you have sine waves, it is ok to find the zero crossing on the current and voltage to calculate a power factor. Then you can read only the current sensor for like 20mS to get a maximum, same with the voltage sensor. Then you can make a mathematical approximation of the... \$\endgroup\$
    – Gee Bee
    Commented Mar 11, 2016 at 1:14
  • 2
    \$\begingroup\$ Using a Raspberry is not a good choice, as you have to fiddle with software challenges (reading jitter because of the interrupt handling). I suggest to go with Arduino. If you still need the high sampling rate, try "interlace" your readings. That is get 180 samples in 20ms first - "even" samples -, then after 55 microsecond start another read - "odd" samples. This halfs your actual ADC sampling rate. You may need to have several seconds of data to calculate good results. Most of the loads have strange transient behavior at powerup. \$\endgroup\$
    – Gee Bee
    Commented Mar 11, 2016 at 1:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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