Documente Academic
Documente Profesional
Documente Cultură
78F053X
TxD D3 / EVB14
TP-UART RxD D4 / EVB10
+Bus E1/EVB25
-Bus E2/EVB26
BIM M13x
VCC - D2 / EVB18
VDD - D1 / EVB22
470
78F053X
LED
TxD D3 / EVB14
TP-UART RxD D4 / EVB10
+Bus E1/EVB25
GND
-Bus E2/EVB26
Connect a LED + resistor between test pin 3 and GND of the BIM M13x Evaluation Board.
- Test pin 3 is T3 of JP4 (TEST pins).
- The test pins are not available on regular BIM M13x devices.
- GND is pin 24 of JP2 (BIM Connector).
Compile the sample project contained in: Opternus_Example1-v01.zip
GO0 toggles test pin 3, this GO is by default associated with GA = 0/0/1.
Send GroupData telegrams for GO0 e.g. with ETS Group Monitor.
- Value = 0 (off) should switch off the LED.
- Value = 1 (on) should switch on the LED.
BIM M13x
78F053X
LED
TxD D3 / EVB14
TP-UART RxD D4 / EVB10
+Bus E1/EVB25
GND
-Bus E2/EVB26
Connect a LED + resistor between I/O port P70 and GND of the BIM M13x Evaluation Board.
- P70 is pin 7 of JP2 (BIM Connector), on regular BIM M13x devices P70 is pin B5.
- GND is pin 24 of JP2 (BIM Connector), on regular BIM M13x devices GND is pin C1.
Compile the sample project contained in: Opternus_Example2-v01.zip
The LED can be activated via GO0, which by default is associated with GA = 0/0/1.
- Value = 0 (off) should switch the LED off.
- Value = 1 (on) should make the LED toggle.
The toggle frequency = 1/ (toggle time * toggle factor).
- The Toggle Time is set to 100 ms.
- Toggle factor = 0 means that the LED is continuously lit.
The toggle factor is stored as parameter in the memory of the device (EEPROM).
The toggle factor can be changed via GO1, which by default is associated with GA = 0/0/2.
- E.g. value = 5 will make the LED toggle 2 times per second when activated.
- E.g. value = 10 will make the LED toggle each second when activated.
BIM M13x
78F053X
GND
Connect a push button between I/O port P77 and GND of the BIM M13x Evaluation Board.
- P77 is pin 13 of JP2 (BIM Connector), on regular BIM M13x devices P77 is pin A3.
- GND is pin 24 of JP2 (BIM Connector), on regular BIM M13x devices GND is pin C1.
Compile the sample project contained in: Opternus_Example3-v01.zip
The push button events will be propagated via GO0 onto the bus.
- GO0 by default is associated with GA = 0/0/1.
- Each push button event makes the value of GO0 toggle.
P77 initialization:
- P77 is set as output port.
- The pull-up resistor of P77 is set, which makes the value of P77 become logically 1.
The push button events are detected as follows:
- After each AP loop (3.3 ms) the value of P77 is evaluated.
- If the value of P77 = 0 (logically) it means that the button was pushed.
- The value of GO0 is toggled and sent to the bus.
- A timer (200 ms) is started in order to debounce the push button events.
P77 is after each push button event reset as follows:
- Set P77 as input.
- Set P77 as output.
- Set the pull-up resistor of P77, which makes the value of P77 become logically 1 again.
BIM M13x
I/O pin 2
78F053X
+Bus E1/EVB25
Arduino UNO
-Bus E2/EVB26
LED
GND
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(19200, SERIAL_8E1);
}
void loop()
{
if (Serial.available())
{
incomingByte = Serial.read();
for(int i=0;i<maxLen;i++)
msg[i] = 0;
}
if(msgState==1)
{
msg[msgCntr++] = incomingByte;
if(msgCntr==2)
msgLen = incomingByte + 6;
if(msgCntr==msgLen)
{
if(incomingByte==0x16)
{
msgState = 0;
digitalWrite(ledPin, msg[6]);
Serial.write(0xE5); //ACK
}
}
}
}
}
BIM M13x
VCC
+Bus E1/EVB25
Arduino UNO
-Bus E2/EVB26
Push
Button
GND
void setup()
{
pinMode(buttonPin, INPUT);
Serial.begin(19200,SERIAL_8E1);
}
void loop()
{
if ((millis() - lastDebounceTime) > debounceDelay)
{
buttonState = digitalRead(buttonPin);
lastDebounceTime = millis();
TM = 1;
}
if ((TM == 1) && (buttonState == LOW))
{
if (KNXoutput == LOW)
{
KNXoutput = HIGH;
for(i=0; i < 9; i++)
Serial.write(msg_odd_1[i]);
}
else
{
KNXoutput = LOW;
for(i=0; i < 9; i++)
Serial.write(msg_even_0[i]);
}
buttonState = HIGH;
TM = 0;
}
}
PEI
KNX Stack:
KNX
PEI
The AP:
KNX
/******************************************************************************/
// parameter: ToggleFactor
// used for TimerTicks = ToggleFactor * TOGGLETIME
#pragma constseg = PARAM
__root const BYTE ToggleFactor;
void AppInit(void)
{
// after initialization a taskswitch is required because
// the task switch is disabled at cstartup
U._TmInit(NUM_OF_TIMERS);
/* set the status of the output (P70) to 'not active' (no toggling) */
P70_status = 0xff;
/* set the initial toggle factor value according to the memory parameter */
/* toggle factor = 0 means that the LED is lit continously when active */
param0 = ToggleFactor;
FORCE_TASKSWITCH();
}
//------------------------------------------------------------------------
// this is the main function of the application program
// it is called at the end of cstartup
//------------------------------------------------------------------------
void main (void)
{
// initialization
for(;;)
{
/* activate or deactivate the output(P70) via GO0 */
if (U._TestAndCopyObject(COM_OBJ0, &Data_Obj0, 1) == TRUE)
{
if (Data_Obj0 == 0)
{
P7 reset_bit BIT0; /* deactivate the output */
P70_status = 0xff;
U._TmStop(&UserTimerTab.Timers[0]);
}
else
{
P7 set_bit BIT0; /* activate the output */
P70_status = 0x01;
U._TmStart(&UserTimerTab.Timers[0], TOGGLETIME * param0);
}
}
if (P70_status != 0xff)
U._TmAddStart(&UserTimerTab.Timers[0], TOGGLETIME * param0);
}
}
}
//------------------------------------------------------------------------
// this function is called @ power loss
//------------------------------------------------------------------------
void save()
{
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// the application info block contains
// information required for the operating system
//------------------------------------------------------------------------
#pragma constseg = APPINFOBLOCK
const AppInfoBlock AIB =
{
Swap(0x0001), // AIBVersion
0x01, 0x01, // ApplFirmwareVersion, ApplFirmwareSubVersion
__program_start, // AppMain
save, // AppSave
unload, // AppUnload
CObjects, // pCObjects
RAMFlags, // pRAMFlags
&UserTimerTab, // pUserTimerTab
NULL, // pUsrIntObjRoot
NULL, // pUsrParamMgmt
0x0000 // WatchDogTime
};
#pragma constseg = default
This reserves the required RAM for the GOs of this AP: flags + values.
This is the operational (live) data for the GOs.
The actual definitions of the GOs are stored in EEPROM and will be set up in tables.c (see further)
in the resource called Object Table.
The address of RAMFlags needs to be specified in the Application Info Block.
BYTE P70_status; /* status of the output (P70) */
BYTE param0; /* to store the value of the toggle factor */
This reserves the required RAM in order to store the status of P70 and the toggle factor.
The exact memory locations depend on the settings stored in BIM_M_130.xcl.
#pragma constseg = PARAM
__root const BYTE ToggleFactor;
This reserves the required EEPROM in order to store the toggle factor.
This reserves the necessary EEPROM in order to store/set up a table, which consists of:
- a pointer to where the number of GOs is stored, this is a pointer to EEPROM
- pointers to where the GO values are stored, these are pointers to RAM.
The address of GObjects needs to be specified in the Application Info Block.
#pragma constseg = APPINFOBLOCK
const AppInfoBlock AIB =
{
Swap(0x0001), // AIBVersion
0x01, 0x01, // ApplFirmwareVersion, ApplFirmwareSubVersion
__program_start, // AppMain
save, // AppSave
unload, // AppUnload
CObjects, // pCObjects
RAMFlags, // pRAMFlags
&UserTimerTab, // pUserTimerTab
NULL, // pUsrIntObjRoot
NULL, // pUsrParamMgmt
0x0000 // WatchDogTime
};
This reserves the necessary EEPROM in order to store the Application Info Block.
This information stores amongst others:
- the starting address of the AP
- pointers to the save & unload routines
- pointer to the RAM flags
- pointer to the table containing the GO value pointers (= GObjects)
};
#pragma constseg = default
This reserves the required EEPROM for the Address Table of this AP.
- The first two bytes are reserved for the Individual Address IA of the BCU.
- The last byte is always 0x00 in order to indicate the end of this table.
- The GAs for this AP are stored between the IA and the end of table byte.
- In case the AP requires more GAs, they need to be added between the IA and the last byte, two
bytes per extra GA.
#pragma constseg = ASSOCTAB
__root const BYTE AssTab[] =
{ NUM_OF_COM_OBJ + 0, // for debug: one association per communication object
// grp.addr., comobj. num.,
0x01, 0x00,
0x02, 0x01,
0x00 // padding
};
This reserves the required EEPROM for the Association Table of this AP.
This table defines the links between the GAs and the GOs.
The last byte is always 0x00 in order to indicate the end of this table.
Each association contains two bytes:
- first = index of the GA in the Address Table
- second = index of the GO in the Object Table.
In case the AP requires more associations, they need to be added before the end of table byte, two
bytes per extra association.
};
This reserves the required EEPROM for the Object Table of this AP.
This table contains the actual definitions of the individual GOs.
- The first byte contains the number of GOs.
- The second byte is reserved and needs to be set to 0x00 (because of compatibility reason).
Each GO definition contains 3 bytes
- The first byte is not used (set to NULL).
- The second byte is the config byte; it is used to define the communication flags (CRWTU) and
the priority (system, high, low, normal).
- Third byte defines the type (length) of the GO.
#define NUM_OF_TIMERS 1
#define NUM_OF_COM_OBJ 2
#define COM_OBJ0 0
#define COM_OBJ1 1
#endif
/********************************************************************\
|* C O D E *|
\********************************************************************/
-Z(CODE)PARAM=9C00-9FFF
-Z(CODE)COMTAB=8190-81FF
-Z(CODE)ASSOCTAB=8140-818F
-Z(CODE)ADDRTAB=8116-813F
-Z(CODE)APPINFOBLOCK=8000-8115
-Z(CODE)ROOTCODE=7800-7FFF
/********************************************************************/
-Z(CODE)BCU2_JMP=7700-77FF
5.5 Debug
Make sure that the Debug option is selected in the Workspace window.
Select Project/Make via the menu to compile and link the project.
Select Project/Debug via the menu in order to start the preparations for a debug session.
Select Debug/Go via the menu to actually start the AP.
This AP should as such work and does not require any real debugging unless you would like to test it with
other (hard-coded) GAs as the ones specified in the Address Table.
5.6 Release
Make sure that the Release option is selected within the Workspace window.
Select Project/Make via the menu to build the project; this will create the file
BIM_M_130_Template.map in the Release\List folder of this project.
As its content is too large to be copied here, only the most important part is shown here.
-------------------------------------------------------------------------
PARAM
Relative segment, address: 9C00 - 9C00 (0x1 bytes), align: 0
Segment part 13. ROOT. Intra module refs: AppInit
ENTRY ADDRESS REF BY
===== ======= ======
ToggleFactor 9C00
-------------------------------------------------------------------------
As such this file is correct but not usable for the MT, as it needs to be modified first.
This can be done automatically via a Post-build command line, by doing the following.
Click Project/Options
Click Build Actions
Copy this: C:\Program Files\Siemens AG\BIM Tools\aioc.exe -t modifier --targs Template_130
"$PROJ_DIR$\config.xml" "$PROJ_DIR$\Release\Exe\BIM_M_130_Template.s19"
"$PROJ_DIR$\Release\Exe\BIM_M_130_Template_mod.s19" into the Post-build command line field.
Building the project will from now on create two extra files in the Release\Exe folder of this project:
BIM_M_130_Template_mod.log, and
BIM_M_130_Template_mod.s19.
BIM_M_130_Template_mod.s19 is the actual modified s19 file and is directly usable (via import) in the
MT. This is its content:
S00F000054656D706C6174655F313330C1
S113000000F00000000000000000000000000000FC
S113E800000101010082CA83CB83029C08FB00FB48
S109E810000000000000FE
S10B01160311FD0001000200C9
S1090140020100020100AF
S10B01900200005F00005F079C
S1130200712AE661D01600FB100E00D23261613211
S1130210AD0143617197868AFC8BFA020080021655
S1130220810240810290819AD382B5B7D410000034
S1130230B1B1891CD6C2A220DE0D25DE0DDE0C254F
S1130240DE0CDE0B25DE0BDE0A25DE0A9D170761B8
S11302500C07DE01612DDE01DE026128DE02DE0311
Not only the content of the first part has indeed been modified, it also has become longer, as the necessary
load controls have been added.
This is important as it is necessary to know where the parameters for the AP will be located in EEPROM.
The log file shows that the offset for the memory locations have been changed:
MEMORYCONVENTRY: 7800 <-> 8115 Offset: +6800
MEMORYCONVENTRY: 8116 <-> 9FFF Offset: -8000
that the actual location for this (ETS) parameters shall be calculated as 0x9C00 0x8000, i.e the address
for ToggleFactor is 0x1C00.
Connect
Wire the device.
Open the serial terminal software (see Figure 1).
Click tab page Port.
Select the virtual com port that has been added.
Put its settings to 9600, 8, 1, none.
Play
Click tab page Send.
Make sure to set EOL (end of line) settings to +CR.
Type e.g. dag in the top entry field and click Send ASCII. This command will ask the device to
send back its Individual Address. This is a perfect method to test the principal working of the test
setup.
Other commands that could be used in this context are: das, dpg, dps, dr, dsg, dvg, gci. Consult the
Tapko Technologies SIM-KNX related documentation for more details.
SIM-KNX
Galvanic Separation
Details:
Interface: serial ASCII protocol via TxD (pin 6) and RxD (pin 7).
For more details about the serial protocol, please consult the Tapko Technologies related SIM-
KNX documentation. URL: www.tapko.de
VCC
VCC
I/O pin 4
GND
10K
TX pin 1
Arduino UNO
Push
Button
GND
+Bus pin 4 TxD pin 6
SIM-KNX
Details:
Arduino UNO pin 4 serves as input port in order to capture push button events.
Arduino UNO pin 1 serves as serial transmit port, which is connected to RxD of the SIM-KNX.
A simple debounce routine is implemented in order to detect the push button events.
For each push button event an ASCII command is sent to the SIM-KNX.
void setup()
{
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop()
{
if ((millis() - lastDebounceTime) > debounceDelay)
{
buttonState = digitalRead(buttonPin);
lastDebounceTime = millis();
TM = 1;
}
if ((TM == 1) && (buttonState == LOW))
{
KNXoutput = !KNXoutput;
if (KNXoutput == LOW)
{
Serial.write("ovs(0)0");
Serial.write(13);
}
else
{
Serial.write("ovs(0)1");
Serial.write(13);
}
buttonState = HIGH;
TM = 0;
}
}
VCC
I/O pin 2
GND
RX pin 0 470
Arduino UNO
(*)
LED
74LVCC3245
(**)
+Bus pin 4 TxD pin 6
GND
-Bus pin 1 RxD pin 7
SIM-KNX
Details:
Arduino UNO pin 2 serves as simulation of a KNX binary output channel by means of a LED.
Arduino UNO pin 0 serves as serial receive port, which is connected to TxD of the SIM-KNX.
A simple serial port read routine is implemented in order to capture and process ASCII commands
from the SIM-KNX.
Depending on the actual content of each received ASCII command the LED will either be switched
on or off.
Remarks:
(*) The voltage translator 74LVCC3245 transfers the 3.3V TxD signal from the SIM-KNX into a 5V
RX signal for the Arduino UNO.
(**) Moreover, we even had to double-loop the connection between SIM-KNX TxD (pin 6) and the
voltage translator, around a clamp-on magnetic noise filter.
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(9600);
}
void loop()
{
if (Serial.available())
{
incomingByte = Serial.read();
for(int i=0;i<maxLen;i++)
msg[i] = 0;
}
if(msgState!=0 && msgCntr<maxLen)
{
msg[msgCntr++] = incomingByte;
Connect
Wire the device.
Open the serial terminal software (see Figure 1).
Click tab page Port.
Select the virtual com port that has been added.
Put its settings to 9600, 8, 1, none.
Play
Click tab page Send.
Make sure to set EOL (end of line) settings to +CR.
Type e.g. dag in the top entry field and click Send ASCII. This command will ask the device to
send back its Individual Address. This is a perfect method to test the principal working of the test
setup.
Other commands that could be used in this context are: das, dpg, dps, dr, dsg, dvg, gci. Consult the
Tapko Technologies SIM-KNX related documentation for more details.
SIM-KNX
Galvanic Separation
Details:
Interface: serial ASCII protocol via TxD (pin 6) and RxD (pin 7).
For more details about the serial protocol, please consult the Tapko Technologies related SIM-
KNX documentation. URL: www.tapko.de
VCC
GND
P2.0
P2.1
MSP-EXP430FR5739
SIM-KNX
Details:
TI C pin P2.0 serves as serial receive port, which is connected to TxD of the SIM-KNX.
TI C pin P2.1 serves as serial transmit port, which is connected to RxD of the SIM-KNX.
A simple debounce routine is implemented in order to detect the onboard push button P4.1 events.
For each push button event an ASCII command is sent to the SIM-KNX.
A simple serial port read routine is implemented in order to capture and process ASCII commands
from the SIM-KNX.
Depending on the actual content of each received ASCII command the onboard LED2 will either
be switched on or off.
#include "msp430fr5739.h"
#include <string.h>
#define MAXLEN 50
char rcv_buffer[MAXLEN];
int rcv_cntr;
char rcv_char;
int msgState;
int S1;
int S2;
int LED1;
int LED2;
void EnableSwitches(void)
{
P4IFG = 0; // P4 IFG cleared
P4IE = BIT0+BIT1; // P4 interrupt enabled
}
void DisableSwitches(void)
{
P4IFG = 0; // P4 IFG cleared
P4IE &= ~(BIT0+BIT1); // P4 interrupt disabled
P4IFG = 0; // P4 IFG cleared
}
void StartDebounceTimer(void)
{
// Debounce time = 1500 * 1/8000 = ~200ms
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 1500;
TA1CTL = TASSEL_1 + MC_1; // ACLK, up mode
}
void setLEDs(void)
{
// Enable LED1 & LED2
PJOUT &= ~(BIT0+BIT1);
PJDIR |= BIT0+BIT1;
LED1 = 0;
LED2 = 0;
}
void setSwitches(void)
{
// Set up switches S1 & S2
// P4.0 and P4.1 are configured as switches
// Port 4 has only two pins
P4OUT |= BIT0+BIT1; // Configure pullup resistor
P4DIR &= ~(BIT0+BIT1); // Direction = input
S1 = 0;
S2 = 0;
}
void setClock(void)
{
CSCTL0_H = 0xA5; // Unlock register
CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting
CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO
CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers
CSCTL0_H = 0x01; // Lock register
}
void setUart(void)
{
// Configure UART pins
P2SEL1 |= BIT0 + BIT1;
P2SEL0 &= ~(BIT0 + BIT1);
// Configure UART 0
UCA0CTL1 |= UCSWRST; // keep in reset mode
UCA0CTL1 = UCSSEL_2; // set SMCLK as UCLK
UCA0BR0 = 52; //9600 baud
UCA0BR1 = 0;
UCA0MCTLW |= 0x4911; // BRCLK = 8000000, UCBRFx = 1, UCBRSx = 0x49, UCOS16 = 1
UCA0CTL1 &= ~UCSWRST; // release from reset mode
UCA0IE |= UCRXIE; // Enable RX interrupt
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // stop watchdog
setLEDs();
setSwitches();
setClock();
setUart();
while(1)
{
__bis_SR_register(LPM4_bits + GIE); // low power mode4 + general interupt
__no_operation(); // For debugger
}
}
//**********************************************************************
//* Port 4 ISR for S1 & S2
//**********************************************************************
#pragma vector=PORT4_VECTOR
__interrupt void Port_4(void)
{
switch(__even_in_range(P4IV,0x04))
{
case 0x02: // P4.0 interrupt = S1
break;
DisableSwitches();
StartDebounceTimer();
break;
default:
break;
}
}
//**********************************************************************
//* Timer A1 ISR for debounce Timer
//**********************************************************************
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
{
TA1CCTL0 = 0;
TA1CTL = 0;
EnableSwitches();
}
//**********************************************************************
//* USCI (universal serial communication interfce) A0 ISR for RX
//**********************************************************************
#pragma vector = USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
switch(__even_in_range(UCA0IV,0x02))
{
case 0x02: // UCRXIFG = P2.1 = RX
rcv_char = UCA0RXBUF;
switch(rcv_char)
{
case 0x6f: // 'o'
if(msgState == 0)
{
msgState = 1;
rcv_cntr = 0;
}
strcpy(rcv_buffer, "");
rcv_cntr = 0;
msgState = 0;
}
break;
default:
if(msgState == 3 && rcv_cntr < MAXLEN)
rcv_buffer[rcv_cntr++] = rcv_char;
break;
}
break;
default: break;
}
}
Connect
Wire the device.
Open the serial terminal software (see Figure 1).
Click tab page Port.
Select the virtual com port that has been added.
Put its settings to 38400, 8, 1, none.
Play
Click tab page Send.
Make sure to set EOL (end of line) settings to +CR.
Type e.g. 03 61 0002 in the top entry field and click Send ASCII. This command will make the
device send back its individual address. This is a perfect method to test the principal working of the
test setup.
Screenshot:
KIMaip
(*)
+Bus pin 10 SDA pin 2
(*)
-Bus pin 9 SCL pin 3 External C
(**) DR pin 1
Details:
Interface: IC based ASCII protocol via SDA (pin 2) and SCL (pin 3).
For more details about the ASCII protocol, please consult the Tapko Technologies related KIMaip
documentation. URL: www.tapko.de
Important:
Depending on the external C it might be required to use pull-up resistors for SDA and SCL,
please carefully check the documentation of your external C.
VCC
VCC
I/O pin 4
GND
SDA pin A4
10K
SCL pin A5
Arduino UNO
Push
Button
GND
KIMaip
Details:
Arduino UNO pin 4 serves as input port in order to capture push button events.
Arduino UNO pin A4 serves as IC SDA port, which is connected to the KIMaip SDA.
Arduino UNO pin A5 serves as IC SCL port, which is connected to the KIMaip SCL.
A simple debounce routine is implemented in order to process the push button events.
For each push button event an ASCII command is sent to the KIMaip.
Important note:
For the Arduino Uno no pull-up resistors shall be used for SDA and SCL.
IC is based on a master-slave principle and KIMaip is always the slave device.
void setup()
{
pinMode(buttonPin, INPUT);
Wire.begin();
}
void loop()
{
if ((millis() - lastDebounceTime) > debounceDelay)
{
buttonState = digitalRead(buttonPin);
lastDebounceTime = millis();
TM = 1;
}
Arduino UNO
LED
GND
+Bus pin 10 SDA pin 2
KIMaip
Figure 6 Arduino UNO used as KNX Actuator
Details:
Arduino UNO pin 2 serves as simulation of a KNX binary output channel by means of a LED.
Arduino UNO pin A4 serves as IC SDA port, which is connected to the KIMaip SDA.
Arduino UNO pin A5 serves as IC SCL port, which is connected to the KIMaip SCL.
Arduino UNO pin 4 serves as Data Ready port, which is connected to the KIMaip Data Ready.
A simple IC read routine is implemented in order to capture and process ASCII commands from
the KIMaip.
Depending on the actual content of each received ASCII command the LED will either be switched
on or off.
Important notes:
For the Arduino Uno no pull-up resistors shall be used for SDA and SCL.
Since IC is based on a master-slave principle, where KIMaip is always the slave, the best practice
for using it as actuator is to involve the Data Ready pin in order to indicate bus events to the
master.
int msg[5];
int i = 0;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(dataReadyPin, INPUT);
Wire.begin();
}
void loop()
{
if ((millis() - lastDebounceTime) > debounceDelay)
{
dataReadyState = digitalRead(dataReadyPin);
lastDebounceTime = millis();
TM = 1;
}
dataReadyState = LOW;
TM = 0;
}
}
Connect
Wire the device.
Open the serial terminal software (see Figure 1).
Click tab page Port.
Select the virtual com port that has been added.
Put its settings to 38400, 8, 1, none.
Play
Click tab page Send.
Make sure to set EOL (end of line) settings to +CR.
Type e.g. 03 61 0002 in the top entry field and click Send ASCII. This command will make the
device send back its individual address. This is a perfect method to test the principal working of the
test setup.
Screenshot:
KIMaip
(*)
+Bus pin 10 SDA pin 2
(*)
-Bus pin 9 SCL pin 3 External C
(**) DR pin 1
Details:
Interface: IC based ASCII protocol via SDA (pin 2) and SCL (pin 3).
For more details about the ASCII protocol, please consult the Tapko Technologies related KIMaip
documentation. URL: www.tapko.de
Important:
Depending on the external C it might be required to use pull-up resistors for SDA and SCL,
please carefully check the documentation of your external C.
VCC
GND
P1.7
P1.6
MSP-EXP430FR5739
KIMaip
Details:
TI C pin P1.6 serves as IC SDA port, which is connected to the KIMaip SDA.
TI C pin P1.7 serves as IC SCL port, which is connected to the KIMaip SCL.
A simple debounce routine is implemented in order to detect the onboard push button P4.1 events.
For each push button event an ASCII command is sent to the KIMaip.
A simple IC read routine is implemented in order to capture and process ASCII commands from
the KIMaip.
Depending on the actual content of each received ASCII command the LED2 will either be
switched on or off.
Important note:
Since IC is based on a master-slave principle, where KIMaip is always the slave, the best practice
for using it as actuator is to involve the Data Ready pin in order to indicate bus events to the
master. TI C pin 3.7 has been used for this purpose, see source code.
void EnableSwitches(void)
{
P4IFG = 0; // P4 IFG cleared
P4IE = BIT0+BIT1; // P4 interrupt enabled
}
void DisableSwitches(void)
{
P4IFG = 0; // P4 IFG cleared
P4IE &= ~(BIT0+BIT1); // P4 interrupt disabled
P4IFG = 0; // P4 IFG cleared
}
void StartDebounceTimer(void)
{
// Debounce time = 1500 * 1/8000 = ~200ms
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 1500;
TA1CTL = TASSEL_1 + MC_1; // ACLK, up mode
}
void setLEDs(void)
{
// Enable LED1 & LED2
PJOUT &= ~(BIT0+BIT1);
PJDIR |= BIT0+BIT1;
LED1 = 0;
LED2 = 0;
}
void setSwitches(void)
{
// Set up switches S1 & S2
// P4.0 and P4.1 are configured as switches
S1 = 0;
S2 = 0;
}
void setClock(void)
{
CSCTL0_H = 0xA5; // Unlock register
CSCTL1 = 0x0060u; // Set max. DCO setting = 8MHz
CSCTL2 = 0x0133u; // set ACLK = VLO; MCLK = DCO
CSCTL3 = 0x0000u; // no dividers
CSCTL0_H = 0x01; // Lock register
}
void setI2C(void)
{
UCB0CTLW0 |= UCSWRST; // keep in reset status
UCB0CTLW0 |= 0x0E00u; // I2C master mode
UCB0BRW = 0x0014u; // Set baudrate = 8MHz/20 = 400KHz
UCB0I2CSA = 0x08; // Set slave address
// Configure I2C pins
P1SEL1 |= 0xC0;
P1SEL0 &= ~0xC0;
// P1.7 = SCL
// P1.6 = SDA
UCB0CTLW0 &= ~UCSWRST; // release from reset status
void sendI2C(void)
{
if(S2==0)
snd_msg = command_0;
else
snd_msg = command_1;
snd_cntr = 0;
if(UCB0STATW&UCBBUSY)
setI2C();
void setDR(void)
{
// set up P3.7 to capture data ready signal
P3SEL1 &= BIT7;
P3SEL0 &= ~BIT7;
P3DIR &= ~BIT7; // direction = input
P3REN |= BIT7; // enable pullup/pulldown resistor
P3IES &= ~BIT7; // low to high transition interrupt
P3IE = BIT7; // interrupt enabled
P3IFG &= ~BIT7; // IFG cleared
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // stop watchdog
setLEDs();
setSwitches();
setClock();
setI2C();
setDR();
while(1)
{
__bis_SR_register(LPM0_bits + GIE); // low power mode0 + general interupt
__no_operation(); // For debugger
}
}
//**********************************************************************
//* Port 4 ISR for S1 & S2
//**********************************************************************
#pragma vector=PORT4_VECTOR
__interrupt void Port_4(void)
{
switch(__even_in_range(P4IV,0x04))
{
case 0x02: // P4.0 interrupt = S1
break;
default:
break;
}
}
//**********************************************************************
//* Timer A1 ISR for debounce Timer
//**********************************************************************
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
{
TA1CCTL0 = 0;
TA1CTL = 0;
EnableSwitches();
}
//**********************************************************************
//* USCI B0 ISR for RX
//**********************************************************************
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch(__even_in_range(UCB0IV,0x18))
{
case 0x04: // NACK received
UCB0IFG &= ~UCSTPIFG;
UCB0IFG &= ~UCTXIFG0;
break;
case 0x06: // START received
UCB0IFG &= ~UCSTTIFG;
UCB0IFG &= ~UCTXIFG0;
break;
case 0x08: // STOP received
UCB0IFG &= ~UCSTPIFG;
UCB0IFG &= ~UCTXIFG0;
break;
case 0x16:
UCB0IFG &= ~UCRXIFG0;
rcv_msg[rcv_cntr++] = UCB0RXBUF;
if(rcv_cntr == 5)
{
if(rcv_msg[2]==0 && rcv_msg[3]==0)
//**********************************************************************
//* Port 3 ISR for Data Ready
//**********************************************************************
#pragma vector=PORT3_VECTOR
__interrupt void Port_3(void)
{
switch(__even_in_range(P3IV,0x10))
{
case 0x10: // P3.7 interrupt
P3IFG &= ~BIT7;
if(UCB0STATW&UCBBUSY)
setI2C();
Connect
Wire the device.
Open the serial terminal software (see Figure 1).
Click tab page Port.
Select the virtual com port that has been added.
Put its settings to 19200, 8, 1, even.
Play
Click tab page Send.
Type e.g. 0x10,0x40,0x40,0x16 in the top entry field and click Send Numbers. This command
will reset the device. The device confirms by sending an FT1.2 ACK (0xE5). This is a perfect
method to test the principal working of the test setup.
BAOS
+BUS TX
External C
-BUS RX
KEY VCC
LED GND
Galvanic Separation
Details:
Interface: FT1.2 based protocol via TX and RX.
For more details about the serial protocol, please consult the Weinzierl Engineering related BAOS
documentation. URL: www.weinzierl.de
VCC
VCC
I/O pin 4
GND
10K
TX pin 1
Arduino UNO
Push
Button
GND
+BUS TX
RX
-BUS
KEY VCC
LED GND
BAOS
Details:
Arduino UNO pin 4 serves as input port in order to capture push button events.
Arduino UNO pin 1 serves as serial transmit port, which is connected to RX of the BAOS.
A simple debounce routine is implemented in order to detect the push button events.
For each push button event an ASCII command is sent to the BAOS.
void setup()
{
pinMode(buttonPin, INPUT);
Serial.begin(19200,SERIAL_8E1);
}
void loop()
{
if ((millis() - lastDebounceTime) > debounceDelay)
{
buttonState = digitalRead(buttonPin);
lastDebounceTime = millis();
TM = 1;
}
if ((TM == 1) && (buttonState == LOW))
{
if (KNXoutput == LOW)
{
KNXoutput = HIGH;
for(i=0; i < 14; i++)
Serial.write(msg_odd_1[i]);
}
else
{
KNXoutput = LOW;
for(i=0; i < 14; i++)
Serial.write(msg_even_0[i]);
}
buttonState = HIGH;
TM = 0;
}
}
VCC
I/O pin 2
GND
RX pin 0 470
Arduino UNO
LED
+BUS TX
RD GND
-BUS
KEY VCC
LED GND
BAOS
Details:
Arduino UNO pin 2 serves as simulation of a KNX binary output channel by means of a LED.
Arduino UNO pin 0 serves as serial receive port, which is connected to TX of the BAOS.
A simple serial port read routine is implemented in order to capture and process ASCII commands
from the BAOS.
Depending on the actual content of each received ASCII command the LED will either be switched
on or off.
Remark:
In the source code (see further) an acknowledge byte (0xE5) is sent after each received BAOS
message. This obviously is only effective if the Arduino UNO pin 1 (TX) is connected to RD of the
BAOS (which is not the case in the above figure).
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(19200 , SERIAL_8E1);
}
void loop()
{
if (Serial.available())
{
incomingByte = Serial.read();
for(int i=0;i<maxLen;i++)
msg[i] = 0;
}
if(msgState==1)
{
msg[msgCntr++] = incomingByte;
if(msgCntr==2)
msgLen = incomingByte + 6;
if(msgCntr==msgLen)
{
if(incomingByte==0x16)
{
msgState = 0;
Serial.write(0xE5); //ACK
}
}
}
}
}
Connect
Wire the device.
Open the serial terminal software (see Figure 1).
Click tab page Port.
Select the virtual com port that has been added.
Put its settings to 19200, 8, 1, even.
Play
Click tab page Send.
Type e.g. 0x10,0x40,0x40,0x16 in the top entry field and click Send Numbers. This command
will reset the device. The device confirms by sending an FT1.2 ACK (0xE5). This is a perfect
method to test the principal working of the test setup.
BAOS
+BUS TX
External C
-BUS RX
KEY VCC
LED GND
Galvanic Separation
Details:
Interface: FT1.2 based protocol via TX and RX.
For more details about the serial protocol, please consult the Weinzierl Engineering related BAOS
documentation. URL: www.weinzierl.de
VCC
GND
P2.0
P2.1
MSP-EXP430FR5739
+BUS TX
-BUS RX
KEY VCC
LED GND
BAOS
Details:
TI C pin P2.1 serves as serial receive port, which is connected to TX of the BAOS.
TI C pin P2.0 serves as serial transmit port, which is connected to RX of the BAOS.
A simple debounce routine is implemented in order to detect the onboard push button events.
For each onboard push button event an ASCII command is sent to the BAOS.
A simple serial port read routine is implemented in order to capture and process ASCII commands
from the BAOS.
Depending on the actual content of each received ASCII command the onboard LED2 will either
be switched on or off.
#include "msp430fr5739.h"
#include <string.h>
#define MAXLEN 50
char rcv_buffer[MAXLEN];
int rcv_cntr;
char rcv_char;
int msgState;
int S1;
int S2;
int LED1;
int LED2;
void EnableSwitches(void)
{
P4IFG = 0; // P4 IFG cleared
P4IE = BIT0+BIT1; // P4 interrupt enabled
}
void DisableSwitches(void)
{
P4IFG = 0; // P4 IFG cleared
P4IE &= ~(BIT0+BIT1); // P4 interrupt disabled
P4IFG = 0; // P4 IFG cleared
}
void StartDebounceTimer(void)
{
// Debounce time = 1500 * 1/8000 = ~200ms
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 1500;
TA1CTL = TASSEL_1 + MC_1; // ACLK, up mode
}
void setLEDs(void)
{
// Enable LED1 & LED2
PJOUT &= ~(BIT0+BIT1);
PJDIR |= BIT0+BIT1;
LED1 = 0;
LED2 = 0;
}
void setSwitches(void)
{
// Set up switches S1 & S2
// P4.0 and P4.1 are configured as switches
// Port 4 has only two pins
S1 = 0;
S2 = 0;
}
void setClock(void)
{
CSCTL0_H = 0xA5; // Unlock register
CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting
CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO
CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers
CSCTL0_H = 0x01; // Lock register
}
void setUart(void)
{
// Configure UART pins
P2SEL1 |= BIT0 + BIT1;
P2SEL0 &= ~(BIT0 + BIT1);
// Configure UART 0
UCA0CTL1 |= UCSWRST; // keep in reset mode
UCA0CTL1 = 0x80; // SMCLK
UCA0CTL0 = 0xc0; // parity enabled + even parity
UCA0BR0 = 26; //19200 baud
UCA0BR1 = 0;
UCA0MCTLW |= 0xb601; // BRCLK=8000000 UCOS16=1 (UCBR=26) UCBRF=0 UCBRS=0xb6
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // stop watchdog
setLEDs();
setSwitches();
setClock();
setUart();
while(1)
{
__bis_SR_register(LPM4_bits + GIE); // low power mode4 + general interupt
__no_operation(); // For debugger
}
}
//**********************************************************************
//* Port 4 ISR for S1 & S2
//**********************************************************************
#pragma vector=PORT4_VECTOR
__interrupt void Port_4(void)
{
switch(__even_in_range(P4IV,0x04))
{
DisableSwitches();
StartDebounceTimer();
break;
default:
break;
}
}
//**********************************************************************
//* Timer A1 ISR for debounce Timer
//**********************************************************************
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
{
TA1CCTL0 = 0;
TA1CTL = 0;
EnableSwitches();
}
//**********************************************************************
//* USCI (universal serial communication interfce) A0 ISR for RX
//**********************************************************************
#pragma vector = USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
switch(__even_in_range(UCA0IV,0x02))
{
case 0x02: // UCRXIFG = P2.1 = RX
rcv_char = UCA0RXBUF;
switch(rcv_char)
{
case 0x68:
if(msgState == 0)
strcpy(rcv_buffer, "");
rcv_cntr = 0;
msgState = 0;
}
break;
default:
if(msgState > 0 && rcv_cntr < MAXLEN)
rcv_buffer[rcv_cntr++] = rcv_char;
break;
}
break;
default: break;
}
}