interfacing to max127 and i2c

Hi all,
i've built a simple adc addon board for arduino that adds 8 12 bit analog input channels, but it talks (or it should) with the i2c protocol :frowning: and i don't know where to start from...
the ic i've used is the max127 and this is the http://datasheets.maxim-ic.com/en/ds/MAX127-MAX128B.pdf datasheet
I didn't found examples on that ic and arduino, so now i'm asking your help.
I'm looking for some bare sample code to start from, any can help?

no Arduino code but this code should get you started.

From - CCS :: View topic - MAX127 and I2C - by gyork: Sun Apr 04, 2004 7:30 pm

void main() {
int16 atod,result;
int8 result1,result2,i;

setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
printf("initiating max128\r\n");

//setup i2c

output_float(PIN_C3);
output_float(PIN_C4);

while (1){
//setup max128 to read channel 0
i2c_start();
i2c_write(0b01010000); //channel 0 0 to 4096 mV
i2c_write(0xF8); // send configuration bit
i2c_stop(); // start conversion

//read result from max128

i2c_start();
i2c_write(0b01010001); // send address to chip to begin read
result1 = i2c_read(); // get high byte of 12bit result
result2 = i2c_read(0);
i2c_stop(); // get low nibble of 12bit result

//convert to 16bit result
result = result1;
result = (result << 4 )+ (result2 >> 4); // combine into 16 bit result first four bits are 0s

printf("%ld\r\n",result); //debug
delay_ms(250);
}

}

Clear there is the initialization to start conversion and the read phase - In Arduinish this would become something like :

uint8_t deviceAddress = 0x50;
// START CONVERSION
Wire.beginTransmission(deviceAddress);
Wire.send(0xF8); 
Wire.endTransmission();

// READ RESULT
Wire.requestFrom(deviceaddress, 2);
int result = 0;
for (int c = 0; c < 2; c++ )
if (Wire.available()) result = result * 256 + Wire.receive();

Maybe best to write a small class that accepts the deviceAddress in the constructor and provides a read() funtion that has the channel as parameter. That allows multiple MAX128 's in one sketch or to add functionality within the class, e.g. an array of prev values, a smoothRead() - etc

Succes,
Rob

Thank you Rob for your answer,
actually i'm using this code to read the first channel of the adc but i'm only receive zeroes...

int deviceAddress = 0x50;

#include <Wire.h>

void setup()
{
  Wire.begin();       
  Serial.begin(9600);  
}

void loop()
{


Wire.beginTransmission(deviceAddress);
Wire.send(0x88); 
Wire.endTransmission();


Wire.requestFrom(deviceAddress, 2);
int result = 0;
for (int c = 0; c < 2; c++ )
if (Wire.available()) result = result * 256 + Wire.receive();
 delay(500);
 Serial.println(result);
}

at the moment this is not working, and i can't figure why...

I have no max127 so I cannot test the code.

Things I notice:

  • you use an int for deviceAddress where the library expects an uint8_t. that should not cause any problem.
  • you send control byte 0x88 = B 1000 1000 (lookup in PDF)
    START = 1
    SEL (210) = 000 => channel 0
    RNG = 1
    BIP = 0 => 0..10 Volt => full range
    PD = 00 => normal mode

Seems all OK,
Best thing to do is check the return values of the Wire functions:

int x = Wire.beginTransmission(deviceAddress);
Serial.println(x);

etc to see if the handshake somewhere is not acknowledged.

Please post the results.

i've changed the code this way

int deviceAddress = 0x50;
char c;

#include <Wire.h>

void setup()
{
  Wire.begin();       
  Serial.begin(9600);  
}

void loop()
{

// Read channel 0
Wire.beginTransmission(deviceAddress);
Wire.send(0x88); 
Wire.endTransmission();

// READ RESULT
Wire.requestFrom(deviceAddress, 2);
int result = 0;
 while (Wire.available()) {
    c = Wire.receive();
    if (c != 0) {
      Serial.print(c);
    }}
 delay(500);
 
}

this doesn't work too :frowning:
if i insert the debug line you suggest i get this error:"master_reader.cpp: In function 'void loop()':
master_reader:15: error: void value not ignored as it ought to be"
I can scan and find the adc with i2c scanner, but it says address is 40! even more confused....
http://todbot.com/blog/2009/11/29/i2cscanner-pde-arduino-as-i2c-bus-scanner/

0x40 is not according spec. Spec might be woring ?

Did you try using address 0x40?

Have you connected the three address lines to Ground - so they are effectively zero? just checking:)

yes, and 0x40 doesn't work too...
A0 A1 and A2 are connected to ground , i've doublechecked them..
i don't know what to think to... :drooling_face:

OK, try this ...

int deviceAddress = 0x50;

#include <Wire.h>

void setup()
{
  Wire.begin();       
  Serial.begin(9600);  
}

void loop()
{
  int x = 0;
  x = Wire.beginTransmission(deviceAddress);
  Serial.print("begin : "); Serial.println(x);

  x = Wire.send(0x88); 
  Serial.print("send: "); Serial.println(x);
  x = Wire.endTransmission();
  Serial.print("end: "); Serial.println(x);

  x = Wire.requestFrom(deviceAddress, 2);
  Serial.print("req: "); Serial.println(x);
  int result = 0;
  while (Wire.available < 2)  // wait for 2 bytes
  {
    Serial.print("."); 
    delay(1);
  }
  for (int c = 0; c < 2; c++) 
  {
    result = result * 256 + Wire.receive(); 
  }
  Serial.println(result);
  delay(10000);
}

doesn't compile...
it gives me the error i said before

I did not test the previous code, sorry; This one does compile under 21 (win7)
What are the results?

int deviceAddress = 0x50;

#include <Wire.h>

void setup()
{
  Wire.begin();       
  Serial.begin(9600);  
}

void loop()
{

  Wire.beginTransmission(deviceAddress);
  Wire.send(0x88); 
  int x = 0;
  x = Wire.endTransmission();
  Serial.print("end: "); Serial.println(x);

  x = Wire.requestFrom(deviceAddress, 2);
  Serial.print("req: "); Serial.println(x);
  int result = 0;
  while (Wire.available() < 2)  // wait for 2 bytes
  {
    Serial.print("."); 
    delay(1);
  }
  for (int c = 0; c < 2; c++) 
  {
    result = result * 256 + Wire.receive(); 
  }
  Serial.println(result);
  delay(10000);
}

serialmonitor says:
........................................end:2
req:0
...............................................................

what does it mean?

So endTransmission returns 2 - check the library what it means ......

uint8_t TwoWire::endTransmission(void)
{
  // transmit buffer (blocking)
  int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
  // reset tx buffer iterator vars
  txBufferIndex = 0;
  txBufferLength = 0;
  // indicate that we are done transmitting
  transmitting = 0;
  return ret;
}
/* 
 * Function twi_writeTo
 * Desc     attempts to become twi bus master and write a
 *          series of bytes to a device on the bus
 * Input    address: 7bit i2c device address
 *          data: pointer to byte array
 *          length: number of bytes in array
 *          wait: boolean indicating to wait for write or not
 * Output   0 .. success
 *          1 .. length to long for buffer
 *          [color=red]2 .. address send, NACK received[/color]
 *          3 .. data send, NACK received
 *          4 .. other twi error (lost bus arbitration, bus error, ..)
 */

So it gets a NACK on the address.

NOw try the same with address 0x40 that you found with the sniffer ...

with 0x40 says:
end:2
req:0
.............................
is it dead? :frowning:

is it dead?

Don't know ...
DO you have 4K7 pull up resistors on the I2C lines?

try using address 0x28

why 0x28 ?

The datasheet says the 4 MSB are 0101 followed by 3 address select bits and a final R/W bit. Assuming the 3 address bits are set to 0 and the R/W is 0 yields an 8 bit address of 0x50. That should yield a 7 bit address of 0x28.

tested with 0x28 and it always yelds:
end:0
req:2
16

I just went back and looked at the posts because I was going to recommend Todbots I2C buss scanner, but it looks like you already ran that. Just so you know, it returned back a value of 40 as the address. The address of 40 is decimal 40, which converts to 0x28 hex so I would continue to use 0x28 as the address.

tested with 0x28 and it always yelds:
end:0
req:2
16

This means it's working!