Skip to content

Instantly share code, notes, and snippets.

@Electronza
Created December 5, 2019 08:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Electronza/8aa23a55e59e61c1509f09036a152d16 to your computer and use it in GitHub Desktop.
Save Electronza/8aa23a55e59e61c1509f09036a152d16 to your computer and use it in GitHub Desktop.
/*
4-20mA Thermometer using Mikroe click boards
https://electronza.com/arduino-4-20ma-thermometer/
Part I - 4-20mA T click transmitter code
*/
#include <SPI.h>
// REQUIRES the following Arduino libraries:
// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor
#include "DHT.h"
// Arduino UNO with Mikroe Arduino Uno Click shield
// 4-20mA is placed in socket #2
// CS is pin 9
// SCK is pin 13
// MISO is pin 12
// MOSI is pin 11
#define DAC_CS 9
#define DHTPIN 10 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
// Calibration data obtained by running the calibration code
const int DAC_4mA = 804;
const int DAC_20mA = 3970;
// Data min and max range
const int data_min_range = -4000;
const int data_max_range = 8000;
// DHT22 returns temperature as float
float t;
// Debug mode? (1 - debug, 0 - no debug);
bool debug_mode = 1;
// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);
void setup() {
// Are we in debug mode
if (debug_mode == 1){
// Initialize serial
Serial.begin(9600);
}
// Initialize SPI
pinMode(DAC_CS, OUTPUT);
digitalWrite(DAC_CS, 1);
SPI.begin();
dht.begin();
}
void loop() {
// Read temperature as Celsius (the default)
t = dht.readTemperature();
// Are we in debug mode
if (debug_mode == 1){
// Print information
Serial.print("Temperature is: ");
Serial.println(t);
}
t = (int)(t*100);
// Constrain it to -40 - +80 C
t = constrain (t, data_min_range, data_max_range);
SendTo420mA(t);
// Update every 10 seconds
delay(1000);
}
void set_DAC(uint16_t set_value){
/*
DAC works on SPI
We must send 16 bits
byte1 is [WR, BUF, /GA, /SHDN, data11, data10, data9, data8]
byte2 is [data7, data6, data5, data4, data3, data2, data1, data0]
Write code
WR 0 - write to DAC register
1 - Ignore this command
VREF Input Buffer Control bit
BUF 0 - Unbuffered
1 - Buffered
Output Gain Selection bit
/GA 0 - 1x (VOUT = VREF * D/4096)
1 - 0 = 2x (VOUT = 2 * VREF * D/4096)
Output Shutdown Control bit
/SHDN 0 - Shutdown the device. Analog output is not available.
1 - Active mode operation. VOUT is available
WR has to be 0 to write to DAC registers
BUF is set to 0 (unbuffered)
GAIN MUST BE SET TO 1. We can't output more than the Vcc!!!
SHDN also set to 1 to have DAC active.
00110000 = 0x30
*/
byte first_byte;
byte second_byte;
first_byte = (set_value >> 8) & 0x0F;
first_byte = first_byte | 0x30;
second_byte = set_value & 0xFF;
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(DAC_CS, 0);
SPI.transfer(first_byte);
SPI.transfer(second_byte);
digitalWrite(DAC_CS, 1);
SPI.endTransaction();
// Are we in debug mode
if (debug_mode == 1){
// Print information
Serial.print("DAC is set to: ");
Serial.println(set_value);
Serial.println();
}
}
void SendTo420mA(unsigned int transmitted_Value)
{
// Map the data to be sent into DAC values
// that result in a loop current between 4 and 20mA
int temp = map(transmitted_Value, data_min_range, data_max_range, DAC_4mA, DAC_20mA);
// update the current loop
set_DAC((uint16_t)temp);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment