Arduino: 4–20mA thermometer

Teodor Costachioiu
Feb 22, 2019 · 3 min read
Image for post
Image for post

I 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 MikroEkeltronika, 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.

Image for post
Image for post

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.

Image for post
Image for post

As a prerequisite, this project requires the following libraries to be installed:

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.

From the same series

Originally published at on February 22, 2019. Moved to Medium on April 23, 2020.


DIY electronics projects and more

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store