Monday, December 10, 2012

Project 1: Home Energy Monitor with Arduino, Part 2/3: SW

In the previous article, a sensor box was developed for Arduino microcontroller board. Its purpose is to measure home energy usage by observing the rate of energy meter's LED blinks (digital meter) or disk revolutions (analog meter). In this article, I discuss writing sensor software for Arduino. We start from the basics: sampling an analog signal and analog-to-digital conversion. Next, simple looping technique is presented for capturing sensor data. Finally, Arduino software is finished by extracting the number of LED blinks per second from digitized signal, and reporting it to PC via serial connection.


LEVEL: Beginner





Motivation


If you have built the sensor box presented in the previous article, I bet you're already anxious to get the system streaming data to a PC and seeing your home energy consumption as a nice graph plotted over time. Or maybe you are here because you've built something else, and now have a data stream that you wish to get from Arduino to PC. In this article, I will go through the process using energy meter setup as an example. It should be trivial to modify the presented software to work with other sensor data sources.

The solution described in this article involves a PC. You might wonder whether a PC is actually needed at all, as Arduino can be expanded with various stackable boards to have PC-like features. That's a fair question, and the answer is that indeed PC is not necessarily needed: you can expand an Arduino with an SD shield to write data to a memory card, or buy an Ethernet shield or even an Arduino with built-in Ethernet to connect directly to the Internet. It is also possible to print from Arduino. While such options exist, PC makes all of these easier to accomplish especially during development phase, when you need to be able to analyze the signal in order to develop algorithms for processing it. Later on, you may want to remove PC from the equation.

In general, the topics covered in this article are good to master if you are interested in using sensors. For example, understanding how an analog signal is sampled and converted to digital form is fundamental for all sensor projects, as almost all sensors are based on an analog signal source but typically use cases are realized using digital signal processing (DSP) methods. Likewise, streaming data via serial connection is a basic skill. But, let's start with the sensor component and sampling theory.


Analog-To-Digital Conversion


The sensor box developed for the energy meter project utilizes an LDR sensor (light-dependent resistor). It is a component that continuously changes its resistance along the amount of light it receives: more light - lower resistance; less light - higher resistance.When connected in series with a preset resistor, the voltage measured over the sensor becomes an analog signal whose amplitude (voltage) is relative to light intensity: more light - lower voltage; less light - higher voltage.

In the sensor box setup, this analog sensor signal is physically wired to one of Arduino's analog input pins. When a software command to read from the said analog input pin is given repeatedly, the analog signal gets sampled and thus becomes converted to a digital signal sample by sample. This process is called analog-to-digital conversion (A/D conversion) and it is performed by a component that is built into Arduino's microcontroller: an analog-to-digital converter (A/D converter).

The process involves two important things to be understood: making the original continuous signal discrete-time by taking samples of it periodically, and discrete-amplitude by giving an integer value from a predefined scale to represent the voltage measured during each (very short) sampling moment.


Making a continuous signal discrete-time by sampling it periodically.
Image: Wikipedia

The rate of readings done per second is generally called the sampling rate of the system. It is an important concept, as explained by Martin H. Weik (1996) in Communications Standard Dictionary (here adopted from Wikipedia):

The sampling rate, sample rate, or sampling frequency Fs defines the number of samples per unit of time (usually seconds) taken from a continuous signal to make a discrete signal. For time-domain signals, the unit for sampling rate is hertz (inverse seconds, 1/s, s−1), sometimes noted as Sa/s (samples per second). The inverse of the sampling frequency is the sampling period or sampling interval, which is the time between samples.



Making a continuous signal discrete-amplitude by quantizing it to predefined levels.
Image: Wikipedia

The number of levels is called the resolution of the system. From Wikipedia:
The resolution of the converter indicates the number of discrete values it can produce over the range of analog values. The values are usually stored electronically in binary form, so the resolution is usually expressed in bits. In consequence, the number of discrete values available, or "levels", is a power of two. For example, an ADC with a resolution of 8 bits can encode an analog input to one in 256 different levels, since 2^8 = 256. The values can represent the ranges from 0 to 255 (i.e. unsigned integer) or from −128 to 127 (i.e. signed integer), depending on the application.

The result of the whole process is a sequence of integer values that represent the original signal, more or less precisely. The precision depends mostly on two things: how short is the time interval between samples, and how high is the number of levels used for describing the whole amplitude range. In other words, the higher the sampling rate and the resolution, the better copy of the original analog signal is created using digital representation. The number of CPU cycles needed for capturing and processing the signal and the amount of memory required to store it are proportional to sampling rate and resolution.

Inevitably, certain level of error will be created in the process due to things like quantization error, clock jitter, and converter non-linearity. Also, part of the original information gets permanently lost: anything that happens in the continuous signal between sample points and quantization levels is simply not present in the discrete signal. Hence, the designer needs to select hardware components and configure the system so that adequate signal quality for the particular use case is reached. However, too high sample rate and resolution only waste memory and CPU cycles during sampling and processing, so one should not go overly broad.


A/D Conversion with Arduino


There are many Arduino models with different specifications, so let's take one as an example: Arduino Diecimila (with ATmega 168 microcontroller) has a theoretical maximum of ~15.000 samples per second - yet in practice the board is reported to handle something like 8.000-10.000 samples per second (source). This is the limit (time-wise) for sampling an analog signal with that board. For comparison: human ear can hear sounds in the range of 20-20.000 Hz. To store this whole range, Compact Disks (CDs) use 44100 Hz sample rate. In studios audio is nowadays recorded at 96 kHz or even 192 kHz.

Said Arduino Diecimila has six 0-5V analog inputs that are sampled with 10-bit precision, giving 2^10=1024 different values (and the range 0-1023). This means that each integer step corresponds roughly 5V/1024=~5mV. This is the limit (amplitude-wise) for sampling an analog signal with that board. Still using sound as an example, CDs use 16 bit resolution, giving the range 0-65536. Professional audio equipment uses 24 bits and production software 32 bits.

Arduino Diecimila has six 10-bit A/D converters.

While Arduino's analog inputs may not be adequate for recording jamming sessions with your garage band, they are actually pretty good for many common sensor use cases. To get back to the energy meter: If you are sampling a blinking LED, in theory you need only 1 bit resolution i.e. need to separate only two different values. Hence, even a digital input could be used with a suitable analog signal. But if you have an analog energy meter with a rotating disk, you must be able to detect fine changes in the signal caused by the reflections of light from the painted and unpainted parts of the edge of the disk. There's still only two states, but separating them now requires a carefully tuned setup.

In practice, a working system is much easier to accomplish with digital signal processing methods than with analog electronics. However, as a precondition, the analog signal needs to be digitized with an accuracy that allows subtle enough changes to be detected later on with digital techniques. This means using high enough sampling rate and resolution during the A/D conversion, as explained previously. I have tested in practice that Arduino's 10 bit A/D converter is indeed good enough for this use case, as well as the available sampling rate. We'll return to these later in the article.


Software for Arduino


In the sensor box article I presented a very simple Arduino program that consists of two C-language functions: setup() and loop(). Setup function is run once when the software starts running and is used for configuring the system. Loop function is run forever (or at least until next reset/shutdown occurs) and contains the actual task that the board should be doing continuously. Now, let's take a closer look at both, and then start improving the code.

void setup() {
  // Configure I/O pins as input/output:
  pinMode(11, OUTPUT); // Yellow LED
  pinMode(12, OUTPUT); // Red LED
  pinMode(A2, INPUT);  // LDR sensor

  // Set default states for output pins:
  digitalWrite(11, LOW);  // Yellow LED off
  digitalWrite(12, HIGH); // Red LED on

  // Start serial communication with a PC:
  Serial.begin(9600);
}


As seen in the code, during the setup phase used I/O pins are first configured to either input or output mode, and in case of output mode the default values are set. This ensures that the board starts from the correct state. Then, serial communication to PC is initialized using the classical (and very slow) baud rate 9600 bps. Pretty simple so far.

void loop() {
  // Read LDR sensor (0-1023 = 0-5V):
  int val = analogRead(A2);

  // Print value to PC:
  Serial.println(val);

  // Notify relevant change with yellow LED:
  if (val < 600)
  {
    digitalWrite(11, HIGH);
  }
  else
  {
    digitalWrite(11, LOW);
  }

  // Wait 100 ms before next read (10 Hz sampling rate):
  delay(100);
}


In the loop function, we read a new sensor value, print it to PC's console by writing it to serial output, set the notification LED on/off based on the latest sensor value, and then wait a while. Sounds reasonable - except that why do we have to wait at the end of the function, as nothing comes after it?

The loop function is actually called over and over again, meaning that after the last line of code is run processing immediately jumps back to the first line and continues from there. In other words, Arduino's microcontroller repeats the loop function as fast as it can. Here the goal is to read a new value from the sensor and send it to PC, but we don't need to do that at the maximum possible speed as the energy meter's LED doesn't blink that fast (and the rotating disk is even slower). So we add a small pause between loop repeats by calling the delay function, and hence limit the speed of the system to a more reasonable rate. But what exactly is an adequate sampling rate? Let's find out.


Optimization 1: Adjusting the Sample Rate


In the code above, we have a delay of 100 milliseconds at the end of the loop. Since the other commands are fairly short to execute and there are not many of them in total, we can say that the sampling period or sampling interval is here defined mainly by the delay set to 100 ms and hence our sampling rate is roughly 1 / 0.100 s = 10 1/s = 10 Hz (hertz).

In practice this means that we get 10 readings per second. Is that enough - or perhaps an overkill? Let's start from the source of the information: the energy meter. A label on the energy meter in my house tells the following "P 10000 imp/kWh", i.e. power P is indicated with 10.000 LED impulses per kWh of energy consumed. Since we need to find out the maximum rate that the LED might blink, we must consider the maximum momentary power consumption in the house.

Here in Finland we usually have a 3-phase 230 V system at real estates, and each of the three phases has typically 35A main fuse. Since power P=U*I i.e. voltage times current, we can conclude that the maximum momentary power consumption per phase is 230V*35A=8050VA. With three separate phases, the total would be 3*8050VA=24150VA. Of course things are not that simple in reality, they never are - but if we say that the maximum momentary power consumption in total is about 24 kilowatts, we have some kind of reasonable estimate for the absolute maximum LED blinking rate that we should be able to capture. For reference, my electricity company tells me that during last winter the highest energy peak per day in my house was 149 kWh, or in average 149 kWh/d / 24h/d = 6.2 kW, which is about 26% of the maximum capacity calculated above. There are momentary peaks high above this level that we should be able to catch, hence the calculated value 24 kW seems reasonable.

A Digital Energy Meter.

If I'd become a really good customer for the electricity company and took the most out of my electricity network, during each hour the energy meter would count 24 kWh and hence make 24 kWh * 10.000 blinks/kWh = 240.000 blinks per hour. Since there are 3600 seconds in an hour, the maximum amount of blinks per second would be 240.000 blinks/h / 3600s/h = 66.67 blinks/s, blinking rate thus being about 67 Hz. This also means that at full speed one cannot catch the blinks by bare eye, as a human can observe only 10-12 blinks per second.

So we have 67 Hz signal, and 10 Hz sampling rate - which is clearly slower. After raising our sampling rate to 67 Hz, we can catch all blinks and everything is OK? Unfortunately, no. According to Nyquist-Shannon sampling theorem (which I won't discuss in a beginner level article) the sampling rate must be at least double the maximum frequency of the sampled signal. The following is by far not a complete representation of the issue, but simple enough for everyone to understand: in order to blink, the LED needs to be ON a short time and then also OFF another short time. If if makes 67 flashes per second and we read our sensor also 67 times per second, depending on the start time we might read it always when it is ON or always when it is OFF - hence our sampled data would not reveal any blinking at all! Clearly the sampling rate needs to be faster than the maximum blinking rate of the LED, so that we can catch both phases. The theorem tells that doubling it is enough, and this time we decide to simply believe it as we're told. Since the maximum frequency in our signal is now determined to be about 67 Hz, according to Nyquist the sampling rate Fs should be at least 2*67Hz=134Hz.


Visualization of Nyquist-Shannon sampling theorem: when sampling frequency is too low,
multiple sine waves of different frequencies match perfectly with captured samples, hence we cannot
determine true signal frequency by looking at the data. Image: Wikipedia.

However, there's one more thing to realize: in real life a LED doesn't turn ON or OFF immediately. When current starts to flow through the component, it takes a short moment to reach the typical light emission level. Likewise, when the current is cut there is a short afterglow. Human eye is too slow to catch these, but Arduino isn't. At blinking rate that fast, this is an issue that needs to be taken into account: the signal from the sensor will not resemble a square wave but is more like a sine wave, since the LED is practically always getting either brighter or dimmer.

Now, if we use a simple threshold for separating LED states (ON/OFF) and set it exactly between the two extremes of the signal, it is in the point where the signal change is fastest. This means two things: if we don't have enough resolution, we might fail to recognize a blink due to quantization error (sample gets quantized to "wrong" side of threshold level), or if our sampling interval does not stay constant (for example because different paths of our program logic take different time to execute), sampling time might deviate just enough for the signal to pass the threshold level before we sample it.

The simplest method to prevent likelihood of missing LED blinks is to raise the sampling rate, so that we can track the analog signal's form more accurately. Let's go for 200 Hz. This way, even if the LED would blink at 50 Hz rate (75% of my house's calculated maximum capacity) we'll still get 4 samples of each LED blink, of which two should occur below the threshold level and another two above it. Thus, we have a pretty good safe margin. This means that sampling period or sampling interval will be 1 / 200 Hz = 0.005 s = 5 ms. Let's fix the code:

  // Wait 5 ms before next read (200 Hz sampling rate):
  delay(5);

After updating the code change to Arduino, I let it sample the energy meter's LED a few seconds, and then copied the printed values from PC's serial console to an Excel sheet to create the plot shown below. From the plot we see that the board has captured about 17 samples from each wave. This means that in 200 samples fits 17/200=11.76 waves. Since one wave corresponds to one LED blink and we have collected 200 samples per second, we can conclude that during the measurement the LED was blinking at about 12 Hz rate. Again, if 67 Hz rate means full 24 kW energy consumption, then during the measurement energy consumption was roughly 12 Hz / 67 Hz * 24 kW =~ 4.3 kW, which is reasonable as it was a cold day and we heat our house primarily with electric energy.

Energy meter's LED measured with an LDR sensor using 200 Hz sampling rate and 10 bit resolution.

Now that we have raised sampling rate from 10 Hz to 200 Hz (20-fold increase), you might wonder whether other stuff in the loop function becomes a bottleneck that prevents sampling at this high speed. Especially, writing stuff to serial port is a bit suspicious... Since sample values seem to be between 800 and 930, each written line consists of three digits and a new line character, in total 4 characters to print. As our serial connection is configured to use the typical 8N1 setting, there will be a start bit, 8 data bits, and a stop bit - in total 10 bits for each character to be sent! Hence, we send 4 * 10 = 40 bits per each sample, resulting to 40 * 200 = 8000 bits/s. In the code we have configured serial port speed to 9600 bps, so we're close but still within the bandwidth limit.

Now, if send 40 bits per sample, at 9600 bps speed it will take 40 bits / 9600 bits/s =~ 0.0042 s or about 4 milliseconds to move the bits from Arduino to PC. But we are already sleeping 5 milliseconds - do these numbers add up to 9 milliseconds? Well, it depends. First, there's a distinction between using microcontroller's hardware serial ports and emulating one with software using ordinary digital I/O pin. Second, proper serial port code is interrupt driven i.e. software should not stay polling when a character has been transmitted. According to this fairly critical yet insightful post, before version 1.0 of Arduino libraries, bad polling technique was in fact used when writing to serial port. So, you should be fine if you're using new enough Arduino IDE, but if you have a problem with this, there are multiple rather simple options:
  • Update to latest Arduino IDE
  • Raise serial port speed
  • Compensate by lowering sleep time

In general: We're essentially trying to do two tasks at the same time (reading samples and sending them to PC). Arduino doesn't have an operating system to share CPU time to multiple tasks, hence the latter task must simply wait until the former one has finished. As said above, proper serial port code uses interrupts instead of polling. Likewise, a good sampling solution uses sensor interrupt or timer interrupt for reading the samples at exactly the wanted rate. Typically, samples are then stored internally into a ring buffer, which is emptied to the serial port by the loop function when the microprocessor is not processing an interrupt. It's not difficult to implement, but has issues to be understood and typically requires some tuning as well. As this is a beginner level article, we'll do with the most basic busy loop. Maybe I'll write another advanced-level post about interrupt-driven sampling with Arduino.


Optimization 2: Adjusting the Threshold


From the image above (the Excel plot from the data capture) one can easily see that signal fluctuates somewhere between 800 and 930. Since the threshold for detecting whether the LED is ON or OFF is currently set to 600, it clearly can't be right. Again, using Excel we can calculate the average (DC level) easily from the capture data: it's 862. Let's use this value as a threshold:


  // Notify relevant change with yellow LED:
  if (val < 862)
  {
    digitalWrite(11, HIGH);
  }
  else
  {
    digitalWrite(11, LOW);
  }


You need to make a similar measurement to find the value that is suitable for you setup.


Optimization 3: Adjusting the Resolution


As said already, Arduino Diecimila's A/D converter has 10-bit precision, thus providing an unsigned value range 0-1023. We can't get more resolution out of it, and we're already sending this raw data stream to PC as-is with the current program code - so what's there to optimize? Well, we can consider if we could do with a little less streaming, as we need to interpret the data somewhere anyway.

  // Read LDR sensor (0-1023 = 0-5V):
  int val = analogRead(A2);

In the code above, the value returned from sensor read command is stored into int data type, which in Arduino Diecimila uses 2 bytes (16 bits) and provides value range -32768...32767. Our 10 bit samples fit in easily - in fact, we have 6 unnecessary bits that are completely wasted! If we intend to stream the data to PC, we could use one bit as a parity bit for error detection later in the system, or even go for error correcting. However, here we connect to PC with a short USB cable and should not expect much errors to occur. Moreover, in the case of energy meter sensor box, missing 1 LED blink would cause an error of 1/10000 kWh, so this route would clearly be an overkill considering our needs.

While we could use an array of bytes as a storage so that each 10 bit sample would be divided to two pieces (stored in two sequential bytes so that all bits of all bytes get used), we should probably first consider if we could manage with 8-bit resolution. To be specific: a single byte data type could store an unsigned value from range 0-255, so if we satisfy to 25% of the original resolution, we can store the data easily using 1 byte per sample instead of 2 bytes, hence saving 50% of the storage space.

In the case of the energy meter, we can actually go much further than that: why an earth would we use 256 values to tell whether a single LED is on or off? Why, you need only 1 bit for that! Moreover, in the code we already have an algorithm that uses a simple threshold to determine whether the LED is on or off, so instead of storing measured sample values we could simply store the result of this decision. There is even a specific boolean data type for storing on/off kind data. But there's a catch: in most computer systems, a boolean is implemented so that it still consumes a full byte (source). By blindly using boolean, we wouldn't save any space but would still lose the possibility of deciding the threshold level later on the PC side!

To go with this route, we'd better pack 8 boolean values to a single byte by using a byte as a bit field. However, this also means that we're not anymore sending the data to the PC in real time. Instead, we have to first collect 8 samples to fill a byte, and only then transmit the data. Since there are no time stamps of the individual measurements included, the PC cannot know when exactly each of the 8 samples were taken, and simply need to trust that Arduino is sampling at constant, known rate. So we are losing information, or raising the abstraction level of the data stream, depending how you look at it.

Let's dig deeper. In case of the bit field, we'd actually store our conclusions of whether the energy meter's LED was ON or OFF during the moment of sampling - a '1' or a '0', respectively. At maximum blinking rate and optimal sampling rate, the bit field would look like this: 0101 0101, i.e. off, on, off, on... But most of the time, the LED doesn't blink nearly as fast as our maximum detection rate, so the bit fields could look something like this: 0000 0111, 1000 0111 etc. assuming 50% duty cycle. Now, do we really need to send sequential 0's and 1's to tell that the LED is blinking slowly? No.

What we are really interested about, are the blinks of the LED, which happen to consist of these two phases ON and OFF. So if we instead count the blinks already in the Arduino, we save lots and lots of storage space. For example, we could modify the algorithm to increment a counter whenever we conclude that the LED turns on. Another big saving comes when we decide to send this counter value as a number instead of a bit field (remember that a byte can present a range from 0 to 255, but contains only 8 bits as a bit field). This is of course natural now that we have a value instead of a boolean type status.

There's one more thing to decide: how frequently we want to send this data to a PC. In a way, this is another sampling rate of the system - from PC point of view. Basically you can now select any rate you want. One second would provide pretty fast stream and quickly updating plots, so I'd consider that as one reasonable rate for this project. Let's start with that, and lower the rate later when we aren't that anxious in observing the signal anymore. Since we have 200 Hz sampling rate, we simply need to count from 0 to 200, and when we reach 200 we send the data to PC and clear the counters. So, first we add a couple of counters as global variables at the top, and also a variable to store current status of the LED so that we can observe the moment when it turns on/off:

byte blinkCount = 0;   // 0-255
byte sampleCount = 0;  // 0-255
boolean ledON = false; // ON=true, OFF=false

void setup() {
  // Configure I/O pins as input/output:
  pinMode(11, OUTPUT); // Yellow LED
  pinMode(12, OUTPUT); // Red LED
  pinMode(A2, INPUT);  // LDR sensor

  // Set default states for output pins:
  digitalWrite(11, LOW);  // Yellow LED off
  digitalWrite(12, HIGH); // Red LED on

  // Start serial communication with a PC:
  Serial.begin(9600);
}

void loop() {
  // Read LDR sensor (0-1023 = 0-5V):
  int val = analogRead(A2);
  sampleCount++;

  // Notify relevant change with yellow LED:
  if (ledON == false && val < 862)
  { // LED just turned ON.
    digitalWrite(11, HIGH);
    ledON = true;
    blinkCount++;
  }
  else if (ledON == true && val >= 862)
  { // LED just turned OFF.
    digitalWrite(11, LOW);
    ledON = false;
  }
  
  if (sampleCount >= 200)
  {
    // Print value to PC:
    Serial.println(blinkCount);
   
    blinkCount = 0;
    sampleCount = 0; 
  }

  // Wait 5 ms before next read (200 Hz sampling rate):
  delay(5);
}

Now, whenever we read a new sensor value (get a new sample), we increment the sample counter. This is also our simple way to keep time and know when to send blink count to the PC. We store the current LED state, and use it to detect if any new change has occurred i.e. if the LED has just turned ON or OFF. We also relay this to the sensor box's own LED, respectively. And only when the LED turns on, we increment the blink counter. Finally, we compare the sample counter to the set limit to find out if one second has gone since we last updated the blink count to the PC, and if true, send it now and clear the counters.

Before the optimization, we sent 200 samples * 4 bytes = 800 bytes per second to the PC. Now we send 2-3 bytes per second, and could easily limit it further by counting in more samples before we send the counter value. But we have also made some tradeoffs on the way, and moved logic from PC side to Arduino, which now provides more abstract data to the PC. Whether this is reasonable depends on the project. Maybe you want to store the raw data on the PC and do all calculations there, at least in the beginning? Nevertheless, many systems benefit from abstracting the stream as much as possible as near the sensor as possible, in the form of saved bandwidth.

And to be exact: all the way we have been writing the values to the PC by printing them to serial port, meaning that we are actually sending strings i.e. character arrays instead of single integer values. For example, printing value 255 with Serial.println() takes 4 characters: '2', '5', '5', '\n'. We could optimize this by replacing Serial.println() with Serial.write() - but then we couldn't observe the values directly as numbers from the PC's serial console. If serial connection really becomes a bottleneck, then the easiest option is to increase bandwidth i.e. choose a higher baud rate. For example, 115200 bps should be pretty safe to use.


Testing


Compile and update the code from Optimization step 3 to Arduino. Then open Arduino IDE's serial console, and test blink counting feature first by covering the sensor e.g. with your finger multiple times per second. Observe that a count is printed to console once per second and that the printed value is correct.

Then, go to the energy meter to try the system in a real setting. Attach the sensor box to the meter for example using blu tack as in the image below. Find a position where sensor box's yellow LED blinks steadily, at a constant rate. Use for example a laptop PC to connect to Arduino, open Arduino IDE's serial console and observe for a while that the values seem reasonable.

If not, you probably need to adjust the threshold. Put the code used in Optimization step 1 to Arduino and capture a few hundred samples to serial console. Copy values from serial console and paste to Excel. Create a plot to see that the signal form seems right and calculate average with Excle. Use average as a new threshold value, and try again.

Sensor Box attached to energy meter using blu tack. Adjust position so that yellow LED blinks at a constant rate.


Summary


In this article, we've learned the basics of digitizing an analog sensor signal and discussed a few fundamental topics such as sampling rate and bit resolution. Then we applied the theory into practice by improving many aspects of the energy meter project's Arduino software, explaining and analyzing everything while going forward. The software was kept simple on purpose - more advanced topics such as interrupt based sampling belong to another article.

Yet, we still haven't finished the project! The next article will end this trilogy by discussing software from PC side of view. We'll go through logging, plotting (not with Excel!) and sending data to the cloud. Stay tuned!

Final note: This article mostly talks about sampling a blinking LED. What if you have an analog energy meter with a rotating disk? Well, it doesn't really make any major difference. The painted mark at the edge of the rotating disk is your "LED" that "blinks" when the disk rotates. Its "blinking" rate is slower than LED's, hence you probably won't get as precise information of electricity consumption as with a digital energy meter. Also, adjusting the sensor box on top of the meter must be done with care. But otherwise - it's the same thing.

No comments:

Post a Comment