Setup & Installation

General requirements

  • PC with Arduino IDE (1.6.4 or newer) (Windows, Linux, MAC)
  • Internet connection

CONTROLLINO library

  • Start Arduino IDE, navigate to Sketch–>Include Library–>Manage Libraries
  • In the Library Manager type CONTROLLINO into the filter text box and search for CONTROLLINO library
  • When found, select the latest version and install it. The installation process should be fully automated
  • When finished – check in Sketch–>Include Library menu that you can see the CONTROLLINO library there
  • You can also check if you can see the set of CONTROLLINO examples in File->Examples->CONTROLLINO

CONTROLLINO boards hardware definition

  • Navigate to File–>Preferences
  • Copy-paste the following link to the Additional Boards Manager URLs: https://raw.githubusercontent.com/CONTROLLINO-PLC/CONTROLLINO_Library/master/Boards/package_ControllinoHardware_index.json
  • Press OK button
  • Then navigate to Tools–>Board: “Foo“–>Boards Manager
  • In the Boards Manager type CONTROLLINO into the filter text box and search for CONTROLLINO boards
  • When found, select the latest version and install it. The installation process should be fully automated
  • When finished – check in Tools–>Board: “Foo“–> menu that you can see the CONTROLLINO boards there

Usage & Features

The terminal “12V/24V” and “GND” on the upper side of the CONTROLLINO terminals are for the supply voltage connection. You can supply the CONTROLLINO with 12V or 24V. The range of voltage should be in the range of 10.8V-13.2V and 21.6V-26.4V direct voltage.

IMPORTANT! Please make sure using a stabilized supply voltage!

The maximal supply current I not the same for MINI, MAXI and MEGA:

  • MINI: 8A
  • MAXI: 20A
  • MEGA: 30A

Exceeding the maximum current would lead to a fusing of the internal fuse of the CONTROLLINO.

The right supply voltage will be indicated by 2 LEDs. The LEDs are marked with “12V” and “24V”. Depending on the supply voltage the LEDs will show the state of the CONTROLLINO.

12V LED 24V LED state

green orange 12V supply voltage active

orange green 24V supply voltage active

orange orange supply voltage outside of supported range

INFO: After connecting the supply voltage CONTROLLINO will start immediately executing the loaded program!

Over the USB port you connect the CONTROLLINO PLC with the computer (USB cable Type A-B). Don’t use to much force when connecting! The main function of this USB port is to program the CONTROLLINO. Inside the CONTROLLINO there is a USB to UART converter which generates a virtual COM-Port on the PC. You can also use this port to give data to a terminal or another program.

The CONTROLLINO PLC MAXI and MEGA have also an Ethernet connector. It is marked with the sign “ETH”. This connecter can be connected with a RJ-45 connector to a computer network using a 1:1 Network cable. Internally an Ethernet WIZnet Chip W5100 is used to connect to a LAN (Local Area Network). With this feature it get very simple to connect to an existing network or the internet. The Ethernet chip is connected to the same SPI bus as in the original “Arduino Ethernet Shield”. Because the ETH chip uses the same SPI bus as for the RTC, the chip has to be selected over a chip select. If you have installed the CONTROLLINO Library’s into the ARDUINO IDE, this selection will take place automatically and you can use the original Ethernet examples. The 2 LEDs on the Ethernet connector will also indicate the status of Ethernet.

LED green: LAN connection active (POWER)

LED yellow: Data is transmitted and received

Over the pinheader connector you can contact “directly” to the microcontroller. Theses contacts are like on the ARDUINO board at a 5V level. You can use this pins freely to connect additional modules and electronics.

INFO: This pinheader pins will change their state together with the Relays, digital inputs and outputs with the same labeling but on 5V level.

These pins are ESD protected.

CONTROLLINO can be reset over the “RST“ button. The RST-LED will be active if the RST button will be pressed and will be active as long as the button is pressed. After releasing the button, the LED goes off and the user program will be executed from the beginning. The reset button is on the top of the CONTROLLINO and can be pressed with a thin screw driver. Don’t use to much force when pressing the button.

This switch is made for switching the internal RTC (Real Time Clock) onto the SPI bus. If you use the RTC in you program, the switch has to be in the “1” position, otherwise there would be no data connection to the RTC.

Inputs (A0 … Ax)

CONTROLLINO has many analog inputs that can be used an analog and digital input. This will be set in the user program.

Inputs as analog input

The data logging work with the internal A/D converter of the microcontroller and has a resolution of 10Bit and delivers the values 0 – 1023. CONTROLLINO internally uses an automatic voltage divider controlled over the supply voltage. Dependent of the supply voltage the divider is switched to the right value.

If you use a 12V supply voltage the measured value can be between 0-13,2V.

1 digit = 0,015V (15,0mV)

If you use a 24V supply voltage the measured value can be between 0-26,4V.

1 digit = 0,03V (30,0mV)

The scaling factor is:

@12V … 3,06

@24V … 6,14

INFO: all inputs are protected against electrostatic discharging and overvoltage.

Inputs as digital input

Every of the A0…Ax inputs can also be used as a digital input to measure a switching status. If a logic “1” is measured the corresponding LED Ax will be active. At a logic “0” the corresponding LED Ax will be off. This optical information can be used to get a quick overview about the status of the inputs. This can be very helpful when toing an error diagnostics or a programming stage.

The logic levels depending on the supply voltage are:

Logik supply voltage level

0 12V 0 .. 3,6V

1 12V 9 .. 13,2V

0 24V 0 .. 7,2V

1 24V 18 .. 26,4V

The maximum input current is < 3mA.

Digital Inputs (I..)

This inputs are only digital inputs. If a logic “1” is measured the corresponding LED Ax will be active. At a logic “0” the corresponding LED Ax will be off. This optical information can be used to get a quick overview about the status of the inputs. This can be very helpful when toing an error diagnostics or a programming stage.

The logic levels depending on the supply voltage are:

Logik supply voltage level

0 12V 0 .. 3,6V

1 12V 9 .. 13,2V

0 24V 0 .. 7,2V

1 24V 18 .. 26,4V

The maximum input current is < 3mA.

Interrupt Inputs (IN0 and IN1)

Additional to the normal analog and digital inputs, CONTROLLINO also has 2 special interrupt inputs. This inputs are capable of measure very fast and important switching operations. The electrical behavior is like at a normal digital input, but in the user program they can execute subroutines at the change of inputs level.

The CONTROLLINO PLC has „High-Side Switch“ outputs, „Half-Bridge“ outputs (only MEGA) and potential free Relays outputs. Some of these outputs are also capable of generating PWM (Pulse Width Modulation) signals. Therefore it is possible to dim a lamp or to control the speed of a DC motor.

Digital outputs (D0..Dx)

The digital „High-Side Switch“ outputs and „Half-Bridge“ outputs (only MEGA) are labeled with “D0 .. Dx” on the upper side of CONTROLLINO. Every of this digital screw terminal switches the supply voltage to the output and can be loaded with 2A @12V or @24V. Every of this outputs are short-circuit proof and limits the maximum output current automatically. The internal resistance when switched is about 70mΩ when using the „High-Side Switch“ outputs and about 240mΩ when using the „Half-Bridge“ outputs.

INFO: This outputs are not potential free. The load have to be connected between the output and GND. At the „Half-Bridge“ outputs you can also put the load between two outputs, to drive for example a DC motor in both directions.

WARNING: this digital outputs are not made to switch 230V.

There is possibility to parallelize some digital outputs to drive loads with the need of more current with following conditions:
– Outputs are controlled from the same processor port (possibility to set it via one instruction)
– There is no delay between control signals for parallelized outputs (shall be managed by the SW).

Possible outputs for parallelization:

MINI:
1st group: D0, D1, D2, D3
2nd group: D4, D5
3rd group: D6, D7

MAXI:
1st group: D0, D1, D3
2nd group: D2
3rd group: D4, D5, D6, D7
4th group: D8, D9, D10, D11

MEGA:
1st group: D0, D1, D3
2nd group: D2
3rd group: D4, D5, D6, D7
4th group: D8, D9, D10, D11
5th group: D12, D13, D14, D15, D16, D17, D18, D19
6th group: D20, D21, D22
7th group: D23

PWM Outputs

The PWM Outputs are marked with a dark background.

MINI: D1, D2, D5
MAXI: D0 .. D11
MEGA: D0 .. D11, D14,D15,D16

 

Relay Outputs

With the Relay outputs „R0 .. Rx“ an external electric circuit can we switched. The type of contact can be seen on the PLC. The maximum switching current is 6A @250V/AC or 6A @30V/DC.

INFO: This Relays outputs are potential free!

IMPORTANT! The Relays Outputs are put together into 2 block.

In one block it shall be possible to use only one type of switching circuit. That means mains, circuit 230V or DC which is not SELV (Safety Extra Low Voltage) on block 1 and SELV circuit on block 2 or vice versa. Because of safety regulations it is not possible to combine these two types of circuit in one block.

The LED with the “OVL” marking show you a thermal overload of the CONTROLLINO PLC.

At the CONTROLLINO MINI there are 2 temperature sensors integrated. They are placed on the Relays-Board and on the Control-Board. If the temperature goes over 80°C the red “OVL” LED will go on and shows you a thermal overload.

At the CONTROLLINO MAXI it is the same but the overload signal will also be available at the microcontroller PE7 (Arduino Pin 9). Therefore, you can use this signal in your user program.

At the CONTROLLINO MEGA additional to the thermal control, the „Half-Bridge“ Driver also has a FAULT signal which is also connected to the Controllino general overload signal. Internal protection functions are provided for undervoltage, charge pump faults, overcurrent, short circuits, and overtemperature.

The CONTROLLINO MAXI and MEGA have a RS485 interface of the type SN65HVD08. With this interface you are able to communicate with other RS485 interfaces.

RS485 is a serial interface standard capable of data communication with up to 32 receivers at a distance up to 1200m.

The RS485 driver is connected to the UART3 (TxD3 / RxD3) of the ATmega2560.

Every CONTROLLINO has an internal RTC of the type RV-2123-C2-TA-QC-020 with a buffered supply. The RTC runs also without external power supply for about 2 weeks. So after a loss of supply voltage you don’t have to reconfigure the time. In the user program you can set hour, minute, second, day, weekday, month and year.

Examples

This example shows you how to read analog input from your Controllino device over serial communication. In order to do this, you have to connect potentiometer on one analog input and establish serial communication between your Controllino board and your computer running the Arduino Software(IDE).

IMPORTANT INFORMATION!
Please, select proper target board in Tools->Board->Controllino MINI/MAXI/MEGA before Upload to your CONTROLLINO.
(Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

Hardware Required

  • Controllino MINI/MAXI/MEGA
  • 10k ohm potentiometer

Circuit

#include <Controllino.h> 
/* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */

// the setup routine runs once when you press reset:
void setup() {
    // initialize necessary pin as input pin
    pinMode(CONTROLLINO_A0, INPUT);
 
    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
    // read the input on analog pin 0:
    int sensorValue = analogRead(CONTROLLINO_A0);
    // print out the value you read:
    Serial.println(sensorValue);
    delay(1); // delay in between reads for stability
}

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

This example shows you how to use our powerful digital outputs and relays. The CONTROLLINO PLCs have “High-Side Switch” outputs, “Half-Bridge” outputs (only MEGA) and potential free relay outputs. Some of these outputs are also capable of generating PWM (Pulse Width Modulation) signals. Therefore it is possible to dim a lamp or to control the speed of a DC motor.

IMPORTANT INFORMATION!
Please, select proper target board in Tools->Board->Controllino MINI/MAXI/MEGA before Upload to your CONTROLLINO.
(Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

Hardware Required

  • Controllino MINI/MAXI/MEGA
  • 12/24V DC Power supply

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

Controllino MINI

In case of the Controllino MINI, the relays are connected parallelly to the digital outputs D0-D5 and thus are named D0-D5.

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */

// the setup function runs once when you press reset (CONTROLLINO RST button) or connect the CONTROLLINO to the PC
void setup() {
 // initialize all used digital output pins as outputs
 pinMode(CONTROLLINO_D0, OUTPUT); // note that we are using CONTROLLINO aliases for the digital outputs
 pinMode(CONTROLLINO_D1, OUTPUT); 
 pinMode(CONTROLLINO_D2, OUTPUT); // the alias is always like CONTROLLINO_
 pinMode(CONTROLLINO_D3, OUTPUT); // and the digital output label as you can see at the CONTROLLINO device 
 pinMode(CONTROLLINO_D4, OUTPUT); // next to the digital output screw terminal                                
}

// the loop function runs over and over again forever
void loop() {
 digitalWrite(CONTROLLINO_D0, HIGH); // turn the LED on (HIGH is the voltage level)
 delay(100);                         // wait for 100 milliseconds which is 1/10 of a second 
 digitalWrite(CONTROLLINO_D0, LOW);  // turn the LED off by making the voltage LOW
 delay(100);                         // wait for 100 milliseconds which is 1/10 of a second 
 digitalWrite(CONTROLLINO_D1, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_D1, LOW); 
 delay(100); 
 digitalWrite(CONTROLLINO_D2, HIGH); // please, visit https://www.controllino.biz/downloads/ 
 delay(100);                         // if you want to know more about the mapping of the CONTROLLINO
 digitalWrite(CONTROLLINO_D2, LOW);  // digital outputs to the Arduino pins
 delay(100); 
 digitalWrite(CONTROLLINO_D3, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_D3, LOW);  // by using CONTROLLINO aliases instead of Arduino pin numbers 
 delay(100);                         // you ensure sketch portability between all CONTROLLINO variants
 digitalWrite(CONTROLLINO_D4, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_D4, LOW); 
 delay(100); 
}

To make the outputs and relays blink, CONTROLLINO pins have to be set up as OUTPUTs!

*pinMode(CONTROLLINO_xx, OUTPUT);

 

Controllino MAXI/MEGA

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch.*/ 

// the setup function runs once when you press reset (CONTROLLINO RST button) or connect the CONTROLLINO to the PC
void setup() {
 // initialize all used digital output pins as outputs
 pinMode(CONTROLLINO_D0, OUTPUT);
 pinMode(CONTROLLINO_D1, OUTPUT); // note that we are using CONTROLLINO aliases for the digital outputs
 pinMode(CONTROLLINO_D2, OUTPUT);
 pinMode(CONTROLLINO_D3, OUTPUT); // the alias is always like CONTROLLINO_
 pinMode(CONTROLLINO_D4, OUTPUT); // and the digital output label as you can see at the CONTROLLINO device 
 pinMode(CONTROLLINO_R0, OUTPUT); // next to the digital output screw terminal
 pinMode(CONTROLLINO_R1, OUTPUT);
 pinMode(CONTROLLINO_R2, OUTPUT);
 pinMode(CONTROLLINO_R3, OUTPUT);
 pinMode(CONTROLLINO_R4, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
 digitalWrite(CONTROLLINO_D0, HIGH); // turn the LED on (HIGH is the voltage level)
 delay(100);                         // wait for 100 milliseconds which is 1/10 of a second 
 digitalWrite(CONTROLLINO_D0, LOW);  // turn the LED off by making the voltage LOW
 delay(100);                         // wait for 100 milliseconds which is 1/10 of a second 
 digitalWrite(CONTROLLINO_D1, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_D1, LOW); 
 delay(100); 
 digitalWrite(CONTROLLINO_D2, HIGH); // please, visit https://www.controllino.biz/downloads/ 
 delay(100);                         // if you want to know more about the mapping of the CONTROLLINO
 digitalWrite(CONTROLLINO_D2, LOW);  // digital outputs to the Arduino pins
 delay(100); 
 digitalWrite(CONTROLLINO_D3, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_D3, LOW);  // by using CONTROLLINO aliases instead of Arduino pin numbers 
 delay(100);                         // you ensure sketch portability between all CONTROLLINO variants
 digitalWrite(CONTROLLINO_D4, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_D4, LOW); 
 delay(100); 
 digitalWrite(CONTROLLINO_R0, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_R0, LOW); 
 delay(100); 
 digitalWrite(CONTROLLINO_R1, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_R1, LOW); 
 delay(100); 
 digitalWrite(CONTROLLINO_R2, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_R2, LOW); 
 delay(100); 
 digitalWrite(CONTROLLINO_R3, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_R3, LOW); 
 delay(100);
 digitalWrite(CONTROLLINO_R4, HIGH); 
 delay(100); 
 digitalWrite(CONTROLLINO_R4, LOW); 
 delay(100); 
 
}

Every CONTROLLINO has a built-in RTC of the type RV-2123-C2-TA-QC-020 with buffered power supply. The RTC also runs without external power supply for about 2 weeks. So after a loss of supply voltage you don’t have to reconfigure the time. In the user program you can set the hour, minute, second, day, weekday, month and year. These values can be prompted and can be used directly or in logical combination with other conditions as a trigger for specific operations.

IMPORTANT INFORMATION!
Please, select proper target board in Tools->Board->Controllino MINI/MAXI/MEGA before Upload to your CONTROLLINO.
(Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

Hardware Required

  • Controllino MINI/MAXI/MEGA
  • 12/24V DC Power supply

Circuit

On CONTROLLINO MINI the “RTC” switch is made for switching the internal RTC (Real Time Clock) onto the SPI bus. If you use the RTC in your program, the switch has to be in the “1” position, otherwise there would be no data connection to the RTC.

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

To set initial values to the RTC chip we use function from Controllino Library:

* Controllino_SetTimeDate(31,2,1,17,8,37,23); // (Day of the month, Day of the week, Month, Year, Hour, Minute, Second)

#include <SPI.h>
#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */

// The setup function runs once when you press reset (CONTROLLINO RST button) or connect power supply 
// (USB or external 12V/24V) to the CONTROLLINO.
void setup() {
 // initialize serial communication at 9600 bits per second
 Serial.begin(9600);
 Controllino_RTC_init(0);
 Controllino_SetTimeDate(31,2,1,17,8,37,23); // set initial values to the RTC chip
}

// the loop function runs over and over again forever
void loop() {
 int n; 
 Serial.print("Day: ");n = Controllino_GetDay(); Serial.println(n);
 
 Serial.print("WeekDay: ");n = Controllino_GetWeekDay(); Serial.println(n);
 
 Serial.print("Month: ");n = Controllino_GetMonth(); Serial.println(n);

 Serial.print("Year: ");n = Controllino_GetYear(); Serial.println(n);

 Serial.print("Hour: ");n = Controllino_GetHour(); Serial.println(n);

 Serial.print("Minute: "); n = Controllino_GetMinute(); Serial.println(n);

 Serial.print("Second: ");n = Controllino_GetSecond(); Serial.println(n);
 
 delay(5000); 
}

The CONTROLLINO PLCs MAXI and MEGA have an RS485 interface type SN65HVD08, which allows it to communicate with other RS485 devices. The RS485 is an interface-standard for digital, line-connected and differential serial data transmission. Connection to the interface is possible via screw terminals. It can carry signals up to about 1.200 metres with 32 subscribers. There is a large number of different components on the market that have an RS485 interface – they can communicate with the CONTROLLINO PLCs.
The RS485 driver module is connected to the UART3 (TxD3 / RxD3) of the ATMEGA2560.

IMPORTANT INFORMATION!
You can download a “PINOUT-table” for MAXI here. In these files, you can easily see all internal wiring indications between clamps and the microcontroller.
Please, select proper target board in Tools->Board->Controllino MINI/MAXI/MEGA before Upload to your CONTROLLINO.
(Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

Hardware Required

  • 2x Controllino MAXI/MEGA
  • 12/24V DC Power supply

Circuit

  

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Demo RS485 Code

This example code is for testing your RS485 interface. Upload first code on CONTROLLINO sending device and the second code on CONTROLLINO receiving device. After programming them, connect the Controllinos according to the previous picture and turn on Serial Monitor on receiving Controllino.

Sending device

#include <SPI.h>
#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */

void TestRS485 (int mode)
{
 DDRJ = DDRJ | B01100000;
 PORTJ = PORTJ & B10011111;
 /*pinMode(CONTROLLINO_RS485_TX, OUTPUT);
 pinMode(CONTROLLINO_RS485_RX, INPUT);
 pinMode(CONTROLLINO_RS485_RE, OUTPUT);
 pinMode(CONTROLLINO_RS485_DE, OUTPUT);*/
 switch (mode)
 {
 case 0:
 PORTJ = PORTJ & B10011111;
 PORTJ = PORTJ | B01000000;
 /*digitalWrite (CONTROLLINO_RS485_RE, HIGH);
 digitalWrite (CONTROLLINO_RS485_DE, HIGH);*/
 delay (10);
 Serial.println ("Sending test message, expected to return;"); 
 Serial3.print("UUUUU Controllino RS485 test Message.UUUUU");
 break;
 
 case 1:
 PORTJ = PORTJ & B10011111;
 PORTJ = PORTJ | B01100000;
 /*digitalWrite (CONTROLLINO_RS485_RE, LOW);
 digitalWrite (CONTROLLINO_RS485_DE, HIGH);*/
 delay (10);
 Serial.println ("Sending test message, not expected to return;");
 Serial3.print("UUUUU Controllino RS485 test Message.UUUUU");
 break;
 
 case 2:
 PORTJ = PORTJ & B10011111;
 PORTJ = PORTJ | B00100000;
 /* digitalWrite (CONTROLLINO_RS485_RE, HIGH);
 digitalWrite (CONTROLLINO_RS485_DE, LOW);*/
 delay (10);
 Serial.println ("Sending test message, not expected to be sended;"); 
 Serial3.print("UUUUU Controllino RS485 test Message.UUUUU");
 break;
 
 default:
 Serial.println("Wrong mode!");
 return; 
 }
}

/* This function enters loop and waits for any incoming data on serial 3.*/
void RecieveRS485()
{
 Serial.println("Recieving RS485.");
 while(true)
 {
 if (Serial3.available()) 
 {
 // print the new byte:
 Serial.print((char)Serial3.read()); 
 }
 }
}

void setup() {
 /* Here we initialize USB serial at 9600 baudrate for reporting */
 Serial.begin(9600);
 /* Here we initialize RS485 serial at 9600 baudrate for communication */
 Serial3.begin(9600);
 /* This will initialize Controllino RS485 pins */
 Controllino_RS485Init();

}

void loop() {
 /* Use only one of the two functions, either send or recieve */
 // RecieveRS485();
 
 /* Send test. 2 seconds apart sending messages with 3 types of different settings. 
    Check the function comment for more infromation */
 TestRS485(0);
 delay(2000);
 TestRS485(1);
 delay(2000);
 TestRS485(2);
 delay(2000);

}

Receiving device

#include <SPI.h>
#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */

void TestRS485 (int mode)
{
 DDRJ = DDRJ | B01100000;
 PORTJ = PORTJ & B10011111;
 /*pinMode(CONTROLLINO_RS485_TX, OUTPUT);
 pinMode(CONTROLLINO_RS485_RX, INPUT);
 pinMode(CONTROLLINO_RS485_RE, OUTPUT);
 pinMode(CONTROLLINO_RS485_DE, OUTPUT);*/
 switch (mode)
 {
 case 0:
 PORTJ = PORTJ & B10011111;
 PORTJ = PORTJ | B01000000;
 /*digitalWrite (CONTROLLINO_RS485_RE, HIGH);
 digitalWrite (CONTROLLINO_RS485_DE, HIGH);*/
 delay (10);
 Serial.println ("Sending test message, expected to return;"); 
 Serial3.print("UUUUU Controllino RS485 test Message.UUUUU");
 break;
 
 case 1:
 PORTJ = PORTJ & B10011111;
 PORTJ = PORTJ | B01100000;
 /*digitalWrite (CONTROLLINO_RS485_RE, LOW);
 digitalWrite (CONTROLLINO_RS485_DE, HIGH);*/
 delay (10);
 Serial.println ("Sending test message, not expected to return;");
 Serial3.print("UUUUU Controllino RS485 test Message.UUUUU");
 break;
 
 case 2:
 PORTJ = PORTJ & B10011111;
 PORTJ = PORTJ | B00100000;
 /* digitalWrite (CONTROLLINO_RS485_RE, HIGH);
 digitalWrite (CONTROLLINO_RS485_DE, LOW);*/
 delay (10);
 Serial.println ("Sending test message, not expected to be sended;"); 
 Serial3.print("UUUUU Controllino RS485 test Message.UUUUU");
 break;
 
 default:
 Serial.println("Wrong mode!");
 return; 
 }
}

/* This function enters loop and waits for any incoming data on serial 3.*/
void RecieveRS485()
{
 Serial.println("Recieving RS485.");
 while(true)
 {
 if (Serial3.available()) 
 {
 // print the new byte:
 Serial.print((char)Serial3.read()); 
 }
 }
}

void setup() {
 /* Here we initialize USB serial at 9600 baudrate for reporting */
 Serial.begin(9600);
 /* Here we initialize RS485 serial at 9600 baudrate for communication */
 Serial3.begin(9600);
 /* This will initialize Controllino RS485 pins */
 Controllino_RS485Init();

}

void loop() {
 /* Use only one of the two functions, either send or recieve */
 RecieveRS485();
 
 /* Send test. 2 seconds apart sending messages with 3 types of different settings. 
    Check the function comment for more infromation */
 // TestRS485(0);
 // delay(2000);
 // TestRS485(1);
 // delay(2000);
 // TestRS485(2);
 // delay(2000);

}

ModbusRTU Code

After successful test of your CONTROLLINOs you can proceed with communication between devices via RS485 with utilization the ModbusRTU protocol. In this example the CONTROLLINOs are used as the Modbus master and slave!
For more information about the Modbus protocol visit the website: http://modbus.org/

The sketch is relevant only for CONTROLLINO variants MAXI and MEGA (because of necessity of RS485 interface)!

Modbus master device periodically reads Modbus 16bit registers (provided by the slave) and prints the current state to the debug Serial:
0 – analog CONTROLLINO_A0 value (0 – 1024)
1 – digital CONTROLLINO_D0 value (0/1)
2 – Modbus messages received
3 – Modbus messages transmitted

Modbus master device periodically writes and toggles Modbus 16bit registers:
4 – relay CONTROLLINO_R0 (0/1)
5 – relay CONTROLLINO_R1 (0/1)
6 – relay CONTROLLINO_R2 (0/1)
7 – relay CONTROLLINO_R3 (0/1)

To easily evaluate this example you need a second CONTROLLINO as Modbus slave running DemoModbusRTUSlave example sketch.

Modbus Master-Slave library for Arduino (ModbusRtu.h) was taken from the website: https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino
It was necessary to modify setting of the PORTJ for pins DE and RE control. These pins are located at the PORTJ and on the pins PIN6(DE) and PIN5(RE).

ModbusRTU master

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h" /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */

// This MACRO defines Modbus master address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!

#define MasterModbusAdd 0
#define SlaveModbusAdd 1

// This MACRO defines number of the comport that is used for RS 485 interface.
// For MAXI and MEGA RS485 is reserved UART Serial3.
#define RS485Serial 3

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch - RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);

// This uint16 array specified internal registers in the Modbus slave device.
// Each Modbus device has particular internal registers that are available for the Modbus master.
// In this example sketch internal registers are defined as follows:
// (ModbusSlaveRegisters 0 - 3 read only and ModbusSlaveRegisters 4 - 7 write only from the Master perspective):
// ModbusSlaveRegisters[0] - Read an analog value from the CONTROLLINO_A0 - returns value in the range from 0 to 1023.
// ModbusSlaveRegisters[1] - Read an digital value from the CONTROLLINO_D0 - returns only the value 0 or 1.
// ModbusSlaveRegisters[2] - Read the number of incoming messages - Communication diagnostic.
// ModbusSlaveRegisters[3] - Read the number of number of outcoming messages - Communication diagnostic.
// ModbusSlaveRegisters[4] - Sets the Relay output CONTROLLINO_R0 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[5] - Sets the Relay output CONTROLLINO_R1 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[6] - Sets the Relay output CONTROLLINO_R2 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[7] - Sets the Relay output CONTROLLINO_R3 - only the value 0 or 1 is accepted.
uint16_t ModbusSlaveRegisters[8];

// This is an structe which contains a query to an slave device
modbus_t ModbusQuery[2];

uint8_t myState; // machine state
uint8_t currentQuery; // pointer to message query

unsigned long WaitingTime;

void setup() {
 // initialize serial communication at 9600 bits per second:
 Serial.begin(9600);
 Serial.println("-----------------------------------------");
 Serial.println("CONTROLLINO Modbus RTU Master Test Sketch");
 Serial.println("-----------------------------------------");
 Serial.println("");
 // ModbusQuery 0: read registers
 ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[0].u8fct = 3; // function code (this one is registers read)
 ModbusQuery[0].u16RegAdd = 0; // start address in slave
 ModbusQuery[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
 ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO

 // ModbusQuery 1: write a single register
 ModbusQuery[1].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[1].u8fct = 6; // function code (this one is write a single register)
 ModbusQuery[1].u16RegAdd = 4; // start address in slave
 ModbusQuery[1].u16CoilsNo = 1; // number of elements (coils or registers) to write
 ModbusQuery[1].au16reg = ModbusSlaveRegisters+4; // pointer to a memory array in the CONTROLLINO
 ModbusSlaveRegisters[4] = 1; // initial value for the relays 
 
 ControllinoModbusMaster.begin( 19200 ); // baud-rate at 19200
 ControllinoModbusMaster.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
 
 WaitingTime = millis() + 1000;
 myState = 0;
 currentQuery = 0; 
}

void loop() {
 switch( myState ) {
 case 0: 
 if (millis() > WaitingTime) myState++; // wait state
 break;
 case 1: 
 Serial.print("---- Sending query ");
 Serial.print(currentQuery);
 Serial.println(" -------------");
 ControllinoModbusMaster.query( ModbusQuery[currentQuery] ); // send query (only once)
 myState++;
 currentQuery++;
 if (currentQuery == 2) 
 {
 currentQuery = 0;
 }
 break;
 case 2:
 ControllinoModbusMaster.poll(); // check incoming messages
 if (ControllinoModbusMaster.getState() == COM_IDLE) 
 {
 // response from the slave was received
 myState = 0;
 WaitingTime = millis() + 1000; 
 // debug printout
 if (currentQuery == 0)
 {
 // registers write was proceed
 Serial.println("---------- WRITE RESPONSE RECEIVED ----");
 Serial.println("");
 }
 if (currentQuery == 1)
 {
 // registers read was proceed
 Serial.println("---------- READ RESPONSE RECEIVED ----");
 Serial.print("Slave ");
 Serial.print(SlaveModbusAdd, DEC); 
 Serial.print(" ADC0: 0x");
 Serial.print(ModbusSlaveRegisters[0], HEX);
 Serial.print(" , Digital0: ");
 Serial.print(ModbusSlaveRegisters[1], BIN);
 Serial.print(" , ModbusCounterIn: ");
 Serial.print(ModbusSlaveRegisters[2], DEC);
 Serial.print(" , ModbusCounterOut: ");
 Serial.println(ModbusSlaveRegisters[3], DEC);
 Serial.println("-------------------------------------");
 Serial.println("");

 // toggle with the relays
 ModbusQuery[1].u16RegAdd++;
 if (ModbusQuery[1].u16RegAdd == 8)
 {
 ModbusQuery[1].u16RegAdd = 4;
 if (ModbusSlaveRegisters[4]) 
 {
 ModbusSlaveRegisters[4] = 0;
 }
 else 
 {
 ModbusSlaveRegisters[4] = 1;
 }
 }
 }
 }
 break;
 }
}

To compile the code, “ModbusRtu.h” file have to be added to the code (Sketch->Add File…). You can find the ModbusRtu.h file in CONTROLLINO Library folder or download it here. You can also start these codes directly from our CONTROLLINO Library.

ModbusRTU slave

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h" /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */

// This MACRO defines Modbus slave address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!
#define SlaveModbusAdd 1

// This MACRO defines number of the comport that is used for RS 485 interface.
// For MAXI and MEGA RS485 is reserved UART Serial3.
#define RS485Serial 3

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch - RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusSlave(SlaveModbusAdd, RS485Serial, 0);

// This uint16 array specified internal registers in the Modbus slave device.
// Each Modbus device has particular internal registers that are available for the Modbus master.
// In this example sketch internal registers are defined as follows:
// (ModbusSlaveRegisters 0 - 3 read only and ModbusSlaveRegisters 4 - 7 write only from the Master perspective):
// ModbusSlaveRegisters[0] - Read an analog value from the CONTROLLINO_A0 - returns value in the range from 0 to 1023.
// ModbusSlaveRegisters[1] - Read an digital value from the CONTROLLINO_D0 - returns only the value 0 or 1.
// ModbusSlaveRegisters[2] - Read the number of incoming messages - Communication diagnostic.
// ModbusSlaveRegisters[3] - Read the number of number of outcoming messages - Communication diagnostic.
// ModbusSlaveRegisters[4] - Sets the Relay output CONTROLLINO_R0 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[5] - Sets the Relay output CONTROLLINO_R1 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[6] - Sets the Relay output CONTROLLINO_R2 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[7] - Sets the Relay output CONTROLLINO_R3 - only the value 0 or 1 is accepted.
uint16_t ModbusSlaveRegisters[8];

// The setup function runs once when you press reset (CONTROLLINO RST button) or connect the CONTROLLINO to the PC
// In the setup function is carried out port setting and initialization of communication of the Modbus slave protocol.
void setup()
{
 pinMode(CONTROLLINO_R0, OUTPUT); // Set the pin CONTROLLINO_R0 as output.
 pinMode(CONTROLLINO_R1, OUTPUT); // Set the pin CONTROLLINO_R1 as output.
 pinMode(CONTROLLINO_R2, OUTPUT); // Set the pin CONTROLLINO_R2 as output.
 pinMode(CONTROLLINO_R3, OUTPUT); // Set the pin CONTROLLINO_R3 as output.

 pinMode(CONTROLLINO_D0, INPUT); // Set the pin CONTROLLINO_D0 as input - Read digital value at the pin D0.
 pinMode(CONTROLLINO_A0, INPUT); // Set the pin CONTROLLINO_A0 as input - Read analog value at the pin A0

 ControllinoModbusSlave.begin( 19200 ); // Start the communication over the ModbusRTU protocol. Baund rate is set at 19200
}

// The loop function runs over and over again forever
void loop()
{
 // This instance of the class Modbus checks if there are any incoming data.
 // If any frame was received. This instance checks if a received frame is Ok.
 // If the received frame is Ok the instance poll writes or reads corresponding values to the internal registers 
 // (ModbusSlaveRegisters).
 // Main parameters of the instance poll are address of the internal registers and number of internal registers.
 ControllinoModbusSlave.poll(ModbusSlaveRegisters, 8);

 // While are not received or sent any data, the Modbus slave device periodically reads the values of analog and 
 // digital outputs.
 // Also it updates the other values of registers.
 ModbusSlaveRegisters[0] = analogRead(CONTROLLINO_A0); // Read the analog input CONTROLLINO_A0.
 ModbusSlaveRegisters[1] = digitalRead(CONTROLLINO_D0); // Read the digital input CONTROLLINO_A0.
 ModbusSlaveRegisters[2] = ControllinoModbusSlave.getInCnt(); // Read the number of incoming messages.
 ModbusSlaveRegisters[3] = ControllinoModbusSlave.getOutCnt(); // Read the number of outcoming messages

 digitalWrite(CONTROLLINO_R0, ModbusSlaveRegisters[4]); // Update the relay output CONTROLLINO_R0 - ON/OFF
 digitalWrite(CONTROLLINO_R1, ModbusSlaveRegisters[5]); // Update the relay output CONTROLLINO_R1 - ON/OFF
 digitalWrite(CONTROLLINO_R2, ModbusSlaveRegisters[6]); // Update the relay output CONTROLLINO_R2 - ON/OFF
 digitalWrite(CONTROLLINO_R3, ModbusSlaveRegisters[7]); // Update the relay output CONTROLLINO_R3 - ON/OFF
}

To compile the code, “ModbusRtu.h” file have to be added to the code (Sketch->Add File…). You can find the ModbusRtu.h file in CONTROLLINO Library folder or download it here. You can also start these codes directly from our CONTROLLINO Library.

If you have a CONTROLLINO MINI device you can use the relay outputs “D0” to “D5” to connect and switch external circuits. The contact type as well as the contact connections are marked on the PLCs. The maximum permissible switching current per relay is 6A (at 250V / AC) or 6A (at a maximum of 30V / DC). The relay outputs are potential free!
On the CONTROLLINO MINI, the relays are connected parallelly to the digital outputs D0-D5 and thus are named D0-D5. If you switch the digital output, the relay digital output will also automatically be switched. In the case you don’t want that to happen you can disconnect the relay outputs by removing the solder line on the Controllino relay board.

Hardware Required

  • Controllino MINI
  • 12/24V DC Power supply
  • Knife or scalpel

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

Controllino MINI

To check if your relay switches together with the digital output on your Controllino MINI, you can run this code for certain digital output.

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */

// the setup function runs once when you press reset (CONTROLLINO RST button) or connect the CONTROLLINO to the PC
void setup() {
 // initialize all used digital output pins as outputs
 pinMode(CONTROLLINO_D0, OUTPUT);                            
}

// the loop function runs over and over again forever
void loop() {
 digitalWrite(CONTROLLINO_D0, HIGH); // turn the LED on (HIGH is the voltage level)
 delay(100);                         // wait for 100 milliseconds which is 1/10 of a second 
 digitalWrite(CONTROLLINO_D0, LOW);  // turn the LED off by making the voltage LOW
 delay(100);                         // wait for 100 milliseconds which is 1/10 of a second  
}

To make the outputs and relays blink, CONTROLLINO pins have to be set up as OUTPUTs!

*pinMode(CONTROLLINO_xx, OUTPUT);

Steps

In the following steps we will show you how to disconnect relays on the Controllino relay board.

Step 1:

Remove the Controllino MINI cover by lifting marked sides of the cover with flat-head screwdriver:


Step 2:

Remove these two screws that hold Controllino relay board in place:

and separate the device from the bottom case.

Step 3:

Turn to the bottom side of Controllino relay board:

and locate this section on the right corner of the board:

Step 4:

Take the sharp knife or scalpel and remove the solder line of the wanted digital output, marked with a red square on a previous picture. When removing the marked solder line, the best way is to make a cut on each side of the marked square and then remove the middle part.


In this example the relay D0 is disconnected from the digital output.
When you are finished you can upload the same program to check it again.

Note*
You can allways reconnect the relay outputs by connecting the 0 ohm smd resistor or some kind of conductor to reestablish the broken connection.

This example shows you how to connect 1-wire temperature sensor to the Controllino device and read the temperature or address of the sensor on the bus.
DS18B20 is 1-Wire digital temperature sensor from Maxim IC. Reports degrees in Celsius or Fahrenheit with 9 to 12-bit precision, from –55°C to +125°C (–67°F to +257°F)±0.5°C. Each sensor has a unique 64-Bit Serial number etched into it – allows for a huge number of sensors to be used on one data bus.

IMPORTANT INFORMATION!
Please, select proper target board in Tools->Board->Controllino MINI/MAXI/MEGA before Upload to your CONTROLLINO.
(Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

Hardware Required

  • Controllino MINI/MAXI/MEGA
  • 12/24V DC Power supply
  • DS18B20  – 1-wire temperature sensor
  • 4.7 kΩ resistor

Circuit

When connecting your sensor you can choose the pin that you want to connect it to.
In this case the data pin of the sensor is connected to the SDA communication pin, but it can also be connected on any digital, relay output (5V pin), or communication pin. The best way is to choose the pin that is free and not used.

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

To get the readings from the temperature sensor you need to instal OneWire library.
Open Sketch->Include Library->Manage Libraries…
In this example we use OneWire 2.3.3 library.
After installing the library you have to open File->Examples->OneWire->DS18x20_Temperature and run the example. The only thing you have to change in the code is the data pin that you are using in line:

*OneWire  ds(20);

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire ds(20); // on pin 20 (a 4.7K resistor is necessary)

void setup(void) {
 Serial.begin(9600);
}

void loop(void) {
 byte i;
 byte present = 0;
 byte type_s;
 byte data[12];
 byte addr[8];
 float celsius, fahrenheit;
 
 if ( !ds.search(addr)) {
 Serial.println("No more addresses.");
 Serial.println();
 ds.reset_search();
 delay(250);
 return;
 }
 
 Serial.print("ROM =");
 for( i = 0; i < 8; i++) {
 Serial.write(' ');
 Serial.print(addr[i], HEX);
 }

 if (OneWire::crc8(addr, 7) != addr[7]) {
 Serial.println("CRC is not valid!");
 return;
 }
 Serial.println();
 
 // the first ROM byte indicates which chip
 switch (addr[0]) {
 case 0x10:
 Serial.println(" Chip = DS18S20"); // or old DS1820
 type_s = 1;
 break;
 case 0x28:
 Serial.println(" Chip = DS18B20");
 type_s = 0;
 break;
 case 0x22:
 Serial.println(" Chip = DS1822");
 type_s = 0;
 break;
 default:
 Serial.println("Device is not a DS18x20 family device.");
 return;
 } 

 ds.reset();
 ds.select(addr);
 ds.write(0x44, 1); // start conversion, with parasite power on at the end
 
 delay(1000); // maybe 750ms is enough, maybe not
 // we might do a ds.depower() here, but the reset will take care of it.
 
 present = ds.reset();
 ds.select(addr); 
 ds.write(0xBE); // Read Scratchpad

 Serial.print(" Data = ");
 Serial.print(present, HEX);
 Serial.print(" ");
 for ( i = 0; i < 9; i++) { // we need 9 bytes
 data[i] = ds.read();
 Serial.print(data[i], HEX);
 Serial.print(" ");
 }
 Serial.print(" CRC=");
 Serial.print(OneWire::crc8(data, 8), HEX);
 Serial.println();

 // Convert the data to actual temperature
 // because the result is a 16 bit signed integer, it should
 // be stored to an "int16_t" type, which is always 16 bits
 // even when compiled on a 32 bit processor.
 int16_t raw = (data[1] << 8) | data[0];
 if (type_s) {
 raw = raw << 3; // 9 bit resolution default
 if (data[7] == 0x10) {
 // "count remain" gives full 12 bit resolution
 raw = (raw & 0xFFF0) + 12 - data[6];
 }
 } else {
 byte cfg = (data[4] & 0x60);
 // at lower res, the low bits are undefined, so let's zero them
 if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
 else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
 else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
 //// default is 12 bit resolution, 750 ms conversion time
 }
 celsius = (float)raw / 16.0;
 fahrenheit = celsius * 1.8 + 32.0;
 Serial.print(" Temperature = ");
 Serial.print(celsius);
 Serial.print(" Celsius, ");
 Serial.print(fahrenheit);
 Serial.println(" Fahrenheit");
}

Information: In this tutorial we are using the HMI from Beijer.

Controllino HMIs are industrial HMI panels with high-resolution touch-screens and modern design. The panels combine IP65 corrosion resistant plastic housing with the full version of the iX software, providing an advanced HMI solution for every kind of applications.
Combine HMI with Controllino and you can create simple as well as the sophisticated applications in very short time.

IMPORTANT: Please, select proper target board in Tools->Board->Controllino MINI/MAXI/MEGA before Upload to your CONTROLLINO.
(Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

Modbus TCP/IP

Hardware Required

  • Controllino MAXI/MEGA
  • 24V DC Power supply
  • Controllino HMI
  • 2x Ethernet cable
  • Router

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

HMI setup

To set up the Controllino HMI for communication and application we use the iX Software. iX Software is a revolutionary software that features drivers to communicate with your automation equipment, enhanced HMI functionality, state-of-the-art graphics, an intuitive design environment and a truly open platform for today’s automation market. iX Developer is a licensed application that runs on a Windows PC and is used to program iX operator panels.
Here we are going to show some steps on how to set it up properly. If you want to check more information and  the iX user manual click here.

Download the Controllino HMI – TCP/IP example and run it in the iX software.
From the left side of the main screen in the iX example there is the Tags button. Open the Tags to set your application addresses. You can see example of this on the next picture:

For more information about Tags and addressing of them navigate to Controllers/Settings and click on the help button of the Modbus Master controller.

After that go to the Controllers tab to choose the right controller for communication. When we are using the Controllino device we want to choose MODICON -> Modbus Master controller. In this example it is already done and they are named Modbus_TCP and Modbus_RTU.

Press on the Modbus_TCP controller, activate it and click on the Settings button to do the folowing:

Set communication mode to the Ethernet TCP/IP and the IP address of the station to your Controllino IP address. To get your Controllino IP address and to ensure that the connections work, run the ArduinoIDE->File->Examples->Ethernet->DhcpAddressPrinter example, upload it and open Serial Monitor. If everything works, you should get your IP address on the screen.

Code

Before uploading the program to the Controllino you have to install the Modbus TCP library. You can download it here. To install it copy the Modbus folder to your Arduino->libraries folder.
After getting the IP address of the Controllino the new program has to be uploaded to the device. The only thing that needs to be changed in the next code is this line:

*uint8_t ip[] = {192, 168, 0, 104}; // change this to the IP address of your Controllino device

#include<Controllino.h>
#include <SPI.h>
#include <Ethernet.h>

#include "Mudbus.h"

Mudbus Mb;

int D0 = CONTROLLINO_D0;
int D1 = CONTROLLINO_D1;
int R0 = CONTROLLINO_R0;
int A0_ = CONTROLLINO_A0;


//Function codes 1(read coils), 3(read registers), 5(write coil), 6(write register)
//signed int Mb.R[0 to 125] and bool Mb.C[0 to 128] MB_N_R MB_N_C
//Port 502 (defined in Mudbus.h) MB_PORT

void setup()
{
 uint8_t mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
 uint8_t ip[] = { 192, 168, 0, 103 };
 uint8_t gateway[] = { 192, 168, 0, 254 };
 uint8_t subnet[] = { 255, 255, 255, 0 };
 Ethernet.begin(mac, ip, gateway, subnet);

 delay(5000);
 Serial.begin(9600);
 Serial.println("Started");
 
 pinMode(D0, OUTPUT); 
 pinMode(D1, INPUT); 
 pinMode(R0, OUTPUT); 
 pinMode(A0_, INPUT); 
}

void loop()
{ 
 
 Mb.Run();

 analogWrite(D0, Mb.R[0]);
 digitalWrite(R0, Mb.R[2]);
 Mb.R[1] = digitalRead(D1); 
 Mb.R[3] = analogRead(A0_); 
 
}

 

Modbus RTU via RS485

Hardware Required

  • Controllino MAXI/MEGA
  • 24V DC Power supply
  • Controllino HMI
  • 3 wires or serial port adapter (male)

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

HMI setup

To set up the Controllino HMI for communication and application we use the iX Software. iX Software is a revolutionary software that features drivers to communicate with your automation equipment, enhanced HMI functionality, state-of-the-art graphics, an intuitive design environment and a truly open platform for today’s automation market. iX Developer is a licensed application that runs on a Windows PC and is used to program iX operator panels.
Here we are going to show some steps on how to set it up properly. If you want to check more information and  the iX user manual click here.

Download the Controllino HMI – RTU example and run it in the iX software.
From the left side of the main screen in the iX example there is the Tags button. Open the Tags to set your application addresses. You can see example of this on the next picture:

For more information about Tags and addressing of them navigate to Controllers/Settings and click on the help button of the Modbus Master controller.

Notice here that the Modbus_RTU tags are starting with “5:”. For communication with other stations than the default station, the station number is given as a prefix to the device. This is stated either as a fixed number or as an index register between I1 and I8. The station number is referring to a specific unit id. (5:40001 addresses holding register 40001 in station 5.)  In our case the Controllino is slave device on station 5. We can always define his station in the code that we upload.

After that go to the Controllers tab to choose the right controller for communication. When we are using the Controllino device we want to choose MODICON -> Modbus Master controller. In this example it is already done and they are named Modbus_TCP and Modbus_RTU.

Press on the Modbus_RTU controller, activate it and click on the Settings button to do the folowing steps:

Set communication mode to the Serial and the COM2 port of your Controllino HMI. Don’t forget to match the baud rate of Controllino and HMI. Choose the COM2 port to be RS-485.

Code

The Controllino HMI is communicating to the Controllino slave device on the station 5 so we have to set it in the next line:

*define SlaveModbusAdd 5

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h" /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */
/*
 CONTROLLINO - Modbus RTU protocol Slave example for MAXI and MEGA, Version 01.00
 
 The sketch is relevant only for CONTROLLINO variants MAXI and MEGA (because of necessity of RS485 interface)!

 This sketch is intended as an example of the communication between devices via RS485 with utilization the 
 ModbusRTU protocol.
 In this example the CONTROLLINO is used as the Modbus slave!
 For more information about the Modbus protocol visit the website: http://modbus.org/
 
 Modbus master device can read Modbus 16bit registers (provided by the slave):
 0 - analog CONTROLLINO_A0 value (0 - 1024)
 1 - digital CONTROLLINO_D0 value (0/1)
 2 - Modbus messages received
 3 - Modbus messages transmitted

 Modbus master device can write Modbus 16bit registers:
 4 - relay CONTROLLINO_R0 (0/1)
 5 - relay CONTROLLINO_R1 (0/1)
 6 - relay CONTROLLINO_R2 (0/1)
 7 - relay CONTROLLINO_R3 (0/1)

 To easily evaluate this example you need a second CONTROLLINO as Modbus master running DemoModbusRTUMaster 
 example sketch.
 Please note that both CONTROLLINOs need 12/24V external supply and you need to interconnect GND, -, + signals 
 of RS485 screw terminal.

 Modbus Master-Slave library for Arduino (ModbusRtu.h) was taken from the website: 
 https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino
 It was necessary to modify setting of the PORTJ for pins DE and RE control. These pins are located at the 
 PORJ and on the pins PIN6(DE) and PIN5(RE).

 IMPORTANT INFORMATION!
 Please, select proper target board in Tools->Board->Controllino MAXI/MEGA before Upload to your CONTROLLINO.
 (Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in 
 the Arduino IDE menu Tools->Board.)

 Created 30 March 2017
 by David


 (Check https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library for the latest CONTROLLINO related software stuff.)
*/
int D0 = CONTROLLINO_D0;
int D1 = CONTROLLINO_D1;
int R0 = CONTROLLINO_R0;
int A0_ = CONTROLLINO_A0;

// This MACRO defines Modbus slave address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!

#define SlaveModbusAdd 5

// This MACRO defines number of the comport that is used for RS 485 interface.
// For MAXI and MEGA RS485 is reserved UART Serial3.

#define RS485Serial 3

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch 
// is used RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.

Modbus ControllinoModbusSlave(SlaveModbusAdd, RS485Serial, 0);

// This uint16 array specified internal registers in the Modbus slave device.
// Each Modbus device has particular internal registers that are available for the Modbus master.
// In this example sketch internal registers are defined as follows:
// (ModbusSlaveRegisters 0 - 3 read only and ModbusSlaveRegisters 4 - 7 write only from the Master perspective):
// ModbusSlaveRegisters[0] - Read an analog value from the CONTROLLINO_A0 - returns value in the range from 0 to 1023.
// ModbusSlaveRegisters[1] - Read an digital value from the CONTROLLINO_D0 - returns only the value 0 or 1.
// ModbusSlaveRegisters[2] - Read the number of incoming messages - Communication diagnostic.
// ModbusSlaveRegisters[3] - Read the number of number of outcoming messages - Communication diagnostic.
// ModbusSlaveRegisters[4] - Sets the Relay output CONTROLLINO_R0 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[5] - Sets the Relay output CONTROLLINO_R1 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[6] - Sets the Relay output CONTROLLINO_R2 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[7] - Sets the Relay output CONTROLLINO_R3 - only the value 0 or 1 is accepted.

uint16_t ModbusSlaveRegisters[8];

// The setup function runs once when you press reset (CONTROLLINO RST button) or connect the CONTROLLINO to the PC
// In the setup function is carried out port setting and initialization of communication of the Modbus slave protocol.

void setup()
{
 delay(5000);
 Serial.begin(9600);
 Serial.println("Started");
 
 pinMode(D0, OUTPUT); 
 pinMode(D1, INPUT); 
 pinMode(R0, OUTPUT); 
 pinMode(A0_, INPUT); 

 ControllinoModbusSlave.begin( 19200 ); // Start the communication over the ModbusRTU protocol. Baund rate is set at 19200.
 Serial.begin(9600);
 
}

// The loop function runs over and over again forever
void loop()
{
 // This instance of the class Modbus checks if there are any incoming data.
 // If any frame was received. This instance checks if a received frame is Ok.
 // If the received frame is Ok the instance poll writes or reads corresponding values to the internal registers 
 // (ModbusSlaveRegisters).
 // Main parameters of the instance poll are address of the internal registers and number of internal registers.
 
 ControllinoModbusSlave.poll(ModbusSlaveRegisters, 8);

 // While are not received or sent any data, the Modbus slave device periodically reads the values of analog and 
 // digital outputs.
 // Also it updates the other values of registers.

 analogWrite(D0, ModbusSlaveRegisters[0]);
 digitalWrite(R0, ModbusSlaveRegisters[2]);
 ModbusSlaveRegisters[1] = digitalRead(D1); 
 ModbusSlaveRegisters[3] = analogRead(A0_); 
 
}

More information about port manipulation on this site: https://www.arduino.cc/en/Reference/PortManipulation

Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Controllino PLC. Each port is controlled by three registers, which are also defined variables in the arduino language:

  • DDR register – determines whether the pin is an INPUT or OUTPUT
  • PORT register – controls whether the pin is HIGH or LOW
  • PIN register – reads the state of INPUT pins set to input with pinMode()

DDR and PORT registers may be both written to, and read. PIN registers correspond to the state of inputs and may only be read.

Output Parallelization

There is the possibility to parallelize some digital outputs to drive loads with the need of more current under the following conditions:

  • Outputs are controlled from the same processor port (possibility to set it via one instruction)
  • There is no delay between control signls for parallelized outputs ( shall be managed by the SW)

Possible outputs for parallelization are:

MINI
1st group: D0, D1, D2, D3
2nd group: D4, D5
3rd group: D6, D7

MAXI:
1st group: D0, D1, D3
2nd group: D2
3rd group: D4, D5, D6, D7
4th group: D8, D9, D10, D11

MEGA:
1st group: D0, D1, D3
2nd group: D2
3rd group: D4, D5, D6, D7
4th group: D8, D9, D10, D11
5th group: D12, D13, D14, D15, D16, D17, D18, D19
6th group: D20, D21, D22
7th group: D23

Controllino PORTS

In order to see which Controllino pin corresponds to which PORT on microprocessor open the Controllino PINOUT tables.
Link to PINOUT table is here.

IMPORTANT INFORMATION!
Please, select proper target board in Tools->Board->Controllino MINI/MAXI/MEGA before Upload to your CONTROLLINO.
(Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

Hardware Required

  • Controllino MINI/MAXI/MEGA
  • 12/24V DC Power supply

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

To  check where is the Overload LED connected we open the PINOUT table of the Controllino and find it.

Here we can see that the OVL LED is connected to the 7th bit of the PORT E on ATmega2560. There is no arduino number for this pin so we cannot set it like other arduino i/o pins.
The manipulation of this pin is shown in the next example:

void setup() 
{

 //Define the LED as an OUTPUT
 DDRE = DDRE | B10000000;
 
}

void loop() 
{

 //Set the 7th bit of the PORT E to HIGH without influence on other bits (OR logic)
 PORTE = PORTE | B10000000;
 delay(1000);
 //Set the 7th bit of the PORT E to LOW without influence on other bits (AND logic)
 PORTE = PORTE & B01111111;
 delay(1000);
 
}

To check the state of the Overload LED:

void setup() 
{
 Serial.begin(9600);
 DDRE = DDRE & B01111111; //Set PE7 (OVL pin) as INPUT
 Serial.println("CONTROLLINO Overload read:");
}

void loop() 
{
 Serial.print("Overload signal: ");
 int Overload_signal = PINE >> 7;
 if (Overload_signal == 1) Serial.println("OFF");
 else Serial.println("ON");
 delay(1000);
}

The MAXI Automation is the version of Controllino MAXI specifically tailored for the needs of automation specialists! It is the perfect compromise between compact size and big input and output number. The core competence is its flexibility.
In this example the usage of Controllino real analog (0-10V) outputs will be shown.
Controllino Maxi Automation has special:

  • 2x Analog Inputs 0-10V
  • 2x Analog Outputs – 0-10V (0-20mA)

If you need two current (0-20mA), and not voltage (0-10V) outputs for your project, you can change them into current outputs by simply removing two 0 Ω resistors on Maxi Automation controll board. This process will be shown in next steps.

Hardware Required

  • Controllino MAXI Automation
  • 24V DC Power supply
  • Soldering iron
  • Tweezers

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

Controllino MAXI Automation

To set your real analog outputs for your needs you can use the builtin example from Controllino Library, or you can copy the example from below.

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */

// the setup function runs once when you press reset (CONTROLLINO RST button) or connect the CONTROLLINO to the PC
void setup() {
 // initialize all used digital output pins as outputs
 pinMode(CONTROLLINO_AO0, OUTPUT);
 pinMode(CONTROLLINO_AO1, OUTPUT);                            
}

// the loop function runs over and over again forever
void loop() {
 int analogOut0 = 127;                     // 0 - 255 to be set (0 - 10 000 mV, or 0 - 20 000 uA)
 int analogOut1 = 255;                     // 0 - 255 to be set (0 - 10 000 mV, or 0 - 20 000 uA)
 analogWrite(CONTROLLINO_AO0, analogOut0); // set the analog output 0 to 5V or 10mA
 analogWrite(CONTROLLINO_AO1, analogOut1); // set the analog output 1 to 10V or 20mA                      
}

If you are not able to compile the sketch, choose the Controllino MAXI Automation board!
To make the outputs and relays work, CONTROLLINO pins have to be set up as OUTPUTs!

*pinMode(CONTROLLINO_xx, OUTPUT);

Steps

In the following steps we will show you how to turn the voltage to the current outputs.

Step 1:

Remove the Controllino MAXI Automation cover by lifting marked sides of the cover with flat-head screwdriver:

Step 2:

Remove the plastic sides and disconnect the Controllino connection board

from the Controllino MAXI Automation.

Step 3:

Locate the two 0 Ω resistors of the Controllino relay board:

 

Step 4:

In order to get the two current outputs (0-20 mA) on Controllino MAXI Automation, apply heat and take the tweezers to remove two 0 Ω resistors:


To get back the voltage outputs (0-10V), simply solder the resistors back on Controllino MAXI Automation control board.

Note*
To test the outputs use previous example or example from the CONTROLLINO library for the Controllino MAXI Automation.
0-10 V -> 0-20 mA
If you are not able to compile the sketch, choose the Controllino MAXI Automation board!

Interrupts are useful for automatically executing things in microcontroller programs and can solve timing problems. Good tasks for using an interrupt may include reading a rotary encoder or monitoring user input.
The Arduino Uno has 2 and the Mega has 6 external interrupt pins available:

  • Arduino Uno/Controllino MINI/INT.x interrupt:                   2/IN0/INT.0  –  3/IN1/INT.1 
  • Arduino Mega/Controllino MAXI,MEGA/INT.x interrupt: 2/D0/INT.0  –  3/D1/INT.1  –  18/IN0/INT.5  –  19/IN1/INT.4  –  20/SDA/INT.3  –  21/SCL/INT.2

On the other hand the pin change interrupts can be enabled on many more pins.

Hardware Required

  • Controllino MINI/MAXI/MEGA
  • 12/24V DC Power supply

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

Controllino MINI/MAXI/MEGA

#include <Controllino.h>

const byte digital_output = CONTROLLINO_D0;
const byte interruptPin = CONTROLLINO_IN1;
volatile byte state = LOW;

void setup() {
 pinMode(digital_output, OUTPUT);
 pinMode(interruptPin, INPUT);
 attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
 digitalWrite(digital_output, state);
}

void blink() {
 state = !state;
}

Controllino MEGA has 24 High Side digital outputs available. The first 20 outputs we can control using the standard Arduino functions (e.g. digitalWrite and analogWrite), but for D20-D23 digital outputs we have to know how to use PORT manipulation on ATmega2560. On the connection picture we can see that there are no Arduino pins assigned to these outputs.

To see more about PORT manipulation please click here.

Hardware Required

  • Controllino MEGA
  • 12/24V DC Power supply

Circuit

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

Controllino MEGA

void setup() 
{
 DDRD = DDRD | B01110000; //Set the ports PD4, PD5, PD6 as outputs
 DDRJ = DDRJ | B00010000; //Set the port PJ4 as output
}

void loop() {
 int del = 100;
 //Digital output 20
 PORTD = PORTD | B00010000; //Set HIGH
 delay(del); 
 PORTD = PORTD & B11101111; //Set LOW
 delay(del);

}


/*
//Digital output 21
 PORTD = PORTD | B00100000;
 delay(del); 
 PORTD = PORTD & B11011111;
 delay(del);


//Digital output 22
 PORTD = PORTD | B01000000;
 delay(del); 
 PORTD = PORTD & B10111111;
 delay(del);
 

//Digital output 23
 PORTD = PORTD | B10000000;
 delay(del); 
 PORTD = PORTD & B01111111;
 
 
 PORTJ = PORTJ | B00010000;
 delay(del); 
 PORTJ = PORTJ & B11101111;
 delay(del);

 
 PORTD = PORTD | B01110000; // sets Digital Outputs 20,21,22 in one shot to HIGH
                            // -> turns the LEDs ON
 PORTJ = PORTJ | B00010000; // sets Digital Output 23 in one shot to HIGH 
                            // -> turns the LED ON


 PORTD = PORTD & B10001111; // sets Digital Outputs 20,21,22 in one shot to LOW 
                            // -> turns the LEDs OFF
 PORTJ = PORTJ & B11101111; // sets Digital Output 23 in one shot to LOW
                            // -> turns the LED OFF
*/

The LiquidCrystal library allows you to control LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface.

This example sketch prints “Hello World!” to the LCD and shows the time in seconds since the Arduino was reset.

To see more about 16×2 LCD and related pins please visit https://www.arduino.cc/en/Tutorial/HelloWorld?from=Tutorial.LiquidCrystal

Hardware Required

  • Controllino MINI/MAXI/MEGA
  • 12/24V DC Power supply
  • 16×2 LCD
  • 10k ohm potentiometer
  • hook-up wires

Circuit

Instead of the pins that we use in this example you can use every other communication, output and input pin. We suggest to use first communication and output pins because of internal resistors and then input pins.
In this example we don’t need UART and SPI communication and we are using these pins to have all input and output pins free.

Note*
Pin header is working on 5V TTL levels. Voltage levels over 5.5V can damage the Controllino permanently.

Code

Controllino MAXI

/*
 LiquidCrystal Library - Hello World

 Demonstrates the use a 16x2 LCD display. The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>
//#include <Controllino.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(1, 0, 53, 51, 50, 52);

void setup() {
 
 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
 
 // Print a message to the LCD.
 lcd.print("Controllino MAXI");
 
}

void loop() {
 
 // set the cursor to column 0, line 1
 // (note: line 1 is the second row, since counting begins with 0):
 
 lcd.setCursor(0, 1);
 
 // print the number of seconds since reset:
 lcd.print("Hello World!");
 
 delay(5);
 
}