Hi everyone! I have a circuit where the Arduino Uno is connected to the BLE-module HM-10 and where this module sends a "Hey!" message to my smartphone every 500 milliseconds. My aim is to measure the power consumption by implementing the following tutorial:
The sensor used to measure power consumption is the current sensor ACS712:
Now, my question is: What has the load to be in my situation? Is it the HM-10 module (= scenario 1)? Or do I have to add a separate load like a LED with a resistor (= scenario 2)?
Which of the circuits is the right one? Or are they both wrong? How about the values? The values of scenario 2 are fluctuating and keep increasing while the values of scenario 1 also fluctuate, but are more stable.
The ACS712 is a very poor choice for measuring low currents. The sensitivity is typically 185 mV/Ampere for the 5 Ampere version, which means that for the HM-10 (say, 20 mA), the voltage output is 3.7 mV, and less than the Arduino can measure.
A better use for the ACS712 is to monitor DC motor current.
ACS stands for AC Sensor. with no current the analogRead returns 512 to be able to oscillate around that middle value as the current alternates between negative and positive.
Sounds like a roundabout way to simply say it has an offset of half its supply voltage. Which is true, but is till makes the device perfectly capable of measuring DC voltages. With the drawback of course the low resolution for small currents.
I'm confused as to what you want. Both circuits evidently work fine (with their inherent limitation; see above), but when you say you want to be able to measure power consumption, what do you mean? The power consumption of which device exactly?
Description
The Allegro® ACS712 provides economical and precise
solutions for AC or DC current sensing in industrial,
commercial, and communications systems.
The goal is actually to compare the power consumption of:
Arduino Uno + HM-10 sending data to a smartphone via BLE (Bluetooth Low Energy)
ESP32 sending data to a smartphone via BLE
The question is: Which of the two variants has the lowest power consumption? In order to answer this question I have to measure the power consumption for both variants.
Uhm, yeah. Not only that, you'd have to do so with a fairly high sample speed for the duration of the data transfer, and then integrate the measurements into a total power draw. Not as trivial as it may seem.
A quick & dirty approach is indeed do as @jremington says, but with the inherent limitation that you won't be able to accurately measure brief peaks. That's a limitation here because of the often spurious/intermittent nature of wireless communications (which tends to consist of bursts, after all).
So in principle your approach is OK, but the devil will be in the details, and the ultimate quality of your comparison will be determined at least to some extent (and possibly a large extent) by these details.
Anyway, neither of your experimental setups you've show before fits exactly with what you want. In setup 1 you only measure the BLE module and not the Arduino's consumption. This may be OK if you want to measure the Arduino separately, or if you decide to approximate the Arduino's power draw based on a theoretical model (i.e. perusing the relevant datasheets and adding stuff up - which all considered may in fact be a fairly OK approach to begin with for the entire endeavor...)
Scenario 2 measures the current of an LED which seems to bear no relation whatsoever to your project, so let's ignore that brain fart for a bit.
So scenario 1 comes close to at least partly realizing the measurement you want to do, but the quality of the measurement will depend on how you program it - and you'll have to complete it by measuring all constituent parts.
Btw, there's in itself not much wrong with measuring the power draw of the Arduino + BLE module at the same time. If you use the same Arduino for the BLE comms. as for the power measurement, you of course have a situation where the measurement influences itself, but this influence will be quite small and I wouldn't feel too bad about ignoring that effect.
Finally you could of course guestimate things a bit. In either solution you have a BLE module at work - either integrated into the platform (ESP), or separate as a module, but the power draw of that solution will likely be fairly similar. At least within an order of magnitude. As the commanding microcontroller, you have on the one hand a 16 MHz Atmega328 that draws something like 20mA or thereabouts if memory serves, and on the other hand an 80 MHz or so ESP processor that is likely to draw significantly more power. So eyeballing things a bit, I'd say the Arduino + BLE module should be able to do things more efficiently in terms of Joules consumed.
Of course, the microcontroller + communications module are only part of a larger system, and the rest of that system can very easily have a far bigger impact on your power budget. An offhanded choice in how you power the whole thing might just swamp out any advantage you thought you had by picking a more efficient processing or communications platform, and a failure to employ power saving strategies in software could make your solution consume precious power 24/7 with the actual BLE communications periods only consuming a fraction of the total power.
So maybe take one step back and ask yourself first if you're focusing on the right part of the system.
I am far from being an expert, so I'll ask a few questions about what you wrote:
Sample speed of what exactly? The measurement? I make a current measurement every 1 ms.
Could you elaborate a bit? Do you mean adding the measurements and taking an average?
Can you explain to me how to measure the Arduino's consumption separately? Do I have to remove the BLE module from the circuit when doing so? And if I succeed in measuring the Arduino's consumption separately, do I then have to add it to the measured consumption value of the module to have a total consumption value?
Or do I have to use two current sensors; one for the Arduino and the other for the module and measure the two at the same time?
And here's my code btw:
#include <SoftwareSerial.h>
SoftwareSerial ble(2, 3); // RX, TX
/*-----------------------------------------------------------
ACS712 DC Current Demonstration
acs712-dc-demo.ino
Read current using ACS712 Hall Effect sensor
DroneBot Workshop 2021
https://dronebotworkshop.com
*/
// Variables for Measured Voltage and Calculated Current
double Vout = 0;
double Current = 0;
// Constants for Scale Factor
// Use one that matches your version of ACS712
//const double scale_factor = 0.185; // 5A
const double scale_factor = 0.1; // 20A
//const double scale_factor = 0.066; // 30A
// Constants for A/D converter resolution
// Arduino has 10-bit ADC, so 1024 possible values
// Reference voltage is 5V if not using AREF external reference
// Zero point is half of Reference Voltage
const double vRef = 5.00;
const double resConvert = 1024;
double resADC = vRef/resConvert;
double zeroPoint = vRef/2;
/*-----------------------------------------------------------
*/
void setup() {
// Open serial port
Serial.begin(9600);
// begin bluetooth serial port communication
ble.begin(9600);
}
// Now for the loop
void loop() {
ble.write("Hey!");
// Vout is read 1000 Times for precision
for(int i = 0; i < 1000; i++) {
Vout = (Vout + (resADC * analogRead(A0)));
delay(1);
}
// Get Vout in mv
Vout = Vout /1000;
// Convert Vout into Current using Scale Factor
Current = (Vout - zeroPoint)/ scale_factor;
// Print Vout and Current to two Current = ");
Serial.print("Vout = ");
Serial.print(Vout,2);
Serial.print(" Volts");
Serial.print("\t Current = ");
Serial.print(Current,5);
Serial.println(" Amps");
delay(500);
}
Code remark: Shouldn't I make my delay equal to 1000 ms because of this?:
// Vout is read 1000 Times for precision
for(int i = 0; i < 1000; i++) {
Vout = (Vout + (resADC * analogRead(A0)));
delay(1);
}
// Get Vout in mv
Vout = Vout /1000;
So I make a measurement every 1 ms, until 1000 measurements are reached after 1 second. Then I divide by 1000 to get an average value. So, I get 1 average value every second, but a value is printed in the serial monitor every 500 ms; I don't think this makes sense. I think it makes more sense to have a delay of 1000 ms. Do you agree?
Which is pretty horrible if you're measuring a burst system. However, if sufficient power supply filtering (capacity) is present, you'll probably get away with murder.
Yeah, but see above; you're not sampling at 1kHz (1ms). You're effectively sampling at 1Hz. I think that's overly long even with sufficient PSU filtering; I'd go for something like 100Hz or so (10ms per sample).
You also don't need 1000 samples to get one reading. Something like 10 should be enough. If you see too much variation on the signal, you have other problems (e.g. poor sensor implementation, noise issues/poor cabling etc.). Start by plotting raw samples in real time using the Serial plotter in the IDE, this gives you a feeling for the nature of your signal.
Hook up its V+ through the ACS712 sensor; simple. It'll make the Arduino measure its own consumption as it were.
Yes.
No.
You're essentially comparing (I assume...) the power consumption of one platform doing a particular task with another platform doing the same task. The task is probably a BLE communication session, e.g. sending a packet of sensor data over BLE. So what you really want to know is how much energy it takes to perform that task. Having average current consumption would be a very coarse approximation only; my suggestion is to monitor the power consumption at specific (preferably many) time intervals and also record how much time it takes to perform the task you want to monitor and then multiply both parameters. This will yield something like "a BLE communication session takes 50ms and consumes 20mJ on an Arduino and it takes 40ms and consumes 23mJ on an ESP". This will give you the necessary information for stuff like battery management, which I suspect is what you're heading towards.
So you're not comparing the power consumption of one device with another?
Doesn't really matter; the same measurement principle applies, since power usage won't be stable (communication bursts --> power consumption peaks).
I think it would help to discuss the background of your question a bit - i.e. why do you want to measure power consumption (and of what exactly...) and also the rest of the system the communication 'thingy' is part of so we can see if you're actually asking the right question at this point.
(Source: Power consumption explained)
This is a somewhat typical wireless communication session. Notice how power consumption is anything but stable. Like I said, actual current levels flowing to/from the module depend on capacitive filtering (smoothing out), which makes the situation a little less challenging to measure, but even then you'd need to somewhat accurately measure the total duration of the process in order to get anything remotely useful from it.
You might want to read that link above BTW; honestly I didn't, but it seems to say more or less exactly what I did - but this one is from the experts at Nordic Semiconductor who actually deal with this professionally.
I have made the same circuit of scenario 1 and tried to implement your advice on my code:
void loop() {
ble.write("Hey!");
// Vout is read 10 Times for precision
for(int i = 0; i < 10; i++) {
Vout = (Vout + (resADC * analogRead(A0)));
delay(1);
}
// Get Vout in mv
Vout = Vout /10;
// Convert Vout into Current using Scale Factor
Current = (Vout - zeroPoint)/ scale_factor;
// Print Vout and Current to two Current = ");
Serial.print("Vout = ");
Serial.print(Vout,2);
Serial.print(" Volts");
Serial.print("\t Current = ");
Serial.print(Current,5);
Serial.println(" Amps");
delay(100);
}
Do you mean pin "5V" of the Arduino when you say "V+"? And where do I have to connect it on the ACS712? I am hesitating between "Wire in" and "Vcc":
If I connect 5V of the Arduino with "Wire in" the "Vcc" pin of the sensor will be left unused and vice versa; if I connect 5V with "Vcc", the "Wire in" pin will be left unused.
Ok, I understand that I don't have to take an average and that I have to measure the consumption of one session. But do you agree that in the code it is the average that is measured? From the original code:
// Vout is read 1000 Times for precision
for(int i = 0; i < 1000; i++) {
Vout = (Vout + (resADC * analogRead(A0)));
delay(1);
}
// Get Vout in mv
Vout = Vout /1000;
I am not asking this because it applies to my case, but just to be sure I understand the code.
I am indeed comparing the power consumption of one device with another. I was just saying that the tutorial didn't fully apply to my case. When I first saw the title of the tutorial "Measuring current WITH Arduino", I asked myself if this really applied to my case, because here it seems like the Arduino is not part of the system and is just used to measure the current of a separate system, whereas in my case I needed to measure the current while the Arduino being part of the system. So, I had this confusion and you answered my question; that indeed, only the current of the BLE module was measured and not of the Arduino.
I have to build a drone with sensors connected to it, measuring height, speed, acceleration, angular speed etc. This data has to be sent to my pc (or smartphone; I only found tutorials about sending data to a smartphone, so I am using my smartphone for the moment). For every aspect I have to present all the possibilities from which I have to make a choice, and give strong arguments for why I made this particular choice. In this case I had to choose between sending data to my pc (or smartphone) via wifi, zigbee, bluetooth or BLE. I have chosen BLE; now I have to choose between different ways of using BLE (like I said: Arduino Uno + HM-10 or ESP32) and give arguments on many aspects, one of which is power consumption.
I don't know how to do this. Is there any tutorial you would recommend me? Or is it possible for you to explain it to me in a few lines? Or a few indications to guide me to the right direction?
I am bombarding you with questions, I hope you don't mind
So your math is off
Always apply common sense. At 2A, the sensor would be burning 10W. Do you see smoke? No? Then the measurement is probably not accurate.
(Which it will never be given the inherent accuracy problems discussed earlier, but let's leave those for a minute).
Sorry, I mean you need to connect the Arduino to an external +5V source and run that through the ACS712. You'll have to devise a way to store measurement data so you can retrieve them later because if you connect the Arduino to USB it will be powered through USB.
Easier would be to take a second Arduino so you can test one while using the other one as a serial monitor. They're cheap anyway, aren't they?
5V from external power supply to 'Wire In' AND to sensor VCC. Then from 'Wire Out' to 5V on Arduino board.
Yes. And I think that doesn't give very accurate information.
Then I'd just rely on information from the datasheets and some smart assumptions. Otherwise you'll have to accurately measure BLE, Zigbee, WiFi etc. etc. which is going to consume a lot of time while your project is far more expansive than just this aspect...
High school maths and logical thinking.
Start communication session.
Start power measurement
Measure power every 10ms or so. Store results.
End communication session.
Calculate power consumption for every 10ms bracket you've measured.
Add up results of all the brackets.
10ms is probably too big of a bracket because a communications session will be shorter and perhaps have a more intermittent/chaotic power consumption (it isn't stable for 10ms). Hence my earlier questions about sampling speed. You might have to sample 1ms brackets, or even 100us brackets to get good accuracy. You'll have to experiment.
Tutorials are often a very good place to start, but nearly always depart from an overly simplistic use case. As the people from Nordic also said: the devil is in the details. Nevertheless, a tutorial can help you get the basics down; you're getting there. From there onwards it's a matter of further decorating the Christmas tree and make it more sophisticated/complex.
But first ask yourself if a real-world measurement really adds enough on top of a theoretical approximation using datasheets. Personally I would just do that and call it a day. Good chance it's actually more accurate than an overly simplified real world measurement anyway.