Skip to content

Commit

Permalink
Add readVcc() function, update README.
Browse files Browse the repository at this point in the history
  • Loading branch information
JChristensen committed Aug 16, 2018
1 parent d761752 commit 7862b4c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 30 deletions.
36 changes: 31 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
```
27 changes: 8 additions & 19 deletions examples/gsCurrentSensor/classes.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <CurrentTransformer.h> // https://github.com/JChristensen/CurrentTransformer
#include <LiquidTWI.h> //http://forums.adafruit.com/viewtopic.php?t=21586
#include <CurrentTransformer.h> // https://github.com/JChristensen/CurrentTransformer
#include <LiquidTWI.h> // https://forums.adafruit.com/viewtopic.php?t=21586

CT_Sensor ct0(A0, 1000, 200);
LiquidTWI lcd(0); //i2c address 0 (0x20)
Expand All @@ -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
Expand All @@ -29,9 +28,14 @@ CurrentSensor::CurrentSensor(uint32_t threshold) : maThreshold(threshold)

void CurrentSensor::begin()
{
CT_Control::begin(static_cast<float>(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
Expand Down Expand Up @@ -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)
}

7 changes: 4 additions & 3 deletions examples/gsCurrentSensor/gsCurrentSensor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=CurrentTransformer
version=2.0.0
version=2.1.0
author=Jack Christensen <[email protected]>
maintainer=Jack Christensen <[email protected]>
sentence=Arduino Library for measuring current in 50/60Hz circuits using current transformers.
Expand Down
16 changes: 16 additions & 0 deletions src/CurrentTransformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<float>(mv) / 1000.0;
}

// adc conversion complete, pass the value back to the main code
ISR(ADC_vect)
{
Expand Down
5 changes: 3 additions & 2 deletions src/CurrentTransformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@ 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
static const uint16_t ADC_MAX; // maximum adc reading
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

0 comments on commit 7862b4c

Please sign in to comment.