Tools40 Library, Useful tool using our equipments

January 11, 2019 by
Tools40 Library, Useful tool using our equipments
Boot & Work Corp. S.L., Support Team

Introduction

Arduino Tools40 is a comprehensive library that provides a set of essential functions and modules designed for industrial environment firmware, specifically tailored for Arduino and ESP32 based devices.

WARNING: Both ModbusTCPMaster and ModbusTCPSlave are only available for Industrial Shields devices. Also the Pulses library is only available for Industrial Shields Arduino-based devices.

Getting started

Prerequisites

  1. The Arduino IDE 1.8.19.
  2. The Industrial Shields Arduino boards or the Industrial Shields ESP32 boards equivalent (optional, used in the examples).

Installing

1. Download the library from the GitHub as a "ZIP" file.

2. From the Arduino IDE, select the downloaded "ZIP" file in the menu "Sketch/Include library/Add .ZIP library".

3. Now you can open any example from the "File/Examples/Tools40" menu.

Modules

Modbus

Modbus is a communication protocol situated at various levels of the OSI Model (1, 2, and 7). Initially developed in 1979 by Modicon for its line of PLCs, it follows a master/slave architecture. This architecture requires one device as the master, to initiate communication with one or more devices (the slaves). The master device sends requests to read or write data to specific memory locations (registers) within the slave devices. In response, the slave devices provide the requested data or acknowledge the received command.

Modbus can work over different physical communication mediums, including serial communication (Modbus RTU and Modbus ASCII) and Ethernet (Modbus TCP). The serial versions are often used in legacy systems, while Modbus TCP has gained popularity with the increasing adoption of Ethernet-based industrial networks.

The protocol is known for its simplicity, ease of implementation, and widespread support in the industrial automation industry. It is an open protocol, making it easy for different manufacturers to incorporate Modbus compatibility into their devices. Due to its long history and proven reliability, Modbus remains a fundamental and widely used communication standard for industrial applications, allowing various devices from different manufacturers to communicate seamlessly within a network.

Our library is compatible with both ModbusRTU (RS-485/RS-232, UART...) and ModbusTCP (WiFi or Ethernet). For practical demonstrations, you can explore the examples provided in the following links:

SimpleComm

One of the modules we offer with our PLCs is the SimpleComm library. This library allows you to send data via any data stream: RS-485, RS-232, Ethernet... The flexibility of this library allows it to adapt to different types of communication such as Ad-Hoc, Master-Slave, Client-Server, etc. using an easy-to-use API.

Usage

The SimpleComm module enables bi-directional, non-blocking data over all available streams (such as UARTS, RS-485, WiFi...). And to optimize data encapsulation, the SimplePacket class is used to neatly pack the data into an efficient structure.

To store data in a packet, you can use the setData function, which supports a wide range of data types, including bool, char, unsigned char, int, unsigned int, long, unsigned long, double, string and even custom data types. In addition, the SimplePacket class includes "getter" functions to retrieve the data stored in the packet, catering for specific data types. If maximum length is specified, it returns the length of the data in bytes.

The SimpleComm singleton is the interface for sending and receiving packets through the desired data stream. The communication system is initiated and configured using the "begin(address)" function. This function not only activates the communication process, but also establishes a unique identifier or address for each device. Each device has its own unique address, allowing it to selectively receive packets destined for its address while packets intended for other devices.

The following methods can be used to send a packet to a destination:

	​SimpleComm.send(stream, packet, destination)
	​SimpleComm.send(stream, packet, destination, type)

The function also accepts a packet type, which serves the purpose of informing the receiver about how to interpret and read the contents of the packet accurately.

The receive function is responsible for fetching a packet from another device through the designated stream:

	​SimpleComm.receive(stream, rxPacket)

If a packet is indeed received, the function returns true, indicating successful reception; otherwise, it returns false.

Compatibility between architectures

This library relies on standard C++ types (e.g., unsigned long, int) which will work correctly if the communicating architectures maintain consistent type sizes. However, problems can arise when trying to communicate between different CPU architectures, such as ESP32 and Arduino. The C++ types defined in each architecture have different sizes, which will cause communication errors.

To ensure proper communication between different architectures and to address potential type size issues, the library provides a solution through the SimplePacketConfig.h header file. This file allows the user to customize the types used in the library, thereby fixing the size of the types for proper communication:

  • If you uncomment "#define UNIVERSAL_CPP", the types used will be the minimum size according to the C++ standard.
  • If you uncomment "#define CUSTOM_TYPES", the types used will be the size of what you define.

Filter

The filter module is a software component designed to effectively smooth unstable analogue inputs. This is very useful when dealing with erratic analogue signals. To define an analogue filter, you need to specify two parameters, the number of samples and the sample period. For instance:

	​​AnalogFilter<10, 2> aFilter;

In this example, the sample time is set to 2ms, and the number of samples is 10.

You can also initialize the filter constructor with an initial value, like this:

	​​AnalogFilter<10, 2> aFilter(24000);

Here, the filter is initialized with an initial value of 24000 instead of the default value of 0. To obtain the filtered value based on the input, you can use the update function as follows:

	​int input = analogRead(I0_0);
​	​int filteredInput = aFilter.update(input);

The update function takes the input value as an argument and returns the corresponding filtered value.

Timer

The Timer module provides three different types of timer, each following standard timer schemes:

  • PulseTimer: When there is a rising edge on the input value, PulseTimer enables the output during the selected time.
    int in = digitalRead(I0_0);if (PT.update(in) == HIGH) {
      // Enter here during 1000ms after in is rised
    }
  • OnDelayTimer: When the input is HIGH during the defined time, the related output will be HIGH. The output will only be disabled when input goes LOW again.
    int in = digitalRead(I0_0); if (TON.update(in) == HIGH) {
      // Enter here after I0.0 is HIGH during 1000ms and until it becomes LOW
    }
  • OffDelayTimer: When the input is LOW during the defined time, the related output will be HIGH. The output will only be disabled when input goes HIGH again.
     int in = digitalRead(I0_0); if (TOFF.update(in) == HIGH) {
      // Enter here after I0.0 is LOW during 1000ms and until it becomes HIGH
    }

Counter

The Counter module offers a method of counting rising edges until a user defined preset value is reached.

	​Counter C(100);

The Counter module returns HIGH when the internal counter equals the preset value. Below is an example to demonstrate its use:

int up = digitalRead(I0_0);
int down = digitalRead(I0_1);
int reset = digitalRead(I0_2);
if (C.update(up, down, reset, preset) == HIGH) {
​// Enter here when the counter is equal to 100
​// The counter counts up when I0.0 rises​​
​// The counter counts down when I0.1 rises
​​// The counter is set to zero when I0.2 is HIGH
}

Pulses (only for Arduino)

The Pulses module provides functions for starting and stopping a series of pulses at a user-defined frequency. The function startPulses(pin, frequency, precision) starts a pulse sequence with the given frequency and precision. The default values are set to 1kHz for frequency and 3 for precision if not specified.

On Ardbox Analog it is possible to use this functions in outputs:

  • TIMER0: Q0.1 and Q0.6
  • TIMER1: Q0.2 and Q0.3
  • TIMER3: Q0.5

On MDUINO-21, MDUINO-42 and MDUINO-58 it is possible to use this functions in outputs:

  • TIMER0: Q0.5 and Q2.6
  • TIMER1: Q2.5
  • TIMER2: Q1.5 (Multiply the frequency x2)
  • TIMER3: PIN2, PIN3 and Q0.6
  • TIMER4: Q0.7, Q1.6 and Q1.7
  • TIMER5: Q1.3, Q1.4 and Q2.0

There are 5 levels of accuracy in total, and each level corresponds to a specific frequency range. To obtain a high accuracy for the desired frequency, you must select the lowest precision level that has a range in which you can fit your desired frequency. The ranges are:

  • Precision = 1: from 30Hz to 150Hz
  • Precision = 2: from 150Hz to 500Hz
  • Precision = 3: from 500Hz to 4kHz
  • Precision = 4: from 4kHz to 32kHz
  • Precision = 5: from 32kHz to 4MHz

IMPORTANT: Outputs that share the same timer cannot use different frequencies.

CAUTION!!! When the TIMER0 pins are used, all time-related functions will lose their functionality. This includes functions like as "delay()", "millis()", "micros()", "delayMicroseconds()" and others.

Search in our Blog

Tools40 Library, Useful tool using our equipments
Boot & Work Corp. S.L., Support Team January 11, 2019
Share this post
Archive

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.


Industrial PLC comparison >>>