Difference between revisions of "DFF4.1"

From KONNEKTING Wiki
Jump to navigation Jump to search
(→‎Help: added details on how to find error with non-switching relais.)
 
Line 99: Line 99:
  
 
// MCP23017 Output register<->pin map
 
// MCP23017 Output register<->pin map
#define OA0 0
+
#define GPA0 0 // E 1
#define OA1 1
+
#define GPA1 1 // E 0
#define OA2 2
+
#define GPA2 2
#define OA3 3
+
#define GPA3 3
#define OA4 4
+
#define GPA4 4
#define OA5 5
+
#define GPA5 5
#define OA6 6
+
#define GPA6 6
#define OA7 7
+
#define GPA7 7
#define OB0 8
+
#define GPB0 8
#define OB1 9
+
#define GPB1 9
#define OB2 10
+
#define GPB2 10 // B 0
#define OB3 11
+
#define GPB3 11 // B 1
#define OB4 12
+
#define GPB4 12 // C 0
#define OB5 13
+
#define GPB5 13 // C 1
#define OB6 14
+
#define GPB6 14 // D 0
#define OB7 15
+
#define GPB7 15 // D 1
  
 +
#define A_SET  GPB1
 +
#define A_RESET GPB0
  
#define A_SET   OB1
+
#define B_SET   GPB3
#define A_RESET OB0
+
#define B_RESET GPB2
  
#define B_SET   OB3
+
#define C_SET   GPB5
#define B_RESET OB2
+
#define C_RESET GPB4
  
#define C_SET   OB5
+
#define D_SET   GPB7
#define C_RESET OB4
+
#define D_RESET GPB6
  
#define D_SET   OB7
+
#define E_SET   GPA0
#define D_RESET OB6
+
#define E_RESET GPA1
  
#define E_SET   OA0
+
#define F_SET   GPA2
#define E_RESET OA1
+
#define F_RESET GPA3
  
#define F_SET   OA2
+
#define G_SET   GPA4
#define F_RESET OA3
+
#define G_RESET GPA5
  
#define G_SET   OA4
+
#define H_SET   GPA6
#define G_RESET OA5
+
#define H_RESET GPA7
  
#define H_SET  OA6
+
boolean state[16];
#define H_RESET OA7
 
  
 
void setup() {
 
void setup() {
 +
  
 
   SerialUSB.begin(115200);
 
   SerialUSB.begin(115200);
 +
  while (!SerialUSB) {
 +
    delay(100);
 +
  }
  
 
   SerialUSB.println("SetupMCP Relais Test ...");
 
   SerialUSB.println("SetupMCP Relais Test ...");
Line 157: Line 162:
 
   for (int i = 0; i < 16; i++) {
 
   for (int i = 0; i < 16; i++) {
 
     mcp.pinMode(i, OUTPUT);
 
     mcp.pinMode(i, OUTPUT);
 +
    state[i]=false;
 +
    setMCP(i, false);
 
   }
 
   }
  
  pulseMCP(A_RESET);
+
//#define D 100
  pulseMCP(B_RESET);
 
  pulseMCP(C_RESET);
 
  pulseMCP(D_RESET);
 
  pulseMCP(E_RESET);
 
  pulseMCP(F_RESET);
 
  pulseMCP(G_RESET);
 
  pulseMCP(H_RESET);
 
  
  
 
   SerialUSB.println("... done");
 
   SerialUSB.println("... done");
 +
  digitalWrite(LED, LOW);
  
 
   // initial delay
 
   // initial delay
Line 184: Line 185:
  
 
String cmd;
 
String cmd;
 +
 +
char c[4];
 +
 +
  
 
void loop() {
 
void loop() {
Line 189: Line 194:
 
   cmd = SerialUSB.readStringUntil('\n');
 
   cmd = SerialUSB.readStringUntil('\n');
  
   if (cmd.length() > 0) {
+
   if (cmd.length() == 2) {
 +
 
 
     SerialUSB.print("Command: ");
 
     SerialUSB.print("Command: ");
 
     SerialUSB.println(cmd);
 
     SerialUSB.println(cmd);
Line 242: Line 248:
  
 
     SerialUSB.println("\n\nWaiting for command...[a-h0-1]");
 
     SerialUSB.println("\n\nWaiting for command...[a-h0-1]");
 +
 +
  } else if (cmd.length() == 4) {
 +
    SerialUSB.print("Command: ");
 +
    SerialUSB.println(cmd);
 +
 +
    if (cmd == "gpa0") {
 +
      state[GPA0] = !state[GPA0];
 +
      setMCP(GPA0, state[GPA0gpb5]);
 +
    } else
 +
    if (cmd == "gpa1") {
 +
      state[GPA1] = !state[GPA1];
 +
      setMCP(GPA1, state[GPA1]);
 +
    } else
 +
    if (cmd == "gpa2") {
 +
      state[GPA2] = !state[GPA2];
 +
      setMCP(GPA2, state[GPA2]);
 +
    } else
 +
    if (cmd == "gpa3") {
 +
      state[GPA3] = !state[GPA3];
 +
      setMCP(GPA3, state[GPA3]);
 +
    } else
 +
    if (cmd == "gpa4") {
 +
      state[GPA4] = !state[GPA4];
 +
      setMCP(GPA4, state[GPA4]);
 +
    } else
 +
    if (cmd == "gpa5") {
 +
      state[GPA5] = !state[GPA5];
 +
      setMCP(GPA5, state[GPA5]);
 +
    } else
 +
    if (cmd == "gpa6") {
 +
      state[GPA6] = !state[GPA6];
 +
      setMCP(GPA6, state[GPA6]);
 +
    } else
 +
    if (cmd == "gpa7") {
 +
      state[GPA7] = !state[GPA7];
 +
      setMCP(GPA7, state[GPA7]);
 +
    } else
 +
    if (cmd == "gpb0") {
 +
      state[GPB0] = !state[GPB0];
 +
      setMCP(GPB0, state[GPB0]);
 +
    } else
 +
    if (cmd == "gpb1") {
 +
      state[GPB1] = !state[GPB1];
 +
      setMCP(GPB1, state[GPB1]);
 +
    } else
 +
    if (cmd == "gpb2") {
 +
      state[GPB2] = !state[GPB2];
 +
      setMCP(GPB2, state[GPB2]);
 +
    } else
 +
    if (cmd == "gpb3") {
 +
      state[GPB3] = !state[GPB3];
 +
      setMCP(GPB3, state[GPB3]);
 +
    } else
 +
    if (cmd == "gpb4") {
 +
      state[GPB4] = !state[GPB4];
 +
      setMCP(GPB4, state[GPB4]);
 +
    } else
 +
    if (cmd == "gpb5") {
 +
      state[GPB5] = !state[GPB5];
 +
      setMCP(GPB5, state[GPB5]);
 +
    } else
 +
    if (cmd == "gpb6") {
 +
      state[GPB6] = !state[GPB6];
 +
      setMCP(GPB6, state[GPB6]);
 +
    } else
 +
    if (cmd == "gpb7") {
 +
      state[GPB7] = !state[GPB7];
 +
      setMCP(GPB7, state[GPB7]);
 +
    }
 +
   
 
   }
 
   }
 +
}
  
 +
void setMCP(int i, boolean s){
 +
  SerialUSB.print("Set addr #");
 +
  SerialUSB.print(i);
 +
  SerialUSB.print(" to ");
 +
  SerialUSB.println(s);
 +
  mcp.digitalWrite(i, s);
 
}
 
}
  
Line 258: Line 341:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
If there are relais that do not switch, follow these steps:
 +
 +
# Set MCP IO pin one by one and check if voltage (0V vs. 3.3V) can be measured between MCP IC and ULN2803 IC.
 +
# Measure also the voltage on ULN2803 output pin.
  
 +
If MCP fires 0V (low), ULN should almost show 5V (typically 4.8V) on output. If MCP fires 3.3V (high) the ULN output voltage will go down to almost 0V (low), but typically 0.7V. If itÄs 0.9V, it will work as well. But if voltage just drops to 1..1.5V, the ULN driver IC is bad and needs to be replaced. Make sure you use a genuine one and not a china-copy.
  
 
== Links ==
 
== Links ==
  
 
[[Category:Device/Kits]]
 
[[Category:Device/Kits]]

Latest revision as of 11:55, 20 February 2022

DFF4.1
DFF4.1 1.0.png
Developer Alexander Christian
Status Version 1.0 finished
Microcontroller/Board M0dularisM+
KNX connectivity Siemens BCU, Eugen's µBCU


Description

The purpose of this actuator is, to control Roto Rototronic skylight with shutters and/or sun blinds. It has 4 "channels". Each channel internally uses two relays: One for the open-action, and one for the close-action.

Of course you can also control your Roto Rototronic skylight with help of a standard switch-actuator. But then you don't have the possibility to "open the window 75%" or "close the shutter 80%". The firmware for DFF4.1 provides all this neat feature that you know from typical shutter/blinds actuators.

Hardware

This actuator consists of the following REG parts:

I2C address on application board:

A0: 1
A1: 0 
A2: 0

I2C address on frontend board:

A0: 0
A1: 0
A2: 0


Software

User Documentation

Check here for the DFF4.1 User Manual

Developer Documentation

Firmware sourcecode is on github: https://github.com/KONNEKTING/DFF4.1 Follow this guide for updating the firmare from source-code: KONNEKTING USB Firmware Update

Get a DIY kit

You are interested in this actuator? Great! This device is available as a DIY kit.

The kit includes all required parts with pre-soldered SMD parts and pre-flashed controller board.

You only need:

  • soldering iron and solder
  • a screw driver
  • a sharp knife with a fine tip
  • a working KNX installation where you can connect the device to
  • ~2-3hrs to build it according to the build instructions linked on this page
  • a computer: Windows, Linux or MAC that is able to run KONNEKTING Suite plus a KNX IP Interface or an KNX IP Router.
  • for updating the firmware: A Mini USB cable (Not Micro-USB like on your smartphone. Mini USB is a big thicker as Micro USB)

Please write a mail to info@konnekting.de and refer to this page.

Build It

This actuator uses three PCBs, a bunch of SMD components as well as a lot of mechanical parts. As most users are not able to solder SMD, the PCBs are pre-soldered with all SMD components. Due to the big amount of parts, this actuator comes as a DIY kit: You have to solder non-SMD parts yourself and build up the device and finally flash the firmware with help of a USB connection.

Check here for the DFF4.1 Building Instructions

Help

If relays do not work as expected, you can run this test-sketch to be able to switch relais by serial console. Commands follow this syntax (\n = LF/LineFeed/NewLine):

[a-h0-1]\n

f.i. "a0" disables relay A, "f1" enables relay F On startup all relays are disabled. It is recommended to use this test without attached window/shutter, but with am multimeter/continuity-tester to be able to test relay by relay.

  1#include <Wire.h>
  2#include <Adafruit_MCP23017.h>
  3
  4Adafruit_MCP23017 mcp;
  5#define LED A5
  6#define EN A0
  7
  8// MCP23017 Output register<->pin map
  9#define GPA0 0 // E 1
 10#define GPA1 1 // E 0 
 11#define GPA2 2
 12#define GPA3 3
 13#define GPA4 4
 14#define GPA5 5
 15#define GPA6 6
 16#define GPA7 7
 17#define GPB0 8
 18#define GPB1 9
 19#define GPB2 10 // B 0
 20#define GPB3 11 // B 1
 21#define GPB4 12 // C 0
 22#define GPB5 13 // C 1
 23#define GPB6 14 // D 0
 24#define GPB7 15 // D 1
 25
 26#define A_SET   GPB1
 27#define A_RESET GPB0
 28
 29#define B_SET   GPB3
 30#define B_RESET GPB2
 31
 32#define C_SET   GPB5
 33#define C_RESET GPB4
 34
 35#define D_SET   GPB7
 36#define D_RESET GPB6
 37
 38#define E_SET   GPA0
 39#define E_RESET GPA1
 40
 41#define F_SET   GPA2
 42#define F_RESET GPA3
 43
 44#define G_SET   GPA4
 45#define G_RESET GPA5
 46
 47#define H_SET   GPA6
 48#define H_RESET GPA7
 49
 50boolean state[16];
 51
 52void setup() {
 53
 54
 55  SerialUSB.begin(115200);
 56  while (!SerialUSB) {
 57    delay(100);
 58  }
 59
 60  SerialUSB.println("SetupMCP Relais Test ...");
 61
 62  pinMode(LED, OUTPUT);
 63  pinMode(EN, OUTPUT);
 64  digitalWrite(LED, HIGH);
 65  digitalWrite(EN, HIGH);
 66
 67
 68  mcp.begin(1);
 69
 70  for (int i = 0; i < 16; i++) {
 71    mcp.pinMode(i, OUTPUT);
 72    state[i]=false;
 73    setMCP(i, false);
 74  }
 75
 76//#define D 100
 77
 78
 79  SerialUSB.println("... done");
 80  digitalWrite(LED, LOW);
 81
 82  // initial delay
 83  delay(1000);
 84  SerialUSB.println("Initial delay done.");
 85  SerialUSB.println("Waiting for command...[a-h0-1]");
 86}
 87
 88//84
 89#define WAIT_TIME 84
 90
 91//16
 92#define SET_TIME 16
 93
 94String cmd;
 95
 96char c[4];
 97
 98
 99
100void loop() {
101
102  cmd = SerialUSB.readStringUntil('\n');
103
104  if (cmd.length() == 2) {
105
106    SerialUSB.print("Command: ");
107    SerialUSB.println(cmd);
108
109    if (cmd == "a1") {
110      pulseMCP(A_SET);
111    } else if (cmd == "a0") {
112      pulseMCP(A_RESET);
113    }
114
115    else if (cmd == "b1") {
116      pulseMCP(B_SET);
117    } else if (cmd == "b0") {
118      pulseMCP(B_RESET);
119    }
120
121    else if (cmd == "c1") {
122      pulseMCP(C_SET);
123    } else if (cmd == "c0") {
124      pulseMCP(C_RESET);
125    }
126
127    else if (cmd == "d1") {
128      pulseMCP(D_SET);
129    } else if (cmd == "d0") {
130      pulseMCP(D_RESET);
131    }
132
133    else if (cmd == "e1") {
134      pulseMCP(E_SET);
135    } else if (cmd == "e0") {
136      pulseMCP(E_RESET);
137    }
138
139    else if (cmd == "f1") {
140      pulseMCP(F_SET);
141    } else if (cmd == "f0") {
142      pulseMCP(F_RESET);
143    }
144
145    else if (cmd == "g1") {
146      pulseMCP(G_SET);
147    } else if (cmd == "g0") {
148      pulseMCP(G_RESET);
149    }
150
151    else if (cmd == "h1") {
152      pulseMCP(H_SET);
153    } else if (cmd == "h0") {
154      pulseMCP(H_RESET);
155    }
156
157    SerialUSB.println("\n\nWaiting for command...[a-h0-1]");
158
159  } else if (cmd.length() == 4) {
160    SerialUSB.print("Command: ");
161    SerialUSB.println(cmd);
162
163    if (cmd == "gpa0") {
164      state[GPA0] = !state[GPA0];
165      setMCP(GPA0, state[GPA0gpb5]);
166    } else 
167    if (cmd == "gpa1") {
168      state[GPA1] = !state[GPA1];
169      setMCP(GPA1, state[GPA1]);
170    } else 
171    if (cmd == "gpa2") {
172      state[GPA2] = !state[GPA2];
173      setMCP(GPA2, state[GPA2]);
174    } else 
175    if (cmd == "gpa3") {
176      state[GPA3] = !state[GPA3];
177      setMCP(GPA3, state[GPA3]);
178    } else 
179    if (cmd == "gpa4") {
180      state[GPA4] = !state[GPA4];
181      setMCP(GPA4, state[GPA4]);
182    } else 
183    if (cmd == "gpa5") {
184      state[GPA5] = !state[GPA5];
185      setMCP(GPA5, state[GPA5]);
186    } else 
187    if (cmd == "gpa6") {
188      state[GPA6] = !state[GPA6];
189      setMCP(GPA6, state[GPA6]);
190    } else 
191    if (cmd == "gpa7") {
192      state[GPA7] = !state[GPA7];
193      setMCP(GPA7, state[GPA7]);
194    } else
195    if (cmd == "gpb0") {
196      state[GPB0] = !state[GPB0];
197      setMCP(GPB0, state[GPB0]);
198    } else 
199    if (cmd == "gpb1") {
200      state[GPB1] = !state[GPB1];
201      setMCP(GPB1, state[GPB1]);
202    } else 
203    if (cmd == "gpb2") {
204      state[GPB2] = !state[GPB2];
205      setMCP(GPB2, state[GPB2]);
206    } else 
207    if (cmd == "gpb3") {
208      state[GPB3] = !state[GPB3];
209      setMCP(GPB3, state[GPB3]);
210    } else 
211    if (cmd == "gpb4") {
212      state[GPB4] = !state[GPB4];
213      setMCP(GPB4, state[GPB4]);
214    } else 
215    if (cmd == "gpb5") {
216      state[GPB5] = !state[GPB5];
217      setMCP(GPB5, state[GPB5]);
218    } else 
219    if (cmd == "gpb6") {
220      state[GPB6] = !state[GPB6];
221      setMCP(GPB6, state[GPB6]);
222    } else 
223    if (cmd == "gpb7") {
224      state[GPB7] = !state[GPB7];
225      setMCP(GPB7, state[GPB7]);
226    } 
227    
228  }
229}
230
231void setMCP(int i, boolean s){
232  SerialUSB.print("Set addr #");
233  SerialUSB.print(i);
234  SerialUSB.print(" to ");
235  SerialUSB.println(s);
236  mcp.digitalWrite(i, s);
237}
238
239void pulseMCP(int i) {
240  SerialUSB.print("Pulse at addr #");
241  SerialUSB.print(i);
242
243  mcp.digitalWrite(i, HIGH);
244  delay(SET_TIME);
245  mcp.digitalWrite(i, LOW);
246  delay(WAIT_TIME);
247  SerialUSB.println(" *DONE*");
248}

If there are relais that do not switch, follow these steps:

  1. Set MCP IO pin one by one and check if voltage (0V vs. 3.3V) can be measured between MCP IC and ULN2803 IC.
  2. Measure also the voltage on ULN2803 output pin.

If MCP fires 0V (low), ULN should almost show 5V (typically 4.8V) on output. If MCP fires 3.3V (high) the ULN output voltage will go down to almost 0V (low), but typically 0.7V. If itÄs 0.9V, it will work as well. But if voltage just drops to 1..1.5V, the ULN driver IC is bad and needs to be replaced. Make sure you use a genuine one and not a china-copy.

Links