Arduino: 4–20mA thermometer

Feb 22, 2019 0 comments

In today’s blog post I will show you how to make an Arduino based thermometer with 4–20mA communication bus.

The project uses two Arduino Uno boards, one for the transmitter and one for the receiver. Each of the Arduino boards was equipped with one Arduino Uno click shield.

The transmitter uses the DHT22 click board placed in mikroBUS socket #1 and the 4–20mA T click boards from MikroElektronika, which was placed in socket #2. Both click boards were configured for 5V logic level operation. By the way the 4–20mA T click is designed, the transmitter must be powered from an external source; it cannot receive power from the 4–20mA bus.

The receiver uses the 4–20mA R click board and the LCD mini click board also from MikroElektronika. The LCD mini click board is placed in mikroBUS socket #1, while the 4–20mA R click board is in socket #2. Also, both boards were configured for 5V operation.

The calibration of the current loop was performed using the simplified procedure described in this post, and the following values were obtained:

for the transmitter

  •     DAC_4mA = 804
  •     DAC_20mA = 3970

for the receiver

  •     ADC_4mA = 791
  •     ADC_20mA = 3941

Below is the code for the transmitter:

Note that, although the DHT22 sensor can measure both temperature and humidity, only one variable can be sent over the 4–20mA bus. In our code example, that variable is the temperature.

As per DHT22 datasheet, the temperature is in the range of -40 C to 80C. That range is used to scale the data: a temperature of -40C will correspond to a 4mA current; a temperature of 80C will correspond to a 20mA current.

In the code, the DHT22 sensor returns the temperature as a float number. But some of the Arduino functions like constrain() and map() use integer math. Thus, the temperature is multiplied by 100 and then cast as an integer. Then, using the temperature range and the calibration values, the temperature is converted to DAC data as in int temp = map(transmitted_Value, data_min_range, data_max_range, DAC_4mA, DAC_20mA);

The code for the receiver is listed below:

In this code we aim to read the current flowing through the 4–20mA bus and to convert it back to temperature values, based on the already known ADC_4mA, ADC_20mA calibration values and knowing the temperature range. Again, we use integer math to do this conversion: received_data = map(loop_current, ADC_4mA, ADC_20mA, data_min_range, data_max_range); Then we divide by 100 to get the decimals back where they belong, and we send the data to the LCD.

Related Posts


{{posts[0].date}} {{posts[0].commentsNum}} {{messages_comments}}


{{posts[1].date}} {{posts[1].commentsNum}} {{messages_comments}}


{{posts[2].date}} {{posts[2].commentsNum}} {{messages_comments}}

Contact Form


Email *

Message *

Recent Comments