RS-485 on Plug & Sense!

The RS-485 protocol is available for Plug & Sense! as a secondary communication module. This is an optional feature. The RS-485 module is placed on socket 0 by default, being accessible through an additional and dedicated socket on the antenna side of the enclosure. On the other hand, the main radio interface of the Plug & Sense! device is placed on socket 1.

Figure: Industrial Protocols available on Plug & Sense!

The user can choose between 2 probes to connect the RS-485 protocol: A standard DB9 connector and a waterproof terminal block junction box. These options make the connections on industrial environments or outdoor applications easier.

Figure: DB9 probe connected to Plug & Sense!

Figure: Terminal box probe connected to Plug & Sense!

The RS-485 signals are wired on the female DB9 connector and on the Terminal box according to the next table.

Note: The DB9 connector pinout on the external device could have different wiring. So please ensure all the signals involved with the communication between Plug & Sense! and the external device are properly wired.

Figure: Wiring of RS-485 signals on Plug & Sense!

Applications

This module allows the user to interface the Waspmote ecosystem with RS-485 systems. Waspmote allows to perform three main applications:

1- Connect any sensor to an existing RS-485 device/network

Waspmote can be configured to work as a node in the network, inserting sensor data into the RS-485 bus already present. Waspmote can obtain information from more than 70 sensors which are currently integrated in the platform by using specific sensor boards (e.g: CO, CO2, temperature, humidity, acceleration, pH, IR, luminosity, etc). This way, the sensor information can be read from any RS-485 device connected to the bus.

Figure: Waspmote integrated in an RS-485 network

2- Add wireless connectivity to RS-485 devices

Waspmote can be configured to read the information coming from the RS-485 bus and send it wirelessly using any of the wireless modules available in the platform to a base station or even directly to a Cloud server. The available wireless technologies are: 802.15.4, ZigBee, DigiMesh, 868 MHz, 900 MHz, LoRa, WiFi, GPRS, GPRS+GPS, 3G, 4G, Sigfox, LoRaWAN, Bluetooth Pro, Bluetooth Low Energy and RFID/NFC.

Figure: Waspmote replacing wired connections

3- Connect to the Cloud RS-485 devices

Waspmote can be configured to read the information coming from the RS-485 bus and send it wirelessly directly to the Cloud using WiFi, GPRS, GPRS+GPS, 3G and 4G radio interfaces.

Figure: Cloud connection

Libelium's library

It is mandatory to include the RS-485 library when using this module. The following line must be introduced at the beginning of the code:

#include <Wasp485.h>

Waspmote's API RS-485 files:

  • Wasp485.cpp

  • Wasp485.h

APIs functions

- Private functions:

The following functions are executed inside the API functions. In normal conditions, the user must NOT manage or use them.

Private functions

Definition

void maxWrite(char address , char data)

Writes data in the MAX3107 address.

uint8_t maxRead(char address)

Reads a data from the MAX3107. Returns the read data.

void begin(void)

Configures the MISO, MOSI, CS, SPCR.

void setBitOrder(uint8_t bitOrder)

Sets most significant bit first.

void setClockDivider(uint8_t rate)

Set the SPI clock divider relative to the system clock.

void setDataMode(uint8_t mode)

Sets the SPI data mode: that is, clock polarity and phase.

uint8_t transfer(uint8_t _data)

Transfers one byte over the SPI bus, both sending and receiving.

void printIntegerInBase(unsigned long n , uint8_t base)

Prints an integer in a given base.

-Public functions:

Public function

Definition

uint8_t ON(void)

Powers the RS-485 module and opens the SPI

OFF(void)

Switches off the module and closes the SPI

uint8_t baudRateConfig(unsigned long speed)

It sets the speed of communication

parityBit(bool state)

Enable or disable the parity bit

stopBitConfig(uint8_t numStopBits)

Selects the number of stop bits to be inserted by the Transmitter

uint8_t read(void)

Receives data through the SPI.

send(n)

Sends data n through the SPI bool

reset(void)

All register bits are reset to their reset state and all FIFO buffers are cleared

flush(void)

Clear both the receive and transmit FIFOs of all data contents

bool noiseReception(void)

If noise is detected on the RX input during reception of a character

uint8_t available(void)

Returns true when the buffer is empty

transmission(bool state)

Disable/Enable transmission

reception(bool state)

Disable/Enable the receiver

Library functions

Library constructor

To start using Waspmote RS-485 library, an object from class Wasp485 must be created. This object, called W485, is created inside Waspmote RS-485 library and it is public to all libraries. It is used through this guide to show how Waspmote RS-485 library works. When creating this constructor, all the variables are defined with an initial value by default.

Switching the module on

This function powers the RS-485 module and configures the SPI bus. The default baud rate is 1200 bps and it can be modified by the function baudRateConfig(). The RS-485 module can be used only in the socket 0. This function is necessary to configure the module, so the RS-485 module must be plugged before, and returns zero, if the module has been configured correctly.

// Include always this library when you are using the Wasp485 functions
#include <Wasp485.h>
void setup()
{
// Powers on the module and assigns the SPI in socket0
if (W485.ON() == 0)
{
USB.println("RS-485 module started successfully");
}
else
{
USB.println("RS-485 did not initialize correctly");
}
}

You can see how to use this function in this example:

Switching the module off

Switches off the RS-485 module and stops sending data frames. This function will disconnect the supply of the module so all data stored on the stack will be lost.

Example of use:

{
// Switches off the module and closes the SPI
W485.OFF();
delay(100);
}

Configuring speed communication

The RS-485 module communication can be configured with the standard values of the RS-485 protocol. RS-485 module has been tested with 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200bps, 230400bps and 460800bps. All these speeds make RS-485 module very compatible with other devices. When a non-defined speed is introduced, the module is configured with the lowest communication speed (1200bps). The RS-485 module don't use a clock signal so the baud rate of all devices in a network must be configured before starting the communication.

// Include always this library when you are using the Wasp485 functions
#include <Wasp485.h>
void setup()
{
// Power on the USB for viewing data in the serial monitor
USB.ON();
delay(100);
// Powers on the module and assigns the SPI in socket0
W485.ON();
delay(100);
// Configure the baud rate of the module
W485.baudRateConfig(9600);
}

You can see how to use this function in this example:

Configuring the number of stop bits

The most common configuration used between computers is 8N1: eight bit characters, with one stop bit and no parity bit. With the RS-485 module you can configure the communication mode with one or two stop bits using the next function.

Example of use with one stop bit:

// Include always this library when you are using the Wasp485 functions
#include <Wasp485.h>
void setup()
{
// Power on the USB for viewing data in the serial monitor
USB.ON();
delay(100);
// Powers on the module and assigns the SPI in socket0
W485.ON();
delay(100);
// Configure the baud rate of the module
W485.baudRateConfig(9600);
// Use one stop bit configuration
W485.stopBitConfig(1);
}

You can see how to use this function in this example:

Example of use with two stop bits:

//Include always this library when you are using the Wasp485 functions
#include <Wasp485.h>
void setup()
{
// Power on the USB for viewing data in the serial monitor
USB.ON();
delay(100);
// Powers on the module and assigns the SPI in socket0
W485.ON();
delay(100);
// Configure the baud rate of the module
W485.baudRateConfig(9600);
// Use one stop bit configuration
W485.stopBitConfig(2);
}

You can see how to use this function in this example:

Configuring the parity bit

Parity is used in many hardware applications to detect frame errors and is usually generated and checked by interface hardware. The RS-485 module uses an odd parity. Parity can be enabled or disabled depending on communication requirements.

Example of use with no parity:

//Include always this library when you are using the Wasp485 functions
#include <Wasp485.h>
void setup()
{
// Power on the USB for viewing data in the serial monitor
USB.ON();
delay(100);
// Powers on the module and assigns the SPI in socket0
W485.ON();
delay(100);
// Configure the baud rate of the module
W485.baudRateConfig(9600);
// Configure the parity bit as disabled
W485.parityBit(DISABLE);
// Use one stop bit configuration
W485.stopBitConfig(1);
// Print hello message
USB.println("Hello this is RS-485 communication send data example.");
}

You can see how to use this function in this example:

Example of use with parity enabled:

//Include always this library when you are using the Wasp485 functions
#include <Wasp485.h>
void setup()
{
// Power on the USB for viewing data in the serial monitor
USB.ON();
delay(100);
// Powers on the module and assigns the SPI in socket0
W485.ON();
delay(100);
// Configure the baud rate of the module
W485.baudRateConfig(9600);
// Configure the parity bit as disabled
W485.parityBit(ENABLE);
// Use one stop bit configuration
W485.stopBitConfig(1);
// Print hello message
USB.println("Hello, this is RS-485 communication send data example");
}

You can see how to use this function in this example:

Reset

After using this function all register bits are reset to their reset state and all FIFOs are cleared.

{
// Resets the W485 module and clear the buffers
W485.reset();
}

Sending data

Thanks to method overloading you can send any data through the SPI with the same function send().

You can see how to use this function in this example:

Sending a char

The most common way to send a character is to send it between single quotes (e.g. 'p').

Example of use:

{
char data = 'p';
// Send data through UART
W485.send(data);
}

You can also send char variables by declaring the corresponding ASCII code. For example, if you initialize a char with "123", it sends the corresponding ASCII "{".

Example of use:

{
char data = 123;
// Send data through UART
W485.send(data);
}

Sending an integer

You can send an unsigned or signed integer using the same function. If an unsigned int is declared you can assign a value from 0 to 65535 and if the variable is signed the value can be between -32768 and 32767.

Example of use:

{
unsigned int data = 12345;
// Send an unsigned int
W485.send(data);
}
{
int data = -12345;
// Send a signed int
W485.send(data);
}

Sending a string

The same function could be uses for sending string of characters.

Example of use:

{
// Send a string trough the SPI
W485.send(“Hello world”);
}

Sending with base

Send function allows to represent the variable in a specific base. You can select binary, octal, byte, decimal, and hexadecimal representation.

Example of use:

{
int data = 12345;
// Send 12345 in binary base. It prints 0110 000 0011 1001.
W485.send(data, BIN);
// Send 12345 in octal base. It prints 30071.
W485.send(data, OCT);
// Send 12345 in decimal base. It prints 12345.
W485.send(data, DEC);
// Send 12345 in hexadecimal base. It prints 3039.
W485.send(data, HEX);
}

Sending a long

Long variables can be sent also with the function send. Long variables represent 32 bits or 4 bytes and the send() function allows signed and unsigned declaration.

Example of use:

{
unsigned long data = 1234567;
// Send and unsigned long
W485.send(data);
}

Receiving data

The RS-485 module has a 128-byte buffer. This bytes can be read with the function read(). This function returns the read value from the buffer.

{
// If data in response buffer
if (W485.available())
{
while (W485.available())
{
// Read one byte from the buffer
char data = W485.read();
// Print data received in the serial monitor
USB.print(data);
}
}
delay(1);
}

You can see how to use this function in this example:

Data available

This function returns the number of bytes available in the RS-485 buffer.

{
// If data in response buffer
if (W485.available())
{
while (W485.available())
{
// Read one byte from the buffer
char data = W485.read();
// Print data received in the serial monitor
USB.print(data);
}
}
delay(1);
}

You can see how to use this function in this example:

Flush function

Flushes the buffer of incoming serial data. The flush() function waits for outgoing data to transmit before clearing the buffer content.

{
// Flushes the buffer
W485.flush();
delay(10);
}

Tranmission control

Use this function to enable/disable transmission. If the transmission is disabled during transmission, the transmitter completes sending out the current character and then ceases transmission. Data still present in the transmit FIFO remains. The TX output is set to logic-high after transmission.

Example of use:

{
// Disable the transmission
W485.transmission(DISABLE);
}

You can see how to use this function in this example:

The transmission could be enabled again by using the same function as we can see below.

Example of use:

{
// Enable the transmission
W485.transmission(ENABLE);
}

Reception control

Use this function to disable the receiver so that the receiver stops receiving data. All data present in the receive FIFO remains.

Example of use:

{
// Disable the reception
W485.reception(DISABLE);
}

The reception could be enabled again by using the same function as we can see below.

Example of use:

{
// Disable the reception
W485.reception(ENABLE);
}