Hello,
I am working on a project to connect 3, 4-20mA industrial sensors that measure pH, turbidity and free chlorine residual to arduino UNO. I have seen the forums that show the conversion to 0 to 5V but I would like to know if there is a shield that would make this process simpler which may have been explained as this is something new I am trying.
Those sensors will output a current of between 4 to 20 mA.
The short answer, is to force the current to flow through a suitable resistor, and then measure the voltage across the resistor using the arduino analog measuring pin.
If you have a 250 ohm resistor, forcing between 4 and 20 mA to flow though it, will create a voltage of between 1 and 5 volts, which you measure with the arduino.
It would be nice if there was a shield that had 12 bit A/D for the full range of 4-20ma or 1 -5 volt. with terminal blocks and a power converter that took 24vdc and dropped it down to 5 vdc to power the Ardunio. If it used the SPI lib would be nice too. This would be very useful in Industrial control applications
Simple code to read it every 5mS and send the data out:
void loop(){
// Elapsed time check for ADC and Switch reading
if (millis()>=previousMillis){
previousMillis = previousMillis + 5; // set for next 5 mS interval
// read ADC with 3 byte transfer
PORTB = PORTB & B11111011; // ADC_SS, LOW
// ADCaddress = 0x0600, 640, 680, 6C0, 700, 740, 780, 7C0
dummyADC = SPI.transfer (highByte(ADCaddress)); // 0x06, 0x07 out, read in dummy data
highADC = SPI.transfer (lowByte(ADCaddress)); // 0x00, 0x40, 0x80, 0xC0, read in upper 4 bits
lowADC = SPI.transfer (0); // dummy 0 byte out , read in lower 8 bits
PORTB = PORTB | B00000100; // ADC_SS, HIGH
// send the data out
Serial.write (ADCsyncbyte); // syncbyte = B00110011, 0x33
// bits 4-3-2 = 0 when switch pressed. Invert them. Leave bits 1-0 alone. No bits 7-6. Bit 5 not used.
Serial.write (PINC ^ B0011100); // 3 switches on Port C, make them 1 if 0 (1 EXOR 1 = 0, 0 EXOR 1 = 1, 0 EXOR 0 = 0
Serial.write (address_count); // find way to put this in top nibble of next command?
Serial.write (highADC & 0x0F); // send it out
Serial.write (lowADC); // send it out
// prep address_count for next pass. Used to create ADC select, DAC select
address_count = address_count +1; // 0 to 7, pass to Rx for DAC sync
if (address_count == 8){
address_count = 0;
} // reset if hit all 8
ADCaddress = baseADCaddress + (address_count * 0x40); // update for next ADC pass
} // end 5mS test
} // end loop
moorsb:
Do these A/D chips give you a full range on 1 - 5v for the 4095 counts or do you loose counts for 0 - 1 v?
I believe you'd lose the 0 - 1 V range when using the MCP3208 chip. I've used the MCP3208 several times myself but I don't think I understand all its features. I believe you can use a reference voltage which is lower than 5V but I don't think you can change the lower end of its measurement range.
I'd be very interested in an ADC chip which would allow one to set independent endpoints for both the bottom of the measurement range as well as independently setting the upper endpoint of the measurement range.