mirror of
https://github.com/thelsing/knx.git
synced 2025-09-28 17:50:25 +02:00
Fix/Update/Add
Add: ResetEnergy function with datetime Update: led Class Fix: many typo, errors
This commit is contained in:
parent
c1d076fbec
commit
7618e82c00
@ -2,6 +2,7 @@
|
|||||||
#include <PZEM004Tv30.h>
|
#include <PZEM004Tv30.h>
|
||||||
#include "wiring_private.h" // pinPeripheral() function
|
#include "wiring_private.h" // pinPeripheral() function
|
||||||
|
|
||||||
|
#include <TimeLib.h>
|
||||||
|
|
||||||
//Sercom Stuff
|
//Sercom Stuff
|
||||||
#define PIN_SERIAL2_RX (34ul) // Pin description number for PIO_SERCOM on D12 (34ul)
|
#define PIN_SERIAL2_RX (34ul) // Pin description number for PIO_SERCOM on D12 (34ul)
|
||||||
@ -19,83 +20,159 @@ void SERCOM1_Handler()
|
|||||||
#define PZEM004_NO_SWSERIAL
|
#define PZEM004_NO_SWSERIAL
|
||||||
#define PZEM_DEFAULT_ADDR 0xF8
|
#define PZEM_DEFAULT_ADDR 0xF8
|
||||||
|
|
||||||
const uint8_t physicalCount = 6; // voltage,current,power_factor,power,energy,frequency
|
|
||||||
|
|
||||||
//knx stuff
|
//knx stuff
|
||||||
#define goReset knx.getGroupObject(1)
|
#define goReset knx.getGroupObject(1)
|
||||||
#define goDateTime knx.getGroupObject(2)
|
#define goDateTime knx.getGroupObject(2)
|
||||||
#define goProgMode knx.getGroupObject(9)
|
#define goProgMode knx.getGroupObject(9)
|
||||||
|
|
||||||
|
// Global Const
|
||||||
|
const uint16_t ets_timePeriod[7] = {0, 1, 5, 15, 1 * 60, 5 * 60, 15 * 60};
|
||||||
const uint8_t ets_startupTimeout[7] = {0, 1, 2, 3, 4, 5, 6};
|
const uint8_t ets_startupTimeout[7] = {0, 1, 2, 3, 4, 5, 6};
|
||||||
const int ets_timePeriod[7] = {0, 1, 5, 15, 1 * 60, 5 * 60, 15 * 60};
|
|
||||||
const uint8_t ets_percentCycle[6] = {0, 5, 10, 15, 20, 30}; //need knxprod update... ?
|
const uint8_t ets_percentCycle[6] = {0, 5, 10, 15, 20, 30}; //need knxprod update... ?
|
||||||
|
|
||||||
int percentCycle = 0; // better to define a global or read knx.paramByte each time... ?
|
const uint8_t ledPin = LED_BUILTIN;// the number of the LED pin
|
||||||
unsigned long timePeriod = 0; // same here,
|
const uint8_t physicalCount = 6; // voltage,current,power_factor,power,energy,frequency
|
||||||
uint8_t resetFlag = 0; // and here...
|
|
||||||
|
// Global Variable
|
||||||
|
uint8_t percentCycle = 0; // better to define a global or read knx.paramByte each time... ?
|
||||||
|
uint32_t timePeriod = 0; // same here,
|
||||||
|
uint8_t resetPeriod = 0; //same here ...
|
||||||
|
uint8_t resetEnergy = 0; // and here... disabled/day/week/month
|
||||||
|
|
||||||
bool progMode = true;
|
bool progMode = true;
|
||||||
|
|
||||||
// Issue on https://github.com/mandulaj/PZEM-004T-v30/issues/43
|
// Issue on https://github.com/mandulaj/PZEM-004T-v30/issues/43
|
||||||
PZEM004Tv30 pzem(Serial2, PZEM_DEFAULT_ADDR);
|
PZEM004Tv30 pzem(Serial2, PZEM_DEFAULT_ADDR);
|
||||||
|
|
||||||
|
|
||||||
struct Physical {
|
struct Physical {
|
||||||
void init(uint8_t GOaddr, Dpt type_dpt){
|
void init(uint8_t GOaddr, Dpt type_dpt){
|
||||||
_GOaddr = GOaddr;
|
_GOaddr = GOaddr;
|
||||||
_dpt = type_dpt;
|
_dpt = type_dpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(float value){
|
void loop(){
|
||||||
unsigned long currentMillis = millis();
|
// unsigned long currentMillis = millis();
|
||||||
|
|
||||||
// Delta Change update as defined in ETS
|
// Delta Change update as defined in ETS
|
||||||
|
int32_t deltaPercent = ( 100 * ( _value - _lastValue ) / _value );
|
||||||
int deltaPercent = ( 100 * ( value - lastValue ) / value );
|
|
||||||
if ( percentCycle != 0 && abs(deltaPercent) >= percentCycle )
|
if ( percentCycle != 0 && abs(deltaPercent) >= percentCycle )
|
||||||
{
|
{
|
||||||
trigger = true;
|
_trigger = true;
|
||||||
|
_lastValue = _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh groupAddress value as defined in ETS since last update
|
// Refresh groupAddress value as defined in ETS since last update
|
||||||
if ( timePeriod != 0 && currentMillis - lastUpdate >= timePeriod )
|
if ( timePeriod != 0 && millis() - _lastMillis >= timePeriod )
|
||||||
{
|
{
|
||||||
trigger = true;
|
_trigger = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateGO but send to bus only if triggered by time or value change percentage
|
// UpdateGO but send to bus only if triggered by time or value change percentage
|
||||||
if (trigger){
|
if (_trigger){
|
||||||
knx.getGroupObject(_GOaddr).value(value, _dpt);
|
knx.getGroupObject(_GOaddr).value(_value, _dpt);
|
||||||
lastUpdate = millis();
|
_lastMillis = millis();
|
||||||
trigger = false;
|
_trigger = false;
|
||||||
}else{
|
}else{
|
||||||
knx.getGroupObject(_GOaddr).valueNoSend(value, _dpt);
|
knx.getGroupObject(_GOaddr).valueNoSend(_value, _dpt);
|
||||||
}
|
}
|
||||||
lastValue = value;
|
}
|
||||||
|
|
||||||
|
void setValue(float value){
|
||||||
|
if (value != _value)
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _GOaddr;
|
|
||||||
Dpt _dpt;
|
Dpt _dpt;
|
||||||
bool trigger = false;
|
float _value = 0;
|
||||||
|
float _lastValue = 0;
|
||||||
|
uint32_t _lastMillis = 0;
|
||||||
|
uint8_t _GOaddr;
|
||||||
|
bool _trigger = false;
|
||||||
|
|
||||||
// bool isUpdated = false;
|
// bool isUpdated = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float lastValue = 0;
|
|
||||||
unsigned long lastUpdate = 0;
|
|
||||||
|
|
||||||
} Physical[physicalCount];
|
} Physical[physicalCount];
|
||||||
|
|
||||||
|
|
||||||
|
class Blinker
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint8_t ledPin_; // the number of the LED pin
|
||||||
|
uint32_t OnTime = 1000; // milliseconds of on-time
|
||||||
|
uint32_t OffTime = 1000; // milliseconds of off-time
|
||||||
|
bool ledState = LOW; // ledState used to set the LED
|
||||||
|
uint32_t previousMillis; // will store last time LED was updated
|
||||||
|
|
||||||
|
void setOutput(bool state_, uint32_t currentMillis_){
|
||||||
|
ledState = state_;
|
||||||
|
previousMillis = currentMillis_;
|
||||||
|
digitalWrite(ledPin_, state_);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Blinker(uint8_t pin)
|
||||||
|
{
|
||||||
|
ledPin_ = pin;
|
||||||
|
pinMode(ledPin_, OUTPUT);
|
||||||
|
previousMillis = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(uint32_t on, uint32_t off){
|
||||||
|
OnTime = on;
|
||||||
|
OffTime = off;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
uint32_t currentMillis = millis();
|
||||||
|
|
||||||
|
if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
|
||||||
|
{
|
||||||
|
setOutput(LOW, currentMillis);
|
||||||
|
}
|
||||||
|
else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
|
||||||
|
{
|
||||||
|
setOutput(HIGH, currentMillis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Blinker led = Blinker(ledPin);
|
||||||
|
|
||||||
|
|
||||||
void callBackProgMode(GroupObject& go){
|
void callBackProgMode(GroupObject& go){
|
||||||
progMode = (bool)go.value();
|
progMode = (bool)go.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback from reset-GO
|
void callBackDateTime(GroupObject& go){
|
||||||
|
static uint32_t lastUpdate = 0;
|
||||||
|
const uint32_t interval = (1000 * 60 * 60 * 24); // 1day
|
||||||
|
|
||||||
|
struct tm myTime;
|
||||||
|
myTime = go.value();
|
||||||
|
unsigned short tmp_sec = myTime.tm_sec;
|
||||||
|
unsigned short tmp_min = myTime.tm_min;
|
||||||
|
unsigned short tmp_hour = myTime.tm_hour;
|
||||||
|
unsigned short tmp_mday = myTime.tm_mday;
|
||||||
|
unsigned short tmp_month = myTime.tm_mon;
|
||||||
|
unsigned short tmp_year = myTime.tm_year;
|
||||||
|
|
||||||
|
if (millis() - lastUpdate >= interval && !timeStatus() == timeSet)
|
||||||
|
{
|
||||||
|
setTime(tmp_hour, tmp_min, tmp_sec, tmp_mday, tmp_month, tmp_year);
|
||||||
|
lastUpdate = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void resetCallback(GroupObject& go)
|
void resetCallback(GroupObject& go)
|
||||||
{
|
{
|
||||||
if (go.value())
|
if (go.value())
|
||||||
{
|
{
|
||||||
pzem.resetEnergy();
|
resetEnergy = true;
|
||||||
goReset.value(false);
|
goReset.value(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,6 +189,7 @@ void setup() {
|
|||||||
randomSeed(millis());
|
randomSeed(millis());
|
||||||
|
|
||||||
knx.readMemory();
|
knx.readMemory();
|
||||||
|
// led.set(5000, 5000);
|
||||||
|
|
||||||
if (knx.configured())
|
if (knx.configured())
|
||||||
{
|
{
|
||||||
@ -121,10 +199,11 @@ void setup() {
|
|||||||
percentCycle = ets_percentCycle[knx.paramByte(1)];
|
percentCycle = ets_percentCycle[knx.paramByte(1)];
|
||||||
timePeriod = ets_timePeriod[knx.paramByte(2)] * 1000;
|
timePeriod = ets_timePeriod[knx.paramByte(2)] * 1000;
|
||||||
|
|
||||||
resetFlag = knx.paramByte(3);
|
resetPeriod = knx.paramByte(3);
|
||||||
|
|
||||||
goReset.callback(resetCallback);
|
goReset.callback(resetCallback);
|
||||||
goReset.dataPointType(DPT_Trigger);
|
goReset.dataPointType(DPT_Trigger);
|
||||||
|
|
||||||
goDateTime.dataPointType(DPT_DateTime);
|
goDateTime.dataPointType(DPT_DateTime);
|
||||||
|
|
||||||
goProgMode.dataPointType(DPT_Trigger);
|
goProgMode.dataPointType(DPT_Trigger);
|
||||||
@ -137,6 +216,7 @@ void setup() {
|
|||||||
Physical[3].init(GOaddr += 1, DPT_Value_Power);
|
Physical[3].init(GOaddr += 1, DPT_Value_Power);
|
||||||
Physical[4].init(GOaddr += 1, DPT_Value_Energy);
|
Physical[4].init(GOaddr += 1, DPT_Value_Energy);
|
||||||
Physical[5].init(GOaddr += 1, DPT_Value_Frequency);
|
Physical[5].init(GOaddr += 1, DPT_Value_Frequency);
|
||||||
|
led.set(2000, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the led active on HIGH or low? Default is LOW
|
// is the led active on HIGH or low? Default is LOW
|
||||||
@ -152,22 +232,17 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
knx.loop();
|
knx.loop();
|
||||||
|
|
||||||
if (knx.configured() && !progMode)
|
if (knx.configured() && !progMode)
|
||||||
{
|
{
|
||||||
unsigned long currentMillis = millis();
|
refreshValueLoop();
|
||||||
|
resetEnergyLoop();
|
||||||
|
|
||||||
for (uint8_t i=0; i< physicalCount; i++)
|
for (uint8_t i=0; i< physicalCount; i++)
|
||||||
{
|
{
|
||||||
if (currentMillis - Physical[i].lastUpdate >= 1000)
|
Physical[i].loop();
|
||||||
{
|
|
||||||
float isanValue = refreshValue(i);
|
|
||||||
if(!isnan(isanValue))
|
|
||||||
{
|
|
||||||
Physical[i].loop(isanValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (progMode)
|
else if (progMode)
|
||||||
@ -176,45 +251,95 @@ void loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float refreshValue(uint8_t physicalNumber){
|
void refreshValueLoop(){
|
||||||
float valueTemp;
|
static const uint16_t pzemInterval = 500; // interval at which to blink (milliseconds)
|
||||||
switch (physicalNumber) { //maybe a pointer or reference could be nicer...
|
static uint32_t lastPzemUpdate = 0;
|
||||||
case 0:
|
|
||||||
valueTemp = pzem.voltage();
|
if (millis() - lastPzemUpdate >= pzemInterval)
|
||||||
return valueTemp;
|
{
|
||||||
case 1:
|
for (uint8_t i=0; i< physicalCount; i++)
|
||||||
valueTemp = pzem.current();
|
{
|
||||||
return valueTemp;
|
float isaValue;
|
||||||
case 2:
|
switch (i) { //maybe a pointer or reference could be nicer...
|
||||||
valueTemp = pzem.pf();
|
case 0:
|
||||||
return valueTemp;
|
isaValue = pzem.voltage();
|
||||||
case 3:
|
break;
|
||||||
valueTemp = pzem.power();
|
case 1:
|
||||||
return valueTemp;
|
isaValue = pzem.current();
|
||||||
case 4:
|
break;
|
||||||
valueTemp = pzem.energy();
|
case 2:
|
||||||
return valueTemp;
|
isaValue = pzem.pf();
|
||||||
case 5:
|
break;
|
||||||
valueTemp = pzem.frequency();
|
case 3:
|
||||||
return valueTemp;
|
isaValue = pzem.power();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
isaValue = pzem.energy();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
isaValue = pzem.frequency();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!isnan(isaValue))
|
||||||
|
{
|
||||||
|
Physical[i].setValue(isaValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetEnergyLoop(){
|
||||||
|
static time_t lastTime;
|
||||||
|
time_t samdTime = now();
|
||||||
|
|
||||||
|
if (timeStatus() == timeSet)
|
||||||
|
{
|
||||||
|
switch (resetPeriod)
|
||||||
|
{
|
||||||
|
case 1: //day
|
||||||
|
if (day(samdTime) != day(lastTime))
|
||||||
|
{
|
||||||
|
lastTime = samdTime;
|
||||||
|
pzem.resetEnergy();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: //week
|
||||||
|
if (weekday(samdTime) != weekday(lastTime) && weekday(samdTime) == 2) //monday
|
||||||
|
{
|
||||||
|
lastTime = samdTime;
|
||||||
|
pzem.resetEnergy();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // month
|
||||||
|
if (month(samdTime) != month(lastTime))
|
||||||
|
{
|
||||||
|
lastTime = samdTime;
|
||||||
|
pzem.resetEnergy();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: // year
|
||||||
|
if (year(samdTime) != year(lastTime))
|
||||||
|
{
|
||||||
|
lastTime = samdTime;
|
||||||
|
pzem.resetEnergy();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetEnergy(){
|
|
||||||
pzem.resetEnergy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prodModeLoop(){ // run Only if progMode triggered ( at start or callback)
|
void prodModeLoop(){ // run Only if progMode triggered ( at start or callback)
|
||||||
|
|
||||||
const uint32_t timerProgMode = ( 15 * 60 * 1000 ) ; // 15min
|
|
||||||
static uint32_t timerProgPrevMillis = 0;
|
static uint32_t timerProgPrevMillis = 0;
|
||||||
|
const uint32_t timerProgMode = ( 15 * 60 * 1000 ) ; // 15min
|
||||||
|
|
||||||
if (!knx.progMode() )
|
if (!knx.progMode())
|
||||||
{
|
{
|
||||||
knx.progMode(true);
|
knx.progMode(true);
|
||||||
timerProgPrevMillis = millis();
|
timerProgPrevMillis = millis();
|
||||||
|
led.set(500, 250);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user