diff --git a/libraries/GpioCtrl/GpioCtrl.cpp b/libraries/GpioCtrl/GpioCtrl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..19ba58edd9caf863e516729baeb58b1180623eb3
--- /dev/null
+++ b/libraries/GpioCtrl/GpioCtrl.cpp
@@ -0,0 +1,165 @@
+//-----------------------------------------------------------------------------
+// Thema:   Social Manufacturing Network / Development Environment
+// Datei:   GpioCtrl.cpp
+// Editor:  Robert Patzke
+// URI/URL: www.mfp-portal.de
+//-----------------------------------------------------------------------------
+// Lizenz:  CC-BY-SA  (siehe Wikipedia: Creative Commons)
+//
+
+#include "GpioCtrl.h"
+
+// --------------------------------------------------------------------------
+// Konstruktoren
+// --------------------------------------------------------------------------
+//
+
+GpioCtrl::GpioCtrl(IntrfGpio *inGpioPtr, int inPeriod)
+{
+  gpioPtr = inGpioPtr;
+  period  = inPeriod;
+}
+
+// --------------------------------------------------------------------------
+// Konfigurationen
+// --------------------------------------------------------------------------
+//
+
+
+
+// --------------------------------------------------------------------------
+// Anwendungsfunktionen allgemein
+// --------------------------------------------------------------------------
+//
+void GpioCtrl::run()
+{
+  BlinkPtr blinkPtr;
+
+  for(int i = 0; i < MaxGpioElements; i++)
+  {
+    // -----------------------------------------------------------------------
+    // run blink
+    // -----------------------------------------------------------------------
+    //
+    blinkPtr = &blinkEl[i];
+
+    if(blinkPtr->doBlink && (blinkPtr->portRef != NULL))
+    {
+    // Blinken wird aktiviert/deaktiviert
+    // --------------------------------------------------------
+      if(!blinkPtr->blinked)    // Noch kein Blinken
+      {
+        if(!blinkPtr->portSet)  // Port noch nicht gesetzt
+        {
+          if(blinkPtr->invPort)
+            gpioPtr->clr(blinkPtr->portRef);
+          else
+            gpioPtr->set(blinkPtr->portRef);
+          blinkPtr->portSet = true;
+        }
+
+        if(blinkPtr->blinkLen > 0)
+          blinkPtr->blinkLen--;
+        else
+        {
+          blinkPtr->blinked = true;
+          blinkPtr->blinkLen = blinkPtr->blinkLenSet;
+        }
+      }
+      else // blinked
+      {
+        if(blinkPtr->portSet)   // Port ist gesetzt
+        {
+          if(blinkPtr->invPort)
+            gpioPtr->set(blinkPtr->portRef);
+          else
+            gpioPtr->clr(blinkPtr->portRef);
+          blinkPtr->portSet = false;
+        }
+
+        if(blinkPtr->repeatPause > 0)
+        {
+          blinkPtr->repeatPause--;
+        }
+        else if(blinkPtr->repeat > 0)
+        {
+          blinkPtr->repeat--;
+          blinkPtr->repeatPause = blinkPtr->repeatPauseSet;
+          blinkPtr->blinked = false;
+        }
+        else
+        {
+          if(blinkPtr->blinkPause > 0)
+            blinkPtr->blinkPause--;
+          else
+          {
+            blinkPtr->blinked = false;
+            blinkPtr->blinkPause = blinkPtr->blinkPauseSet;
+            blinkPtr->repeat = blinkPtr->repeatSet;
+            blinkPtr->repeatPause = blinkPtr->repeatPauseSet;
+          }
+        }
+      }
+    // --------------------------------------------------------
+    } // doBlink, portRef
+  } // for
+} // run
+
+// --------------------------------------------------------------------------
+// Anwendungsfunktionen Steuerung der Pins
+// --------------------------------------------------------------------------
+//
+
+void  GpioCtrl::blink(GpioExtRefPtr portRef, int chn, int len, int pause)
+{
+  blink(portRef,chn,len,0,pause,0,false);
+}
+
+void  GpioCtrl::blink(GpioExtRefPtr portRef, int chn, int len, int pause, bool invert)
+{
+  blink(portRef,chn,len,0,pause,0,invert);
+}
+
+void  GpioCtrl::blink(GpioExtRefPtr portRef, int chn, int len, int wait, int pause, int repeat, bool invert)
+{
+  BlinkPtr  blinkPtr;
+  int       calc;
+
+  if(chn < 0 || chn >= MaxGpioElements) return;
+  if(len <= 0) return;
+  if(period == 0) return;
+
+  blinkPtr = &blinkEl[chn];
+  blinkPtr->portRef = portRef;
+  blinkPtr->invPort = invert;
+
+  calc = (1000 * len) / period;
+  if(calc == 0)
+    calc = 1;
+  blinkPtr->blinkLen = blinkPtr->blinkLenSet = calc;
+
+  calc = (1000 * pause) / period;
+  if(calc == 0)
+    calc = 1;
+  blinkPtr->blinkPause = blinkPtr->blinkPauseSet = calc;
+
+  if(repeat != 0)
+  {
+    blinkPtr->repeat = blinkPtr->repeatSet = repeat;
+
+    calc = (1000 * wait) / period;
+    if(calc == 0)
+      calc = 1;
+    blinkPtr->repeatPause = blinkPtr->repeatPauseSet = calc;
+  }
+
+  blinkPtr->blinked   = false;
+  blinkPtr->doBlink   = true;
+  blinkPtr->portSet   = false;
+}
+
+
+// ----------------------------------------------------------------------------
+// Ereignisbearbeitung und Interrupts
+// ----------------------------------------------------------------------------
+//
diff --git a/libraries/GpioCtrl/GpioCtrl.h b/libraries/GpioCtrl/GpioCtrl.h
new file mode 100644
index 0000000000000000000000000000000000000000..8374bdd884b86a50990246476af128ec7702471b
--- /dev/null
+++ b/libraries/GpioCtrl/GpioCtrl.h
@@ -0,0 +1,91 @@
+//-----------------------------------------------------------------------------
+// Thema:   Social Manufacturing Network / Development Environment
+// Datei:   GpioCtrl.h
+// Editor:  Robert Patzke
+// URI/URL: www.mfp-portal.de
+//-----------------------------------------------------------------------------
+// Lizenz:  CC-BY-SA  (siehe Wikipedia: Creative Commons)
+//
+#ifndef GpioCtrl_h
+#define GpioCtrl_h
+//-----------------------------------------------------------------------------
+
+#include "stdio.h"
+#include "IntrfGpio.h"
+
+#define MaxGpioElements   4
+
+class GpioCtrl
+{
+  // --------------------------------------------------------------------------
+  // spezifische Datentypen
+  // --------------------------------------------------------------------------
+  //
+  typedef struct _Blink
+  {
+    int           blinkLen;
+    int           blinkLenSet;
+    int           blinkPause;
+    int           blinkPauseSet;
+    int           repeat;
+    int           repeatSet;
+    int           repeatPause;
+    int           repeatPauseSet;
+    bool          doBlink;
+    bool          blinked;
+    bool          portSet;
+    bool          invPort;
+    GpioExtRefPtr portRef;
+  } Blink, *BlinkPtr;
+
+private:
+  // --------------------------------------------------------------------------
+  // lokale Variablen
+  // --------------------------------------------------------------------------
+  //
+  IntrfGpio *gpioPtr;                 // Referenz auf Pin-Treiber
+  Blink     blinkEl[MaxGpioElements]; // Liste der Blinkelemente
+  int       period;                   // Aufrufperiode in Mikrosekunden
+
+  // --------------------------------------------------------------------------
+  // lokale Funktionen
+  // --------------------------------------------------------------------------
+  //
+
+public:
+  // --------------------------------------------------------------------------
+  // Konstruktoren
+  // --------------------------------------------------------------------------
+  //
+  GpioCtrl(IntrfGpio *inGpioPtr, int inPeriod);
+
+  // --------------------------------------------------------------------------
+  // Konfigurationen
+  // --------------------------------------------------------------------------
+  //
+
+  // --------------------------------------------------------------------------
+  // Anwendungsfunktionen
+  // --------------------------------------------------------------------------
+  //
+  void run();
+  void  blink(GpioExtRefPtr portRef, int chn, int len, int pause);
+  void  blink(GpioExtRefPtr portRef, int chn, int len, int pause, bool invert);
+  void  blink(GpioExtRefPtr portRef, int chn, int len, int wait, int pause, int repeat);
+  void  blink(GpioExtRefPtr portRef, int chn, int len, int wait, int pause, int repeat, bool invert);
+
+
+  // ----------------------------------------------------------------------------
+  // Ereignisbearbeitung und Interrupts
+  // ----------------------------------------------------------------------------
+  //
+
+  // --------------------------------------------------------------------------
+  // Debugging und globale Variablen
+  // --------------------------------------------------------------------------
+  //
+
+};
+
+//-----------------------------------------------------------------------------
+#endif // GpioCtrl_h
diff --git a/libraries/nRF52840Gpio/nRF52840Gpio.cpp b/libraries/nRF52840Gpio/nRF52840Gpio.cpp
index 47a25ddebcff11a2d9ef003cf83ddf1be250d057..57f3a89ec14be8bbf2aa21fa59f87a5675f6aee9 100644
--- a/libraries/nRF52840Gpio/nRF52840Gpio.cpp
+++ b/libraries/nRF52840Gpio/nRF52840Gpio.cpp
@@ -85,7 +85,7 @@ GpioError nRF52840Gpio::config(int nrFrom, int nrTo, unsigned int cnfBits, GpioE
   tmpMask = IfDrvPullDown | IfDrvPullUp;
   if((cnfBits & tmpMask) == tmpMask) return (GEcdictPar);
 
-  cnfValue  = getCnfValue(cnfBits);
+  cnfValue  = getCnfValue(cnfBits);    // spezifische Bits setzen
   tmpMask   = 0;
 
   // Bedienen des angegebenen Bereiches
@@ -93,9 +93,9 @@ GpioError nRF52840Gpio::config(int nrFrom, int nrTo, unsigned int cnfBits, GpioE
   for(int i = nrFrom; i <= nrTo; i++)
   {
     portNum = (i & 0x0E0) >> 5;
-    pinNum  =  i & 0x01F;
+    pinNum  =  i & 0x01F;         // 0 ... 31
 
-    tmpMask |= (1 << i);
+    tmpMask |= (1 << pinNum);
 
     if(portNum == 0)
       gpioPtr = NrfGpioPtr0;
@@ -116,7 +116,7 @@ GpioError nRF52840Gpio::config(int nr, unsigned int cnfBits, GpioExtRefPtr refPt
   return(config(nr,nr,cnfBits, refPtr));
 }
 
-GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr)
+GpioError nRF52840Gpio::config(GpioExtMask *maskPtr, unsigned int cnfBits, GpioExtRefPtr refPtr)
 {
   GpioError retv = GEnoError;
   dword     cnfVal;
@@ -135,12 +135,12 @@ GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRe
 
   for(int i = 0; i < 32; i++)
   {
-    if(mask.port == 0)
+    if(maskPtr->port == 0)
       gpioPtr = NrfGpioPtr0;
     else
       gpioPtr = NrfGpioPtr1;
 
-    if(mask.pins & chkMask)
+    if(maskPtr->pins & chkMask)
       gpioPtr->PIN_CNF[i] = cnfVal;
 
     chkMask <<= 1;
@@ -149,7 +149,7 @@ GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRe
   if(refPtr != NULL)
   {
     refPtr->ioPtr = (dword *) gpioPtr;
-    refPtr->pins  = mask.pins;
+    refPtr->pins  = maskPtr->pins;
   }
 
   return(retv);
@@ -183,7 +183,7 @@ GpioError nRF52840Gpio::configArd(ArdMask ardMask, unsigned int cnfBits)
       break;
   }
 
-  return config(ioMask, cnfBits, NULL);
+  return config(&ioMask, cnfBits, NULL);
 }
 
 
@@ -192,6 +192,25 @@ GpioError nRF52840Gpio::configArd(ArdMask ardMask, unsigned int cnfBits)
   // Anwendungsfunktionen
   // --------------------------------------------------------------------------
   //
+bool      nRF52840Gpio::isSet(GpioExtRefPtr ioRefPtr)
+{
+  gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr;
+  return(gpioPtr->IN & ioRefPtr->pins);
+}
+
+bool      nRF52840Gpio::anySet(GpioExtRefPtr ioRefPtr)
+{
+  gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr;
+  return(gpioPtr->IN & ioRefPtr->pins);
+}
+
+bool      nRF52840Gpio::allSet(GpioExtRefPtr ioRefPtr)
+{
+  gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr;
+  return((gpioPtr->IN & ioRefPtr->pins) == ioRefPtr->pins);
+}
+
+
 void      nRF52840Gpio::read(GpioExtRefPtr ioRefPtr, GpioExtValPtr valPtr)
 {
   gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr;
diff --git a/libraries/nRF52840Gpio/nRF52840Gpio.h b/libraries/nRF52840Gpio/nRF52840Gpio.h
index addf5ad533ddfecabd2c540824238c278a117998..0bf899dac62db0ff73fa3f58953a6ed37fccc910 100644
--- a/libraries/nRF52840Gpio/nRF52840Gpio.h
+++ b/libraries/nRF52840Gpio/nRF52840Gpio.h
@@ -110,6 +110,7 @@ typedef struct _nrfGpio
 #define ArdD11      P1(1)
 #define ArdD12      P1(8)
 #define ArdD13      P0(13)
+#define ArdLedGn    P1(9)
 
 #define ArdD2Mask   (1 << 11)
 #define ArdD3Mask   (1 << 12)
@@ -150,7 +151,7 @@ public:
   dword     getCnfValue(unsigned int cnfBits);
   GpioError config(int nr, unsigned int cnfBits, GpioExtRefPtr refPtr);
   GpioError config(int nrFrom, int nrTo, unsigned int cnfBits, GpioExtRefPtr refPtr);
-  GpioError config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr);
+  GpioError config(GpioExtMaskPtr maskPtr, unsigned int cnfBits, GpioExtRefPtr refPtr);
 
   GpioError configArd(ArdMask ardMask, unsigned int cnfBits);
 
@@ -158,6 +159,9 @@ public:
   // Anwendungsfunktionen
   // --------------------------------------------------------------------------
   //
+  bool      isSet(GpioExtRefPtr ioRef);
+  bool      allSet(GpioExtRefPtr ioRef);
+  bool      anySet(GpioExtRefPtr ioRef);
   void      read(GpioExtRefPtr ioRef, GpioExtValPtr valPtr);
   dword     readArd(ArdMask ardMask);
 
diff --git a/sketches/SoaapBleSlave/SoaapBleSlave.h b/sketches/SoaapBleSlave/SoaapBleSlave.h
index 84bf1f4243b3b5f477a99f99819ef95061c2cf35..fc5dd65c3254e6f98e1c2cbdb3c04d42eaa12df2 100644
--- a/sketches/SoaapBleSlave/SoaapBleSlave.h
+++ b/sketches/SoaapBleSlave/SoaapBleSlave.h
@@ -19,6 +19,7 @@
 #include "StateMachine.h"
 
 #include "nRF52840Gpio.h"
+#include "GpioCtrl.h"
 
 #include "nRF52840Twi.h"
 #include "SensorLSM9DS1.h"
@@ -62,6 +63,7 @@ void smSensGetErrors() ;
 void smDebugProcMeas();
 void smSensGetTimeOuts() ;
 void smSensGetRunCounts() ;
+void smTestIO();
 void smTempTesting();
 void smTestAdcMem();
 #endif
diff --git a/sketches/SoaapBleSlave/SoaapBleSlave.ino b/sketches/SoaapBleSlave/SoaapBleSlave.ino
index e2c03755245a1e74d71dc505a0e14aad0d63b515..70acbc983e06ac0682f3b734b5e8f7fa5ca943fe 100644
--- a/sketches/SoaapBleSlave/SoaapBleSlave.ino
+++ b/sketches/SoaapBleSlave/SoaapBleSlave.ino
@@ -46,7 +46,7 @@ char *StartMsg =
 #ifdef SlaveADR4
     "(Adr=4), "
 #endif
-    "Version 20221024-1 "
+    "Version 20221107-1 "
 };
 
 LoopCheck     lc;
@@ -71,12 +71,13 @@ Monitor       mon(modeEcho | modeNl,0,&lc);
 
 char *infoThis =
 {
-"SOAAP BLE Slave Version 22.09.25-1\r\n"
-"c0  Abschalten der periodischen Meldung\r\n"
-"c1  Auslesen BlePoll-Debug-Register\r\n"
-"c2  Steuern/Analysieren des Polling\r\n"
-"c3  Steuern/Analysieren der Messwerterfassung\r\n"
-"c4  Temporäre lokale Tests\r\n"
+    "SOAAP BLE Slave Version 22.09.25-1\r\n"
+    "c0  Abschalten der periodischen Meldung\r\n"
+    "c1  Auslesen BlePoll-Debug-Register\r\n"
+    "c2  Steuern/Analysieren des Polling\r\n"
+    "c3  Steuern/Analysieren der Messwerterfassung\r\n"
+    "c4  Testen von Peripheriezugriffen\r\n"
+    "c5  Temporäre lokale Tests\r\n"
 };
 
 #endif
@@ -145,8 +146,19 @@ SensorLSM9DS1 sens((IntrfTw *) &twi, SensorCycle);
 ProcMeas proc((IntrfMeas *) &sens);
 // Vorauswertung der Messwerte
 
+GpioExtRef  LedRot;
+// Handle für den Zugriff auf eine rote LED an Pin D11
+GpioExtRef  LedGreen;
+// Handle für die grüne LED auf dem Nano Board
+
 nRF52840Gpio  gpio;
-// Zugriff auf die Anschlüsse des Board
+// Zugriff auf die digitalen Anschlüsse des Board
+
+#define GpioCycleTime 500
+// Zykluszeit (in Mikrosekunden) bei der Ansteuerung digitaler I/Os
+
+GpioCtrl  ioCtrl((IntrfGpio *) &gpio, GpioCycleTime);
+// Instanz zur Ansteuerung der Peripherie (Blinken, etc.)
 
 bool getValues(PlpType plpType, byte *dest);
 // Vorwärtsreferenz für Datenübergabe
@@ -155,12 +167,22 @@ bool xchgCtrl(PlpType plpType, byte *dest, byte *src, int sSize);
 // Vorwärtsreferenz für Steuerungsaustausch
 
 nRF52840Adc   adc;
+// Anwendung des A/D-Wandlers
 
 void setup()
 {
   TwiParams   twiPar;       // Parameter für den I2C-Bus
 
-  gpio.configArd(ArdA0A3, IfDrvInput | IfDrvPullUp);
+  // Einschalten der roten LED (am Pin D11 des Arduino-Board)
+  // bei der SOAAP-Anwendung
+  //
+  gpio.config(ArdD11, IfDrvOutput | IfDrvOpenDrain | IfDrvStrongLow, &LedRot);
+  //ioCtrl.blink(&LedRot, 0, 2, 998, true);
+  ioCtrl.blink(&LedRot, 0, 2, 200, 398, 2, true);
+
+  // Ausschalten der grünen LED (auf dem Arduino-Board)
+  //
+  gpio.config(ArdLedGn, IfDrvInput, &LedGreen);
 
 #ifdef DebugTerminal
   mon.config(6);    // 6 Anzeigekanäle, die von ArduinoMonTerm aufgebaut werden
@@ -268,18 +290,23 @@ void loop()
   if(lc.timerMicro(lcTimer2, ProcMeasCycle, 0))
     proc.run();
 
+  // Alle 500 Mikrosekunden erfolgt der Aufruf der Peripheriesteuerung
+  //
+  if(lc.timerMicro(lcTimer3, GpioCycleTime, 0))
+    ioCtrl.run();
+
 #ifdef DebugTerminal
   // Alle 5 Millisekunden wird die Zustandsmaschine für
   // betriebliche Abläufe aufgerufen
   //
-  if(lc.timerMilli(lcTimer3, smCycleTime, 0))
+  if(lc.timerMilli(lcTimer4, smCycleTime, 0))
   {
     sm.run();
   }
 
   // Jede halbe Sekunde erfolgt die Ausgabe der Version
   //
-  if(lc.timerMilli(lcTimer4, 500, 0))
+  if(lc.timerMilli(lcTimer5, 500, 0))
   {
     if(!mon.cFlag[0])
     {
@@ -455,6 +482,8 @@ void smCheckJobs()
   else if(mon.cFlag[3] && !mon.busy)
     sm.enter(smCheckSens);
   else if(mon.cFlag[4] && !mon.busy)
+    sm.enter(smTestIO);
+  else if(mon.cFlag[5] && !mon.busy)
     sm.enter(smTempTesting);
 }
 
@@ -1124,7 +1153,43 @@ void smSensGetRunCounts()
 }
 
 // ----------------------------------------------------------------------------
-// (4) Temporäres Testen lokaler Speicher und Funktionen
+// (4) Testen von Peripheriezugriffen
+// ----------------------------------------------------------------------------
+//
+
+void smTestIO()
+{
+  if(sm.firstEnter())
+  {
+    mon.print((char *) "Testen der Peripheriezugriffe ");
+    mon.lastKeyIn = ':';
+  }
+
+  if(mon.lastKeyIn == ':') return;
+
+  charOut[0] = mon.lastKeyIn;
+  charOut[1] = '\0';
+  mon.println(charOut);
+
+  if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ')
+  {
+    mon.cFlag[4] = false;
+    mon.print((char *) "-- Schleifenabbruch - drücke Enter");
+    sm.enter(smCheckJobs);
+  }
+  else if(mon.lastKeyIn == 's' || mon.lastKeyIn == 'S')
+  {
+    mon.print("ConfStru = ");
+    mon.print((byte *) &LedRot.ioPtr,4,' ');
+    mon.print(" /  ");
+    mon.println((byte *) &LedRot.pins,4,' ');
+  }
+  sm.resetEnter();
+}
+
+
+// ----------------------------------------------------------------------------
+// (5) Temporäres Testen lokaler Speicher und Funktionen
 // ----------------------------------------------------------------------------
 //
 
@@ -1144,7 +1209,7 @@ void smTempTesting()
 
   if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ')
   {
-    mon.cFlag[4] = false;
+    mon.cFlag[5] = false;
     mon.print((char *) "-- Schleifenabbruch - drücke Enter");
     sm.enter(smCheckJobs);
   }