0_10V and 4_20 ma in the same sketch

Can the ADCs be configured for both 0_10V and 4_20 ma in the same sketch? I'd like to read sensors with both outputs at the same time. Thanks!

Do your sensors have both outputs? You could turn the 0-10VDC output into an Arduino-compatible 0-5V with a voltage divider, and turn the 4-20mA into an Arduino Compatible 1-5V with a 250ohm resistor.

How safe, reliable, and isolated do you need to make things?

1 Like

Hi @adugenske,

Yes this functionality is possible but its not officially supported even though the documentation states otherwise.

There is a pull request open for this functionality and I have logged a support ticket with Arduino support this month to try and get it closed.

If like me, you cannot wait for the official release then try this:

git clone https://github.com/SJThomas29/Arduino_MachineControl.git

I have created the following sketch based on the library source from SJThomas29 and the PMC examples:

/*
  Machine Control - Individual analog inputs

  0-10V
  4..20 mA
  NTC
*/

// Disable official library
//#include <Arduino_MachineControl.h>

// Modified library
// Source: https://github.com/SJThomas29/Arduino_MachineControl
#include "Arduino_MachineControl/src/Arduino_MachineControl.h"
using namespace machinecontrol;

const int SENSE_RES = 120;
const float RES_DIVIDER = 0.28057;
const float LOWEST_VOLTAGE = 2.7;
const float REFERENCE_RES = 100000;
// Corrected 3.0V reference
// https://github.com/arduino-libraries/Arduino_MachineControl/pull/94
const float REFERENCE = 3.0;

void setup() {
  Serial.begin(115200);

  unsigned long startSetup = millis();
  while (!Serial) {
    if (millis() - startSetup > 5000) { // Time override: 5 seconds
      break;
    }
  }

  // Setup analog reads
  analogReadResolution(16);
  // AI0 0-10V
  analog_in.set0_10V(0);
  // AI1 
  analog_in.set4_20mA(1);
  // AI2 
  analog_in.set0_10V(2);
}

void loop() {
  // 0-10V
  float raw_voltage_ch0 = analog_in.read(0);
  float voltage_ch0 = (raw_voltage_ch0 * REFERENCE) / 65535 / RES_DIVIDER;

  // 4..20mA
  float raw_voltage_ch1 = analog_in.read(1);
  float voltage_ch1 = (raw_voltage_ch1 * REFERENCE) / 65535;
  float current_ch1 = (voltage_ch1 / SENSE_RES) * 1000;

  // NTC
  float raw_voltage_ch2 = analog_in.read(2);
  float voltage_ch2 = (raw_voltage_ch2 * REFERENCE) / 65535;
  float resistance_ch2;
  if (voltage_ch2 < LOWEST_VOLTAGE) {
    resistance_ch2 = ((-REFERENCE_RES) * voltage_ch2) / (voltage_ch2 - REFERENCE);
  } else {
    resistance_ch2 = -1;
  }

  // For use with Serial plotter
  Serial.print(voltage_ch0);
  Serial.print(" ");
  Serial.print(current_ch1);
  Serial.print(" ");
  Serial.print(resistance_ch2);
  Serial.print(" ");
  Serial.println();
  delay(250);
}


I have tested a 0-10V input on AI0 and 4..20mA input on AI1 and they are both working simultaneously. I have added the NTC input for completeness but it is untested. I hope this helps!

@thebeest, Thank you very much for the quick response and the excellent input! I'll implement your recommendations and confirm that it works for me to give others confidence.

Really glad I could help out @adugenske. I just happened to be working on the solution yesterday and was searching the forums 4..20mA inputs and found your post. Thanks for commenting on the PR too, fingers crossed Arduino will get it closed soon and we don't have to use this workaround for any longer than necessary!

It may be worth noting that the analog input readings do seem to fluctuate quite a bit and you will likely have to smooth this out in software. I have found that the RunningAverage library does a nice job of this.

For example I have my bench PSU set to 5.009V which gives me 5.000V at the PMC and my readings over 5 minutes range from 4.814V to 4.836V. Similarly I have 4..20mA T2000 pressure transducer measuring a static pressure and its values range from 14.942mA 15.397mA over the same 5 minutes. Its not a big problem for me as I can calibrate and smooth it out but it may have implications for your application.

@thebeest I attempted to run the code, but I had challenges with the library. I downloaded the repo located here: GitHub - SJThomas29/Arduino_MachineControl: Fork of official Arduino_MachinControl, but kept getting reference errors. I'm fairly certain, I'm messing-up library locations.
A few questions:

  1. Is this the right library?
  2. Where should I place it?
  3. Do I need to remove my current Arduino_MachineControl library?
  4. Any additional tips would be appreciated.
    Thanks!

@adugenske,

It sounds like it is a library problem, I did have problems with it myself as Arduino was trying to use the built-in library instead of this modified one. Once you get the library included correctly the analog input should be fine.

  1. Yes that is the correct library
  2. The library needs to be inside your project folder so that the #include statement points to the relative path to the Arduino_MachineControl.h file
  3. You can keep your existing built-in library but do not include it in your project.
  4. Try an absolute path to the file #include "/home/user/project/Arduino_MachineControl/src/Arduino_MachineControl.h" (assuming your on Linux, Windows would be C:\project\Arduino_MachineControl/src/Arduino_MachineControl.h). And maybe compile with the arduino-cli as I find it gives you more control over the process.