diff --git a/examples/knx-433Dio/KNXto433.xml b/examples/knx-433Dio/KNXto433.xml
new file mode 100644
index 0000000..888c1e9
--- /dev/null
+++ b/examples/knx-433Dio/KNXto433.xml
@@ -0,0 +1,153 @@
+
+
+  
+    
+      
+        
+          
+        
+      
+      
+        
+          
+            
+              
+            
+            
+              
+                
+                  
+                  
+                  
+                  
+                  
+                  
+                  
+                
+              
+              
+                
+                  
+                  
+                  
+                  
+                  
+                  
+                  
+                
+              
+              
+                
+              
+            
+            
+              
+                
+              
+              
+                
+              
+              
+                
+              
+              
+                
+              
+              
+                
+              
+              
+                
+              
+              
+                
+              
+              
+                
+              
+              
+                
+              
+              
+                
+              
+            
+            
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+            
+            
+              
+              
+              
+              
+              
+            
+            
+              
+              
+              
+              
+              
+            
+            
+            
+            
+              
+                
+              
+              
+                
+              
+            
+            
+          
+          
+            
+              
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+              
+            
+          
+        
+      
+      
+        
+          
+            
+              
+            
+          
+          
+            
+              
+              
+            
+          
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/examples/knx-433Dio/README.md b/examples/knx-433Dio/README.md
new file mode 100644
index 0000000..31d7ce1
--- /dev/null
+++ b/examples/knx-433Dio/README.md
@@ -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.
+
+
+
+
diff --git a/examples/knx-433Dio/knx-433.knxprod b/examples/knx-433Dio/knx-433.knxprod
new file mode 100644
index 0000000..b3d72fc
Binary files /dev/null and b/examples/knx-433Dio/knx-433.knxprod differ
diff --git a/examples/knx-433Dio/knx-433Dio.ino b/examples/knx-433Dio/knx-433Dio.ino
new file mode 100644
index 0000000..841dd6a
--- /dev/null
+++ b/examples/knx-433Dio/knx-433Dio.ino
@@ -0,0 +1,368 @@
+#include 
+//#include 
+
+//#define DEBUGSERIAL 1
+#ifdef DEBUGSERIAL
+  #define DPRINT(...)    SerialUSB.print(__VA_ARGS__)
+  #define DPRINTLN(...)  SerialUSB.println(__VA_ARGS__)
+  #include 
+  #include 
+#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");
+        }
+    }
+}
diff --git a/examples/knx-pzem004/pzem-004t-v30.ino b/examples/knx-pzem004/pzem-004t-v30.ino
index 2bc92ff..2bf6527 100644
--- a/examples/knx-pzem004/pzem-004t-v30.ino
+++ b/examples/knx-pzem004/pzem-004t-v30.ino
@@ -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;
         }
     }
 }