From 7862b4ccebb8bd346b30e4a60a0116d899158683 Mon Sep 17 00:00:00 2001 From: JChristensen Date: Thu, 16 Aug 2018 17:50:33 -0400 Subject: [PATCH] Add readVcc() function, update README. --- README.md | 36 +++++++++++++++++--- examples/gsCurrentSensor/classes.h | 27 +++++---------- examples/gsCurrentSensor/gsCurrentSensor.ino | 7 ++-- library.properties | 2 +- src/CurrentTransformer.cpp | 16 +++++++++ src/CurrentTransformer.h | 5 +-- 6 files changed, 63 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 9b70cc0..464dc92 100644 --- a/README.md +++ b/README.md @@ -40,17 +40,28 @@ Operating frequency for the current transformer. ## Constructors ### CT_Sensor(uint8_t channel, float ratio, float burden) -##### Description -Defines a CT_Sensor object. One or more CT_Sensor objects can be defined as needed. +### CT_Sensor(uint8_t channel, float amps, float volts) +##### Description +Defines a CT_Sensor object. One or more CT_Sensor objects can be defined as needed. +The first form is for current transformers with a user-supplied burden resistor. In this case, the turns ratio and the burden resistor value are given. +The second form is for current transformers with a built-in burden resistor. These are often specified as the output voltage corresponding to the maximum input current, e.g. 20A/1V. ##### Syntax -`CT_Sensor myCT(channel, ratio, burden);` +```c++ +CT_Sensor myCT(channel, ratio, burden); +/* or */ +CT_Sensor myCT(channel, amps, volts); +``` ##### Parameters **channel:** ADC channel number that the current transformer is connected to. (Arduino pin numbers can also be used, e.g. A0-A5). *(uint8_t)* **ratio:** Secondary-to-primary turns ratio for the current transformer. *(float)* -**burden:** Current transformer burden resistor value in ohms. *(float)* +**burden:** Current transformer burden resistor value in ohms. *(float)* +**amps:** Maximum rated current for the current transformer. *(float)* +**volts:** Voltage output corresponding to the maximum current input. *(float)* ##### Example ```c++ -CT_Sensor mySensor(0, 1000, 200); +CT_Sensor mySensor(0, 1000, 200); // 1000:1 turns ratio, 200Ω burden resistor +/* or */ +CT_Sensor mySensor(0, 20, 1); // 1 volt output at 20 amps (built-in burden resistor) ``` ### CT_Control(ctFreq_t freq) @@ -115,3 +126,18 @@ myCtrl.read(&mySensor); float rmsCurrent = myCT.read(); ``` +### float CT_Control::readVcc() +##### Description +Reads the value of the microcontroller's supply voltage and returns it in volts. Call this function only before calling `begin()`, since `begin()` configures the ADC for continuous timer-driven readings. This function is useful for accurately determining the Vcc value to be passed to the `begin()` function. +##### Syntax +`myCtrl.readVcc();` +##### Parameters +None. +##### Returns +Supply voltage in volts *(float)* +##### Example +```c++ +CT_Control myCtrl(CT_FREQ_50HZ); +float vcc = myCtrl.readVcc(); +myCtrl.begin(vcc); +``` \ No newline at end of file diff --git a/examples/gsCurrentSensor/classes.h b/examples/gsCurrentSensor/classes.h index a8bb720..ddf2392 100644 --- a/examples/gsCurrentSensor/classes.h +++ b/examples/gsCurrentSensor/classes.h @@ -1,5 +1,5 @@ -#include // https://github.com/JChristensen/CurrentTransformer -#include //http://forums.adafruit.com/viewtopic.php?t=21586 +#include // https://github.com/JChristensen/CurrentTransformer +#include // https://forums.adafruit.com/viewtopic.php?t=21586 CT_Sensor ct0(A0, 1000, 200); LiquidTWI lcd(0); //i2c address 0 (0x20) @@ -11,7 +11,6 @@ class CurrentSensor : public CT_Control void begin(); float sample(); void clearSampleData(); - int readVcc(); int nSample; // number of times CT was read int nRunning; // number of times current was >= threshold value @@ -29,9 +28,14 @@ CurrentSensor::CurrentSensor(uint32_t threshold) : maThreshold(threshold) void CurrentSensor::begin() { - CT_Control::begin(static_cast(readVcc()) / 1000.0); + float vcc = readVcc(); + CT_Control::begin(vcc); lcd.begin(16, 2); lcd.clear(); + lcd.setCursor(0, 0); + lcd << F("Vcc = ") << _FLOAT(vcc, 3); + delay(1000); + lcd.clear(); } // read the ct and collect sample data, display on lcd @@ -61,18 +65,3 @@ void CurrentSensor::clearSampleData() maMax = 0; maMin = 999999; } - -// read 1.1V reference against AVcc -// from http://code.google.com/p/tinkerit/wiki/SecretVoltmeter -int CurrentSensor::readVcc() -{ - ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); - delay(5); // Vref settling time - ADCSRA |= _BV(ADSC); // start conversion - loop_until_bit_is_clear(ADCSRA, ADSC); // wait for it to complete - delay(5); - ADCSRA |= _BV(ADSC); // start conversion - loop_until_bit_is_clear(ADCSRA, ADSC); // wait for it to complete - return 1125300L / ADC; // calculate AVcc in mV (1.1 * 1000 * 1023) -} - diff --git a/examples/gsCurrentSensor/gsCurrentSensor.ino b/examples/gsCurrentSensor/gsCurrentSensor.ino index 09c4857..d355189 100644 --- a/examples/gsCurrentSensor/gsCurrentSensor.ino +++ b/examples/gsCurrentSensor/gsCurrentSensor.ino @@ -29,7 +29,7 @@ const time_t SYNC_RETRY_INTERVAL(5*60); // time sync retry interval, sec //object instantiations gsXBee xb; // the XBee -CurrentSensor cs(100); // current transformer +CurrentSensor cs(100); // current transformer, 100mA threshold //time, time zone, etc. uint32_t ms; // current time from millis() @@ -186,7 +186,8 @@ void xmit(xbeeReadStatus_t xbStatus) payloadInteger(n, cs.nSample); payloadInteger(r, cs.nRunning); payloadInteger(t, cs.maSum); - payloadInteger(m, cs.maMin); + // if no current observed, send 0 for the min instead of 999999 + payloadInteger(m, (cs.maMax == 0 ? 0 : cs.maMin)); payloadInteger(x, cs.maMax); xb.destAddr = coordinator; xb.sendData(payload); @@ -219,7 +220,7 @@ void xmit(xbeeReadStatus_t xbStatus) // suspect that the time sync request arrives too soon and the // base station reads it as the response to the DB command // used to get last hop RSS. was seeing RSS UNEXP RESP messages. - delay(50); + delay(10); timeSyncRetry += SYNC_RETRY_INTERVAL; xb.destAddr = coordinator; xb.requestTimeSync(utc); diff --git a/library.properties b/library.properties index 586ef51..7ce9229 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=CurrentTransformer -version=2.0.0 +version=2.1.0 author=Jack Christensen maintainer=Jack Christensen sentence=Arduino Library for measuring current in 50/60Hz circuits using current transformers. diff --git a/src/CurrentTransformer.cpp b/src/CurrentTransformer.cpp index 85be0c9..883a1fd 100644 --- a/src/CurrentTransformer.cpp +++ b/src/CurrentTransformer.cpp @@ -87,6 +87,22 @@ void CT_Control::read(CT_Sensor *ct0, CT_Sensor *ct1) return; } +// read 1.1V reference against AVcc +// call this function only before calling begin() as the ADC is +// then automatically triggered by the timer. +// returns the value of Vcc in volts. +// from http://code.google.com/p/tinkerit/wiki/SecretVoltmeter +float CT_Control::readVcc() +{ + // set AVcc as reference, 1.1V bandgap reference voltage as input + ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); + delay(5); // Vref settling time + ADCSRA |= _BV(ADSC); // start conversion + loop_until_bit_is_clear(ADCSRA, ADSC); // wait for it to complete + int mv = 1125300L / ADC; // calculate AVcc in mV (1.1 * 1000 * 1023) + return static_cast(mv) / 1000.0; +} + // adc conversion complete, pass the value back to the main code ISR(ADC_vect) { diff --git a/src/CurrentTransformer.h b/src/CurrentTransformer.h index 7d3a84b..b0ac22b 100644 --- a/src/CurrentTransformer.h +++ b/src/CurrentTransformer.h @@ -33,6 +33,7 @@ class CT_Control // read the rms value of one cycle for one or two CTs void read(CT_Sensor *ct0, CT_Sensor *ct1); void read(CT_Sensor *ct0) {read(ct0, ct0);} + float readVcc(); // read Vcc value in millivolts static volatile bool adcBusy; // adc busy flag static volatile int adcVal; // value returned from adc static const uint16_t sampleSize; // number of samples to cover one cycle @@ -40,8 +41,8 @@ class CT_Control static const uint16_t OCR50; // timer output compare register value for 50Hz static const uint16_t OCR60; // timer output compare register value for 60Hz private: - float m_vcc; // mcu supply voltage - uint16_t m_tcOCR1; // compare value for timer + float m_vcc; // mcu supply voltage + uint16_t m_tcOCR1; // compare value for timer }; #endif