Has anyone had experience with this chip? It’s an ADC. You can buy an interface board for it from ereshop.com, which allows 0-10V and 4-20mA input, which is pretty handy for a Particle Electron, as it would let you interface with ‘industry standard’ control voltages.
I’ve tried a few libraries but had no luck:
Both will compile, with the usual modifications from Arduino code to Particle, but produce no output. The first library gives me “Read error” and “Read failed”…
I’m not asking for answers, because that’s lazy But if anyone has any experience with this device I’d be really interested to know what you did.
Standard question I’m sure The board has built-in 10k’s for both SDA and SCLK, and this is the only I2C device connected. I’ve literally tried all the addresses also, because there is some discrepancy between the manufacturers information and the datasheet of the module on the ereshop.com website.
Triple checked all connections with my multimeter, everything is connected and no shorts etc. It’s very odd behaviour.
I know that both libraries do conversions and give read outs in mV, despite the ereshop board being 0-10v/4-20mA etc but this just a scaling issue. Something I can solve once I know I’m getting data!
@joearkay, how are you powering the board. I assume you have both pull-up jumpers on the board. Have you run an I2C bus scanner to see if anything comes up?
// --------------------------------------
// i2c_scanner
//
// http://playground.arduino.cc/Main/I2cScanner
//
// Version 1
// This program (or code that looks like it)
// can be found in many places.
// For example on the Arduino.cc forum.
// The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
// Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26 2013
// V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
// by Arduino.cc user Krodal.
// Changes by louarnold removed.
// Scanning addresses changed from 0...127 to 1...119,
// according to the i2c scanner by Nick Gammon
// http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
// As version 4, but address scans now to 127.
// A sensor seems to use address 120.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
#include <application.h>
//#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
delay(10000);
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknow error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
@peekay123 Oh brilliant, I had no idea you could scan the bus like this! Fantastic, it shows a device at 0x68. Both pull-ups are enabled and it’s powered with the battery and the USB port.
Nope. Just the Particle Electron’s built in 2-pin LiPo connector in conjunction with my USB power. I was originally concerned that the I2C device was drawing more current that can be provided, but the 3.3V pin should be able to deliver ~800mA. Anyway, it shows up on the I2C scanner so must be working properly.
I’m using this library, and it still gives me an error. Like i said before, I’ve made a few modifications to make sure it works for Particle, mainly including ‘application.h’, removing the ‘wire.h’ reference and a few tweaks here and there.
Sorry I wasn’t being clear. There are no ‘compilation’ errors, but when I run the sketch, I get “Read Error” and “Read Failed”, which is being called from readData()
Yes, I did think 800mA is a high value, considering a standard USB port pumps out 500mA max, but this is what’s in the documentation!
@joearkay, try adding a delay between the Wire.requestFrom() and the next line in readData. The device may need a bit of setup time and the STM32 is fast.
Wire.requestFrom(MCP3424_ADDRESS, 4);
delay(1);
if (Wire.available() != 4) {
@peekay123 Good point, I never really considered the clock speed to be an issue. I guess you would probably be able to get away with more using an Arduino, compared to something snappy like a Particle Electron.
I tried 1ms, 10ms and 100ms delays with no luck. I’ve thrown half second delays to each call of getChannelmV() as well. Even tried a half second delay where you suggested. Still no luck
Ok I’ve tried the other library with the correct address, hey presto! It must just be a timing issue somewhere in the old library! The results I’m getting are sporadic, but that’s probably because the scaling is different on this interface board compared to what it is natively (without the external op-amp etc).
Still doesn’t explain the behaviour of the library that doesn’t work, but hey ho!
@joearkay, there seems to be a minor error in the library. The contructor takes an address argument and correctly sets it private variable _address. However, it then ignores that value and uses its own #define value in:
Wire.requestFrom(MCP3424_ADDRESS, 4);
That line should be: Wire.requestFrom(_address, 4);
I assume you set the correct address in the .ino file’s #define
@peekay123 Just trying to adjust the conversion now, so that it yields a correct reading. In 12-bit mode, in the response, byte 0 is (MSB)XXXX SDDD(LSB) and byte 1 is DDDD DDDD, where ‘X’ bits are ignored, ‘S’ is the sign bit and ‘D’ bits are the data.
The interface board I’m using has an Op-Amp which means it can accept a larger voltage range. On the datasheet, they give the equation to convert the binary ‘code’ received into a voltage, as follows:
V = (code/2047)(2.048/PGA)(180/33).
I’ve modified the ‘switch’ case in the library to realise this equation, but it’s just returning zeros. I’d originally placed the values straight in-line, but decided to define them ‘long’ so that all arithmetic operations used the same type. I’ll comment each line so you can see my understanding:
switch (_resolution){
case 12:
_resultat = _Buffer[0]; //originally assigning _resultat to the first byte
_resultat&=0b00001111; //ANDING this to 'mask' the unwanted bits
_resultat = _resultat << 8; //Shifting 8 bits in the MSB direction
_resultat |= _Buffer[1]; //OR to add byte 1 to the end of the first byte
if(_resultat>2048-1) {
_resultat=_resultat-4096-1; //not sure what this bit is
}
long maxCode = 2047;
long vRef = 2.048;
long invGain = (180/33); //all from datasheet
_resultat = (_resultat/maxCode)*(vRef/_PGA)*invGain; //equation from datasheet
If I just return ‘_resultat’ before doing this last arithmetic calculation, it yields the pure binary code. If I work out the equation on pen and paper, it works out! FYI _resultat is of ‘long’ type and _Buffer and _PGA are ‘uint_8’