-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit fda62c0
Showing
10 changed files
with
974 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# A GitHub Manifesto | ||
### Notes on contributing to my repositories | ||
Jack Christensen | ||
Jan 2018 | ||
|
||
Surely Git and GitHub are wonderful tools. They make coding and collaboration so much easier. I'm equally impressed with the open source movement, and with the Arduino ecosystem in particular. | ||
|
||
I'm just one guy, mostly a hobbyist. Posting my projects to GitHub is my way of giving back a little to the community. It's very gratifying that some of my code has received a modicum of popularity. | ||
|
||
Like many things, this has been somewhat of a double-edged sword. Especially since I tend to be a pretty busy guy with many varied interests. | ||
|
||
First, I am always interested in bug reports. Please raise an issue in the appropriate repository and please please please include a good, concise description of the issue and a Short, Self Contained, Correct (Compilable), Example (see [sscce.org](http://www.sscce.org/)). I will need to be able to reproduce the issue, with minimal hardware, and without installing a dozen other libraries. I work exclusively with the AVR architecture so most times I will not be able to reproduce issues on other platforms. (There have been one or two occasions where relatively simple changes have been made to accommodate another platform; I am not necessarily averse to these.) | ||
|
||
Second, bug reports should always be for problems with *my* code. I will not use GitHub to help you with *your* code, even if you happen to be using one of my libraries. Please use the [Arduino forum](https://forum.arduino.cc/) or other such venue instead. | ||
|
||
Finally, pull requests can be problematic, especially if they represent enhancements rather than fixes. I seldom intend my code to be all things to all people. This is mostly a hobby activity and I have very limited bandwidth. Reviewing and managing PRs requires time that I do not often have. Sometimes a PR will take a library in a direction that I'm not interested in. Sometimes a PR will be counter to my original design intent. No doubt the author of a PR thinks that their new feature is the best thing since canned beer, but if I don't happen to share that opinion, then I'll decline it. OTOH, I am certainly capable of making stupid mistakes and missing absolutely fundamental things, and I do appreciate it when these are pointed out. | ||
|
||
All this to say, that if I do decline a request, please do not take it personally. Feel free to consider it my problem, not yours. At the end of the day, it's my code, and I reserve the right to decline issues or PRs for any reason, or for no reason at all. But here is the beauty of open source. You can always fork the repository and have your way with it. |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Arduino CurrentTransformer Library | ||
https://github.com/JChristensen/CurrentTransformer | ||
README file | ||
|
||
## License | ||
Arduino CurrentTransformer Library Copyright (C) 2018 Jack Christensen GNU GPL v3.0 | ||
|
||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0 as published by the Free Software Foundation. | ||
|
||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
|
||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/gpl.html> | ||
|
||
## Introduction | ||
The CurrentTransformer library measures RMS current values in a 50/60Hz AC circuit using current transformers. Each call to `read()` causes the analog-to-digital converter (ADC) to measure a single AC cycle. The data gathered is processed using the [standard RMS calculation](https://en.wikipedia.org/wiki/Root_mean_square#Definition) and the result in amperes is returned to the caller. | ||
|
||
Since each call to `read()` measures only a single cycle, it may be desirable, depending on the application and the nature of the electrical load, to make several calls, perhaps averaging the results, removing transients, etc. Each call to `read()` only takes about as long as one AC cycle, so there is not a lot of overhead or delay in taking several measurements. | ||
|
||
Because measuring AC causes the current transformer to output positive and negative currents, a DC bias must be applied to ensure that below-ground voltages are not applied to the microcontroller's ADC input. It is also necessary to ensure that peak voltages do not exceed the microcontroller's supply voltage (Vcc). Do the math to ensure that your circuit operates within safe limits; also see the example below. | ||
|
||
This library is specific to the AVR microcontroller architecture and will not work on others. Timer/Counter1 is used to trigger the ADC conversions and so is not available for other purposes. | ||
|
||
## Example Design Calculations | ||
|
||
The TA17L-03 current transformer is rated at 10A maximum and has a 1000:1 turns ratio. A 200Ω burden resistor is recommended. A 10A RMS current in the primary will generate a 10mA current in the secondary and therefore 2V across the burden resistor. However the peak voltage will then be √2 * 2V = ±2.8V (assuming a sine wave) which exceeds the 2.5V DC bias provided by the circuit below. Therefore the measured current should be limited to about 8.5A RMS (giving ±2.4V P-P) or perhaps a smaller burden resistor could be used if larger currents need to be measured. | ||
|
||
## Typical Circuit | ||
|
||
## Enumeration | ||
### ctFreq_t | ||
##### Description | ||
Operating frequency for the current transformer. | ||
##### Values | ||
- CT_FREQ_50HZ | ||
- CT_FREQ_60HZ | ||
|
||
## Constructor | ||
|
||
### CurrentTransformer(uint8_t channel, float ratio, float burden, float vcc, ctFreq_t freq) | ||
##### Description | ||
The constructor defines a CurrentTransformer object. | ||
##### Syntax | ||
`CurrentTransformer(channel, ratio, burden, vcc, freq);` | ||
##### Required parameters | ||
**channel:** ADC channel number that the current transformer is connected to. (Arduino pin numbers can also be used, i.e. A0-A5). *(uint8_t)* | ||
**ratio:** Secondary:Primary turns ratio for the current transformer. *(float)* | ||
**burden:** Current transformer burden resistor value in ohms. *(float)* | ||
##### Optional parameters | ||
**vcc:** Microcontroller supply voltage. For best accuracy, measure the actual microcontroller supply voltage and provide it using this parameter. Defaults to 5.0V if not given. *(float)* | ||
**freq:** AC line frequency, either CT_FREQ_50HZ or CT_FREQ_60HZ. Defaults to CT_FREQ_60HZ if not given. *(ctFreq_t)* | ||
##### Example | ||
```c++ | ||
CurrentTransformer myCT(0, 1000, 200, 5.08, CT_FREQ_50HZ); | ||
``` | ||
## Library Functions | ||
### void begin() | ||
##### Description | ||
Initializes the AVR timer and ADC. If more than one CurrentTransformer object is defined, `begin()` only needs to be called for one of the objects, although calling it on more than one object will not cause an issue. | ||
##### Syntax | ||
`myCT.begin();` | ||
##### Parameters | ||
None. | ||
##### Returns | ||
None. | ||
##### Example | ||
```c++ | ||
myCT.begin(); | ||
``` | ||
### float read() | ||
##### Description | ||
Measures the RMS current value for one AC cycle and returns the value in amperes. | ||
##### Syntax | ||
`myCT.read();` | ||
##### Parameters | ||
None. | ||
##### Returns | ||
RMS current value in amperes *(float)* | ||
##### Example | ||
```c++ | ||
float rmsCurrent; | ||
rmsCurrent = myCT.read(); | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Arduino Current Transformer Library | ||
// https://github.com/JChristensen/CurrentTransformer | ||
// Copyright (C) 2018 by Jack Christensen and licensed under | ||
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html | ||
// | ||
// Example sketch to read two current transformers every five seconds | ||
// and print the measurements to Serial. | ||
// Tested with TA17L-03 current transformers (10A max), Arduino Uno, | ||
// Arduino v1.8.5. | ||
|
||
#include <CurrentTransformer.h> // https://github.com/JChristensen/CurrentTransformer | ||
#include <Streaming.h> // http://arduiniana.org/libraries/streaming/ | ||
|
||
const float ctRatio(1000); // current transformer winding ratio | ||
const float rBurden(200); // current transformer burden resistor value | ||
const float vcc(5.120); // adjust to actual value for best accuracy | ||
const uint32_t MS_BETWEEN_SAMPLES(5000); // milliseconds | ||
const int32_t BAUD_RATE(115200); | ||
|
||
CurrentTransformer ct0(A0, ctRatio, rBurden, vcc); | ||
CurrentTransformer ct1(A1, ctRatio, rBurden, vcc); | ||
|
||
void setup() | ||
{ | ||
delay(1000); | ||
Serial.begin(BAUD_RATE); | ||
ct0.begin(); | ||
} | ||
|
||
void loop() | ||
{ | ||
uint32_t msStart = millis(); | ||
float i0 = ct0.read(); | ||
float i1 = ct1.read(); | ||
Serial << millis() << F(" ") << _FLOAT(i0, 3) << F(" A ") << _FLOAT(i1, 3) << F(" A\n"); | ||
while (millis() - msStart < MS_BETWEEN_SAMPLES); // wait to start next measurement | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Arduino Current Transformer Library | ||
// https://github.com/JChristensen/CurrentTransformer | ||
// Copyright (C) 2018 by Jack Christensen and licensed under | ||
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html | ||
// | ||
// Example sketch to read a current transformer every five seconds | ||
// and print the measurement to Serial. | ||
// Tested with TA17L-03 current transformer (10A max), Arduino Uno, | ||
// Arduino v1.8.5. | ||
|
||
#include <CurrentTransformer.h> // https://github.com/JChristensen/CurrentTransformer | ||
#include <Streaming.h> // http://arduiniana.org/libraries/streaming/ | ||
|
||
const uint8_t ctChannel(0); // adc channel | ||
const float ctRatio(1000); // current transformer winding ratio | ||
const float rBurden(200); // current transformer burden resistor value | ||
const float vcc(5.120); // adjust to actual value for best accuracy | ||
const uint32_t MS_BETWEEN_SAMPLES(5000); // milliseconds | ||
const int32_t BAUD_RATE(115200); | ||
|
||
CurrentTransformer ct0(ctChannel, ctRatio, rBurden, vcc); | ||
|
||
void setup() | ||
{ | ||
delay(1000); | ||
Serial.begin(BAUD_RATE); | ||
ct0.begin(); | ||
} | ||
|
||
void loop() | ||
{ | ||
uint32_t msStart = millis(); | ||
float i0 = ct0.read(); | ||
Serial << millis() << ' ' << _FLOAT(i0, 3) << F("A\n"); | ||
while (millis() - msStart < MS_BETWEEN_SAMPLES); // wait to start next measurement | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CurrentTransformer KEYWORD1 | ||
begin KEYWORD2 | ||
read KEYWORD2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
name=CurrentTransformer | ||
version=1.0.0 | ||
author=Jack Christensen <[email protected]> | ||
maintainer=Jack Christensen <[email protected]> | ||
sentence=Arduino Library for measuring current in 50/60Hz circuits using current transformers. | ||
paragraph=Each call to read() returns the RMS current in amperes measured for a single AC cycle. | ||
category=Sensors | ||
url=https://github.com/JChristensen/CurrentTransformer | ||
architectures=avr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Arduino Current Transformer Library | ||
// https://github.com/JChristensen/CurrentTransformer | ||
// Copyright (C) 2018 by Jack Christensen and licensed under | ||
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html | ||
|
||
#include <CurrentTransformer.h> | ||
|
||
CurrentTransformer::CurrentTransformer(uint8_t adcChannel, float turnsRatio, | ||
float rBurden, float vcc, ctFreq_t freq) | ||
: m_ratio(turnsRatio), m_rBurden(rBurden), m_vcc(vcc) | ||
{ | ||
if (adcChannel >= 14) adcChannel -= 14; // if user passed A0-A5, adjust accordingly | ||
m_channel = adcChannel & 0x07; // ruthlessly coerce to an acceptable value | ||
tcOCR1 = (freq == CT_FREQ_50HZ) ? 4922 : 4102; | ||
} | ||
|
||
volatile bool CurrentTransformer::adcBusy; | ||
volatile int CurrentTransformer::adcVal; | ||
const int CurrentTransformer::sampleSize(65); // number of samples to cover one cycle | ||
|
||
void CurrentTransformer::begin() | ||
{ | ||
// set up the timer | ||
TCCR1B = 0; // stop the timer | ||
TCCR1A = 0; | ||
TIFR1 = 0xFF; // ensure all interrupt flags are cleared | ||
OCR1A = tcOCR1; // set timer output compare value | ||
OCR1B = tcOCR1; | ||
cli(); | ||
TCNT1 = 0; // clear the timer | ||
TIMSK1 = _BV(OCIE1B); // enable timer interrupts | ||
sei(); | ||
TCCR1B = _BV(WGM12) | _BV(CS10); // start the timer, ctc mode, prescaler divide by 1 | ||
|
||
// set up the adc | ||
ADMUX = _BV(REFS0) | m_channel; // set channel, and AVcc as reference | ||
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE); // enable ADC, auto trigger, interrupt when conversion complete | ||
ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // ADC clock prescaler: divide by 128 (for 125kHz) | ||
ADCSRB = _BV(ADTS2) | _BV(ADTS0); // trigger ADC on Timer/Counter1 Compare Match B | ||
} | ||
|
||
float CurrentTransformer::read() | ||
{ | ||
uint8_t n(0); // sample count | ||
int32_t sumsq(0); // sum of squares | ||
while (adcBusy); // if a conversion is in progress, wait for it to complete | ||
ADMUX = _BV(REFS0) | m_channel; // set channel, and AVcc as reference | ||
|
||
do { | ||
while (!adcBusy); // wait for next conversion to start | ||
while (adcBusy); // wait for conversion to complete | ||
cli(); | ||
int32_t v = adcVal; // get the reading, promote to 32 bit | ||
sei(); | ||
// accumulate the sum of squares, | ||
// subtract 512 (half the adc range) to remove dc component | ||
sumsq += (v - 512) * (v - 512); | ||
} while (++n < sampleSize); | ||
|
||
// calculate rms voltage and current | ||
float Vrms = m_vcc * sqrt(static_cast<float>(sumsq) / static_cast<float>(sampleSize - 1)) / 1024; | ||
return m_ratio * Vrms / m_rBurden; | ||
} | ||
|
||
// adc conversion complete, pass the value back to the main code | ||
ISR(ADC_vect) | ||
{ | ||
CurrentTransformer::adcBusy = false; | ||
CurrentTransformer::adcVal = ADC; | ||
} | ||
|
||
// adc starts conversion when the timer interrupt fires | ||
ISR(TIMER1_COMPB_vect) | ||
{ | ||
CurrentTransformer::adcBusy = true; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Arduino Current Transformer Library | ||
// https://github.com/JChristensen/CurrentTransformer | ||
// Copyright (C) 2018 by Jack Christensen and licensed under | ||
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html | ||
|
||
#ifndef CURRENT_TRANSFORMER_H_INCLUDED | ||
#define CURRENT_TRANSFORMER_H_INCLUDED | ||
#include <Arduino.h> | ||
|
||
// Line frequencies | ||
enum ctFreq_t {CT_FREQ_50HZ, CT_FREQ_60HZ}; | ||
|
||
class CurrentTransformer | ||
{ | ||
public: | ||
CurrentTransformer(uint8_t adcChannel, float turnsRatio, | ||
float rBurden, float vcc=5.0, ctFreq_t freq=CT_FREQ_60HZ); | ||
void begin(); // initializations | ||
float read(); // read the rms value of one cycle | ||
static volatile bool adcBusy; // adc busy flag | ||
static volatile int adcVal; // value returned from adc | ||
static const int sampleSize; // number of samples to cover one cycle | ||
|
||
private: | ||
uint8_t m_channel; // adc channel | ||
float m_ratio; // current transformer turns ratio | ||
float m_rBurden; // current transformer burden resistor value, ohms | ||
float m_vcc; // mcu supply voltage | ||
uint16_t tcOCR1; // compare value for timer | ||
}; | ||
|
||
#endif | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.