Add knx-433 (#122)

* knx-pzem004v30

Add first draft of a pzem-004t power/current/tension/etc.. on your main line (BE CAREFUL WITH VOLTAGE!)

PZEM-004t-v30 wired on a samd21 with the use of Sercom2

Use with slight modification of: https://github.com/mandulaj/PZEM-004T-v30
View issue:  https://github.com/mandulaj/PZEM-004T-v30/issues/43

* Rename examples/knx-pzem0004t.xml to examples/knx-pzem004/knx-pzem0004t.xml

* Delete knx-pzem004t.knxprod

* Delete pzem-004t-v30.ino

* Update: 'just move to right directory'

* Update knx-pzem0004t.xml

* Add: ProgMode

* Fix/Update/Add

Add: ResetEnergy function with datetime
Update: led Class
Fix: many typo, errors

* Cleaning

Some strange bug/feature...
Information is transmitted only when the device got time from KNX, I have put 
        if (timeStatus() == timeSet && resetPeriod != 0)
        {
           resetEnergyLoop();
        }

But don't know if it's enough...

* Create knx-433Dio.ino

* Add Files:

README.md

.xml and knxprod files

* Delete pzem-004t-v30.ino

* Update pzem-004t-v30.ino
This commit is contained in:
zelogik 2021-02-09 02:37:14 +01:00 committed by GitHub
parent cddef776f7
commit 21a05ae9b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 574 additions and 10 deletions

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<KNX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" CreatedBy="KNX MT" ToolVersion="5.6.407.26745" xmlns="http://knx.org/xml/project/11">
<ManufacturerData>
<Manufacturer RefId="M-00FA">
<Catalog>
<CatalogSection Id="M-00FA_CS-1" Name="Geräte" Number="1" DefaultLanguage="en-US">
<CatalogItem Id="M-00FA_H-12288-1_HP-1074-0B-0000_CI-EC05-1" Name="KNX to 433mhz (DIO)" Number="1" ProductRefId="M-00FA_H-12288-1_P-EC05" Hardware2ProgramRefId="M-00FA_H-12288-1_HP-1074-0B-0000" DefaultLanguage="en-US" />
</CatalogSection>
</Catalog>
<ApplicationPrograms>
<ApplicationProgram Id="M-00FA_A-1074-0B-0000" ApplicationNumber="4212" ApplicationVersion="11" ProgramType="ApplicationProgram" MaskVersion="MV-07B0" Name="SAMD-DIO" LoadProcedureStyle="MergedProcedure" PeiType="0" DefaultLanguage="en-US" DynamicTableManagement="false" Linkable="false" MinEtsVersion="4.0">
<Static>
<Code>
<RelativeSegment Id="M-00FA_A-1074-0B-0000_RS-04-00000" Name="Parameters" Offset="0" Size="34" LoadStateMachine="4" />
</Code>
<ParameterTypes>
<ParameterType Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout" Name="StartupTimeout">
<TypeRestriction Base="Value" SizeInBit="8">
<Enumeration Text="Disabled" Value="0" Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout_EN-0" />
<Enumeration Text="1 s" Value="1" Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout_EN-1" />
<Enumeration Text="2 s" Value="2" Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout_EN-2" />
<Enumeration Text="3 s" Value="3" Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout_EN-3" />
<Enumeration Text="4 s" Value="4" Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout_EN-4" />
<Enumeration Text="5 s" Value="5" Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout_EN-5" />
<Enumeration Text="6 s" Value="6" Id="M-00FA_A-1074-0B-0000_PT-StartupTimeout_EN-6" />
</TypeRestriction>
</ParameterType>
<ParameterType Id="M-00FA_A-1074-0B-0000_PT-TimeCycle" Name="TimeCycle">
<TypeRestriction Base="Value" SizeInBit="8">
<Enumeration Text="Disabled" Value="0" Id="M-00FA_A-1074-0B-0000_PT-TimeCycle_EN-0" />
<Enumeration Text="1 sec" Value="1" Id="M-00FA_A-1074-0B-0000_PT-TimeCycle_EN-1" />
<Enumeration Text="5 sec" Value="2" Id="M-00FA_A-1074-0B-0000_PT-TimeCycle_EN-2" />
<Enumeration Text="15 sec" Value="3" Id="M-00FA_A-1074-0B-0000_PT-TimeCycle_EN-3" />
<Enumeration Text="1 min" Value="4" Id="M-00FA_A-1074-0B-0000_PT-TimeCycle_EN-4" />
<Enumeration Text="5 min" Value="5" Id="M-00FA_A-1074-0B-0000_PT-TimeCycle_EN-5" />
<Enumeration Text="15 min" Value="6" Id="M-00FA_A-1074-0B-0000_PT-TimeCycle_EN-6" />
</TypeRestriction>
</ParameterType>
<ParameterType Id="M-00FA_A-1074-0B-0000_PT-pulseValue" Name="pulseValue">
<TypeNumber SizeInBit="32" Type="signedInt" minInclusive="-2147483648" maxInclusive="2147483647" />
</ParameterType>
</ParameterTypes>
<Parameters>
<Parameter Id="M-00FA_A-1074-0B-0000_P-1" Name="startupTimeout" ParameterType="M-00FA_A-1074-0B-0000_PT-StartupTimeout" Text="Startup delaytime" Value="1">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="0" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-2" Name="timeCycleRefresh" ParameterType="M-00FA_A-1074-0B-0000_PT-TimeCycle" Text="refresh period" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="1" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-3" Name="value1" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Button 1 On" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="2" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-4" Name="value2" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Button 1 Off" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="6" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-5" Name="value3" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Button 2 On" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="10" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-6" Name="value4" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Button 2 Off" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="14" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-7" Name="value5" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Button 3 On" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="18" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-8" Name="value6" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Button 3 Off" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="22" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-9" Name="value7" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Shift On All" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="26" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-1074-0B-0000_P-10" Name="value8" ParameterType="M-00FA_A-1074-0B-0000_PT-pulseValue" Text="Shift Off All" Value="0">
<Memory CodeSegment="M-00FA_A-1074-0B-0000_RS-04-00000" Offset="30" BitOffset="0" />
</Parameter>
</Parameters>
<ParameterRefs>
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-1_R-1" RefId="M-00FA_A-1074-0B-0000_P-1" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-2_R-2" RefId="M-00FA_A-1074-0B-0000_P-2" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-3_R-3" RefId="M-00FA_A-1074-0B-0000_P-3" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-4_R-4" RefId="M-00FA_A-1074-0B-0000_P-4" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-5_R-5" RefId="M-00FA_A-1074-0B-0000_P-5" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-6_R-6" RefId="M-00FA_A-1074-0B-0000_P-6" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-7_R-7" RefId="M-00FA_A-1074-0B-0000_P-7" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-8_R-8" RefId="M-00FA_A-1074-0B-0000_P-8" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-9_R-9" RefId="M-00FA_A-1074-0B-0000_P-9" />
<ParameterRef Id="M-00FA_A-1074-0B-0000_P-10_R-10" RefId="M-00FA_A-1074-0B-0000_P-10" />
</ParameterRefs>
<ComObjectTable>
<ComObject Id="M-00FA_A-1074-0B-0000_O-1" Name="trigger value 1" Text="trigger value 1" Number="1" FunctionText="get/set button 1" ObjectSize="1 Bit" ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" />
<ComObject Id="M-00FA_A-1074-0B-0000_O-2" Name="trigger value 2" Text="trigger value 2" Number="2" FunctionText="get/set button 2" ObjectSize="1 Bit" ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" />
<ComObject Id="M-00FA_A-1074-0B-0000_O-3" Name="trigger value 3" Text="trigger value 3" Number="3" FunctionText="get/set button 3" ObjectSize="1 Bit" ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" />
<ComObject Id="M-00FA_A-1074-0B-0000_O-4" Name="trigger value 4" Text="trigger value 4" Number="4" FunctionText="get/set All buttons" ObjectSize="1 Bit" ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" />
<ComObject Id="M-00FA_A-1074-0B-0000_O-5" Name="trigger progMode" Text="trigger progMode" Number="5" FunctionText="put device in ETS programmation" ObjectSize="1 Bit" ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" />
</ComObjectTable>
<ComObjectRefs>
<ComObjectRef Id="M-00FA_A-1074-0B-0000_O-1_R-1" RefId="M-00FA_A-1074-0B-0000_O-1" />
<ComObjectRef Id="M-00FA_A-1074-0B-0000_O-2_R-2" RefId="M-00FA_A-1074-0B-0000_O-2" />
<ComObjectRef Id="M-00FA_A-1074-0B-0000_O-3_R-3" RefId="M-00FA_A-1074-0B-0000_O-3" />
<ComObjectRef Id="M-00FA_A-1074-0B-0000_O-4_R-4" RefId="M-00FA_A-1074-0B-0000_O-4" />
<ComObjectRef Id="M-00FA_A-1074-0B-0000_O-5_R-5" RefId="M-00FA_A-1074-0B-0000_O-5" />
</ComObjectRefs>
<AddressTable MaxEntries="65000" />
<AssociationTable MaxEntries="65000" />
<LoadProcedures>
<LoadProcedure MergeId="2">
<LdCtrlRelSegment LsmIdx="4" Size="34" Mode="0" Fill="0" AppliesTo="full" />
</LoadProcedure>
<LoadProcedure MergeId="4">
<LdCtrlWriteRelMem ObjIdx="4" Offset="0" Size="34" Verify="true" />
</LoadProcedure>
</LoadProcedures>
<Options />
</Static>
<Dynamic>
<ChannelIndependentBlock>
<ParameterBlock Id="M-00FA_A-1074-0B-0000_PB-1" Name="ParameterPage" Text="Common Parameters">
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-1_R-1" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-2_R-2" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-3_R-3" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-4_R-4" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-5_R-5" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-6_R-6" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-7_R-7" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-8_R-8" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-9_R-9" />
<ParameterRefRef RefId="M-00FA_A-1074-0B-0000_P-10_R-10" />
<ComObjectRefRef RefId="M-00FA_A-1074-0B-0000_O-1_R-1" />
<ComObjectRefRef RefId="M-00FA_A-1074-0B-0000_O-2_R-2" />
<ComObjectRefRef RefId="M-00FA_A-1074-0B-0000_O-3_R-3" />
<ComObjectRefRef RefId="M-00FA_A-1074-0B-0000_O-4_R-4" />
<ComObjectRefRef RefId="M-00FA_A-1074-0B-0000_O-5_R-5" />
</ParameterBlock>
</ChannelIndependentBlock>
</Dynamic>
</ApplicationProgram>
</ApplicationPrograms>
<Hardware>
<Hardware Id="M-00FA_H-12288-1" Name="SAMD21-KNXto433" SerialNumber="12288" VersionNumber="1" BusCurrent="10" HasIndividualAddress="true" HasApplicationProgram="true">
<Products>
<Product Id="M-00FA_H-12288-1_P-EC05" Text="KNX to 433mhz (DIO)" OrderNumber="EC05" IsRailMounted="false" DefaultLanguage="en-US">
<RegistrationInfo RegistrationStatus="Registered" />
</Product>
</Products>
<Hardware2Programs>
<Hardware2Program Id="M-00FA_H-12288-1_HP-1074-0B-0000" MediumTypes="MT-0">
<ApplicationProgramRef RefId="M-00FA_A-1074-0B-0000" />
<RegistrationInfo RegistrationStatus="Registered" RegistrationNumber="0001/111" />
</Hardware2Program>
</Hardware2Programs>
</Hardware>
</Hardware>
</Manufacturer>
</ManufacturerData>
</KNX>

View File

@ -0,0 +1,32 @@
Control Chacon/DIO 433Mhz plug like that: (not an affiliated link just for info)
https://www.amazon.fr/DiO-Connected-Home-t%C3%A9l%C3%A9command%C3%A9es-t%C3%A9l%C3%A9commande/dp/B005LKMAW0
Hardware:
- Samd21 (gy-samd21)
- FS 1000A (cheap 433 transmitter)
- TpUart KNX
- logic level converter
- Chacon/DIO 433Mhz plug (must work with every dumb 433mhz plug/remote that support the HomeEasy protocol)
Software
- change the rfPin variable, compile and tranfert into the samd21 (or any microcontroller)
- (maybe) adapt THIGH and TLOW in rfCode class for your case.
Before configuring ETS, you need to receive the 433mhz code for each button of your remote.
Take an arduino UNO, plug the FS1000a receiver, look on github/google to receive the code rc-switch or https://charleslabs.fr/fr/project-Contr%C3%B4le+de+prises+DiO+avec+Arduino (in french), or https://caron.ws/diy-cartes-microcontroleurs/piloter-vos-prises-chacon-rf433mhz-arduino/ ( in french too)
for me it's : 1806947472 and 1806947456 for the channel 1 on/off, etc...
Now in ETS put the received 433Mhz code into parameters.
-> Full Download in ETS and enjoy.
Feature:
This code is delay() free, blocking code free (ie: no long while or for loop), to call the knx.loop() as fast as possible.

Binary file not shown.

View File

@ -0,0 +1,368 @@
#include <knx.h>
//#include <DiOremote.h>
//#define DEBUGSERIAL 1
#ifdef DEBUGSERIAL
#define DPRINT(...) SerialUSB.print(__VA_ARGS__)
#define DPRINTLN(...) SerialUSB.println(__VA_ARGS__)
#include <MemoryFree.h>
#include <pgmStrToRAM.h>
#else
#define DPRINT(...) //now defines a blank line
#define DPRINTLN(...) //now defines a blank line
#endif
#define goButton1 knx.getGroupObject(1)
#define goButton2 knx.getGroupObject(2)
#define goButton3 knx.getGroupObject(3)
#define goButtonAll knx.getGroupObject(4)
#define goProgMode knx.getGroupObject(5)
//DiOremote myRemote = DiOremote(6);
//void function2();
//void function1(void (*)());
//void loop() {
// function1(function2);
//}
//Global Const
const uint8_t ets_startupTimeout[7] = {0, 1, 2, 3, 4, 5, 6};
const uint16_t ets_timePeriod[7] = {0, 1, 5, 15, 1 * 60, 5 * 60, 15 * 60};
const uint8_t ets_progMode[7] = {0, 1, 2 * 60, 3 * 60, 4 * 60, 5 * 60, 10 * 60}; //need knxprod update... ?
const uint8_t ledPin = LED_BUILTIN;
const uint8_t rfPin = 6;
// //Protocol timing (in us)
// #define DiOremote_START_FRAME_1 220
// #define DiOremote_START_FRAME_0 2675
// #define DiOremote_THIGH 220
// #define DiOremote_TLOW_0 350 short
// #define DiOremote_TLOW_1 1400 long
// #define DiOremote_END_FRAME_1 220
// #define DiOremote_END_FRAME_0 10600
// Global Variable
bool progMode = true;
// bool codeSendindBlock = false;
uint8_t percentCycle = 0; // better to define a global or read knx.paramByte each time... ?
uint32_t timePeriod = 0; // same here,
uint32_t timerProgMode = 0; // same here,
uint32_t ch1_on, ch1_off, ch2_on, ch2_off, ch3_on, ch3_off, chall_on, chall_off;
class RfCode {
private:
uint8_t _rfPin;
uint32_t _codeValueOn;
uint32_t _codeValueOff;
uint8_t _GOaddress;
const uint16_t THIGH = 220, TSTART = 2675, TSHORT = 220, TLONG = 1400, TEND = 10600;
uint8_t _loopCount = 0; // fixed ==5
bool lastState = false;
uint32_t _codePending = 0;
uint32_t _codePendingMemory = _codePending;
uint8_t _loopPending = 0; // fixed ==32
bool _sendMsgPending= false;
enum PulseStates {
PULSE_INIT,
PULSE_KEY1, //32 times loop
PULSE_KEY2, //32 times loop
PULSE_END
};
PulseStates pulseStates = PULSE_INIT;
bool pulseSend(const uint16_t delayHigh, const uint16_t delayLow){ //alike state machine?
static bool initPulse = false;
static bool highDone = false;
static uint32_t pulseLastTime = 0;
uint32_t currentTime = micros();
if (!initPulse){
initPulse = true;
digitalWrite(_rfPin, HIGH);
pulseLastTime = currentTime;
}
else if (currentTime - pulseLastTime >= delayHigh && !highDone)
{
digitalWrite(_rfPin, LOW);
pulseLastTime = currentTime;
highDone = true;
}
else if (currentTime - pulseLastTime >= delayLow && highDone)
{
initPulse = false;
highDone = false;
}
return !initPulse;
}
uint16_t TTime(bool invert){
uint16_t TTIME;
if (_codePending & 0x80000000L)// future bug if uint32_t _codePengin > 2^32 / 2 ?
{
TTIME = invert ? TSHORT : TLONG;
}
else
{
TTIME = invert ? TLONG : TSHORT;
}
return TTIME;
}
public:
RfCode(uint8_t rfPin){
_rfPin = rfPin;
pinMode(_rfPin, OUTPUT);
}
// void init(uint8_t addr, uint32_t codeValueOn, uint32_t codeValueOff){ //GroupObject &device, long timeOn){
// _codeValueOn = codeValueOn;
// _codeValueOff = codeValueOff;
// _GOaddress = addr;
// }
void setState(bool modeOnOff, uint32_t codeValueOn, uint32_t codeValueOff){
if (!_sendMsgPending)
{
_sendMsgPending = true;
_codeValueOn = codeValueOn;
_codeValueOff = codeValueOff;
// _GOaddress = addr;
if (modeOnOff){
_codePending = _codeValueOn;
// SerialUSB.println(_codePending);
}
else
{
_codePending = _codeValueOff;
// SerialUSB.println(_codePending);
}
_codePendingMemory = _codePending;
}
}
// bool getMsgPendingState(){
// return _sendMsgPending;
// }
void loop(){
if (_sendMsgPending)
{
// needed to block setState of another Class, yes FIFO is better...
// codeSendindBlock = true;
if (_loopCount < 5)
{
switch (pulseStates){
case PULSE_INIT:
if (pulseSend(THIGH, TSTART)){
pulseStates = PULSE_KEY1;
}
break;
case PULSE_KEY1:
if (pulseSend(THIGH, TTime(false)))
{
pulseStates = PULSE_KEY2;
}
break;
case PULSE_KEY2:
if (pulseSend(THIGH, TTime(true)))
{
if (_loopPending < 32){
_codePending <<= 1;
_loopPending++;
pulseStates = PULSE_KEY1; // next loop !
}
else{ // finish!
pulseStates = PULSE_END;
}
}
break;
case PULSE_END:
if (pulseSend(THIGH, TEND)){
_loopCount++;
_codePending = _codePendingMemory;
_loopPending = 0;
pulseStates = PULSE_INIT;
}
break;
default:
break;
}
}
else
{
_loopCount = 0;
_sendMsgPending = false;
// codeSendindBlock = false;
}
}
}
};
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);
}
}
};
RfCode button = RfCode(5);
Blinker led = Blinker(ledPin);
void callBackButton1(GroupObject& go){
button.setState((bool)go.value(), ch1_on, ch1_off);
}
void callBackButton2(GroupObject& go){
button.setState((bool)go.value(), ch2_on, ch2_off);
}
void callBackButton3(GroupObject& go){
button.setState((bool)go.value(), ch3_on, ch3_off);
}
void callBackButtonAll(GroupObject& go){
button.setState((bool)go.value(), chall_on, ch3_off);
}
void callBackProgMode(GroupObject& go){
progMode = (bool)go.value();
}
void setup() {
// #ifdef DEBUGSERIAL
// SerialUSB.begin(9600);
// while (!SerialUSB) { //wait for DEBUGING
// ; // wait for serial port to connect. Needed for native USB port only
// }
// ArduinoPlatform::SerialDebug = &SerialUSB;
// #endif
randomSeed(millis());
// knx.bau().deviceObject().individualAddress(1);
knx.readMemory();
if (knx.configured())
{
DPRINT("Setup: KNX Configuration...");
progMode = false; // don't need to put device in progMode.
int confStartupTime = ets_startupTimeout[knx.paramByte(0)] * 1000;
delay(confStartupTime); // the only delay used, why make a withoutDelay function for that?
timePeriod = ets_timePeriod[knx.paramByte(1)] * 1000;
// timerProgMode = ets_progMode[knx.paramByte(34)] * 1000;
ch1_on = knx.paramInt(2);
ch1_off = knx.paramInt(6);
goButton1.callback(callBackButton1);
goButton1.dataPointType(DPT_Switch);
ch2_on = knx.paramInt(10);
ch2_off = knx.paramInt(14);
goButton2.callback(callBackButton2);
goButton2.dataPointType(DPT_Switch);
ch3_on = knx.paramInt(18);
ch3_off = knx.paramInt(22);
goButton3.callback(callBackButton3);
goButton3.dataPointType(DPT_Switch);
chall_on = knx.paramByte(26);
chall_off = knx.paramByte(30);
goButtonAll.callback(callBackButtonAll);
goButtonAll.dataPointType(DPT_Switch);
goProgMode.callback(callBackProgMode);
goProgMode.dataPointType(DPT_Trigger);
DPRINTLN("Finished");
}
knx.ledPin(5);
knx.ledPinActiveOn(HIGH);
knx.buttonPin(9);
knx.start();
led.set(2000, 2000);
}
void loop()
{
knx.loop();
led.loop();
if (knx.configured() && !progMode)
{
button.loop();
}
else if (progMode)
{
prodModeLoop();
}
}
void prodModeLoop(){ // run Only if progMode triggered ( at start or callback)
const uint32_t timerProgMode = ( 15 * 60 * 1000 ) ; // 15min
static uint32_t timerProgPrevMillis = 0;
if (!knx.progMode())
{
knx.progMode(true);
led.set(500, 500);
timerProgPrevMillis = millis();
DPRINTLN("progModeLoop Start");
}
else
{
if (millis() - timerProgPrevMillis > timerProgMode) {
knx.progMode(false);
goProgMode.value(false);
progMode = 0;
led.set(100, 100); // panic!
DPRINTLN("progModeLoop Stop");
}
}
}

View File

@ -38,7 +38,7 @@ const uint8_t physicalCount = 6; // voltage,current,power_factor,power,energy,fr
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
//uint8_t resetEnergy = 0; // and here... disabled/day/week/month
bool progMode = true;
@ -54,11 +54,10 @@ struct Physical {
void loop(){
// unsigned long currentMillis = millis();
// Delta Change update as defined in ETS
int32_t deltaPercent = ( 100 * ( _value - _lastValue ) / _value );
float deltaPercent = ( 100 * ( _value - _lastValue ) / _value );
if ( percentCycle != 0 && abs(deltaPercent) >= percentCycle )
{
_trigger = true;
_lastValue = _value;
}
// Refresh groupAddress value as defined in ETS since last update
@ -70,6 +69,7 @@ struct Physical {
// UpdateGO but send to bus only if triggered by time or value change percentage
if (_trigger){
knx.getGroupObject(_GOaddr).value(_value, _dpt);
_lastValue = _value;
_lastMillis = millis();
_trigger = false;
}else{
@ -143,7 +143,6 @@ class Blinker
Blinker led = Blinker(ledPin);
void callBackProgMode(GroupObject& go){
progMode = (bool)go.value();
}
@ -172,7 +171,7 @@ void resetCallback(GroupObject& go)
{
if (go.value())
{
resetEnergy = true;
pzem.resetEnergy();
goReset.value(false);
}
}
@ -181,7 +180,7 @@ void setup() {
pinPeripheral(PIN_SERIAL2_RX, PIO_SERCOM);
pinPeripheral(PIN_SERIAL2_TX, PIO_SERCOM);
SerialUSB.begin(9600);
// SerialUSB.begin(9600);
Serial2.begin(9600);
ArduinoPlatform::SerialDebug = &SerialUSB;
@ -238,12 +237,17 @@ void loop() {
if (knx.configured() && !progMode)
{
refreshValueLoop();
resetEnergyLoop();
for (uint8_t i=0; i< physicalCount; i++)
{
Physical[i].loop();
}
if (timeStatus() == timeSet && resetPeriod != 0)
{
resetEnergyLoop();
}
}
else if (progMode)
{
@ -257,7 +261,7 @@ void refreshValueLoop(){
if (millis() - lastPzemUpdate >= pzemInterval)
{
for (uint8_t i=0; i< physicalCount; i++)
for (uint8_t i=0; i < physicalCount; i++)
{
float isaValue;
switch (i) { //maybe a pointer or reference could be nicer...
@ -282,11 +286,18 @@ void refreshValueLoop(){
default:
break;
}
if(!isnan(isaValue))
{
Physical[i].setValue(isaValue);
}
else
{
Physical[i].setValue(-1);
}
}
lastPzemUpdate = millis();
led.set(500, 1000);
}
}
@ -339,14 +350,14 @@ void prodModeLoop(){ // run Only if progMode triggered ( at start or callback)
{
knx.progMode(true);
timerProgPrevMillis = millis();
led.set(500, 250);
led.set(50, 100);
}
else
{
if (millis() - timerProgPrevMillis > timerProgMode) {
knx.progMode(false);
goProgMode.value(false);
progMode = 0;
progMode = false;
}
}
}