Author Topic: MCP3425 - 16 bit adc jumping every 256 units ?  (Read 3160 times)

0 Members and 1 Guest are viewing this topic.

Offline DuncanSteelTopic starter

  • Contributor
  • Posts: 39
  • Country: ee
MCP3425 - 16 bit adc jumping every 256 units ?
« on: February 13, 2017, 07:44:37 am »
Hi

I am trying to learn ADC & have purchased following chip: MCP3425 , (datasheet).

From the 5.2 Configuration Register:
G1-G0: PGA Gain Selector Bits     -  00 = 1 V/V
S1-S0: Sample Rate Selection Bit -  10 = 15 SPS (16 bits)
And Continuous Conversion Mode


After connecting all the pins & got the I2C interface working I made some measurements By increasing the input voltage from 0V to ~2V. I actually made a voltage divider with 10 turn pot that let me increase the voltage very slowly.

And for some reason the output was changing only every 15 mV & always by 256 Units.

So every 15 mV increase 256 unit jump.

Shouldnt the sample value I read be changing at least every 1mV (in fact from datasheet every 65uV) ?


 

Offline cyr

  • Frequent Contributor
  • **
  • Posts: 252
  • Country: se
Re: MCP3425 - 16 bit adc jumping every 256 units ?
« Reply #1 on: February 13, 2017, 08:10:07 am »
So your 8 lower bits are always zero right?  Double-check your code and I2C communication, are you actually reading all the data bits? Is your code assembling the 16-bit value correctly?
 

Offline DuncanSteelTopic starter

  • Contributor
  • Posts: 39
  • Country: ee
Re: MCP3425 - 16 bit adc jumping every 256 units ?
« Reply #2 on: February 13, 2017, 08:31:42 am »
So your 8 lower bits are always zero right?  Double-check your code and I2C communication, are you actually reading all the data bits? Is your code assembling the 16-bit value correctly?

Well actually no, see the img below. I turned the PSU switch from 0V to 2V & the bits are changing. The jump in nr is big because I was turning the switch slower in the beginning. So I would guess the I2C is correct.

 

Offline bktemp

  • Super Contributor
  • ***
  • Posts: 1616
  • Country: de
Re: MCP3425 - 16 bit adc jumping every 256 units ?
« Reply #3 on: February 13, 2017, 08:51:40 am »
+1  for a software problem:
Quote
When the Master sends a read command (R/W = 1),
the MCP3425 outputs the conversion data bytes and
configuration byte.
That would be my guess: You are reading the configuration byte as low data byte.
« Last Edit: February 13, 2017, 08:53:18 am by bktemp »
 

Offline DuncanSteelTopic starter

  • Contributor
  • Posts: 39
  • Country: ee
Re: MCP3425 - 16 bit adc jumping every 256 units ?
« Reply #4 on: February 13, 2017, 10:47:45 am »
+1  for a software problem:
Quote
When the Master sends a read command (R/W = 1),
the MCP3425 outputs the conversion data bytes and
configuration byte.
That would be my guess: You are reading the configuration byte as low data byte.

Hmm, maybe you are right, what Im getting is:
Quote
Db1: 11010001 Db2: 00011001 Db3: 11111111 Db4: 11111111

where Db1 is the slave address, Db2 seems to be 2nd Byte, Upper Data Byte & all what is following is gibberish..

I tidied up & cleaned the little code I made, maybe you could have a look at the logic?

I commented the actions Im taking.

I imagine the problem is TWCR code 58: (Data byte has been received; NOT ACK has been returned)

I think the master must somehow send ACK.
« Last Edit: February 13, 2017, 10:57:47 am by DuncanSteel »
 

Offline bktemp

  • Super Contributor
  • ***
  • Posts: 1616
  • Country: de
Re: MCP3425 - 16 bit adc jumping every 256 units ?
« Reply #5 on: February 13, 2017, 11:03:57 am »
You are reading the first data byte after sending the slave address. At that time no data has been received yet, so you are reading back the transmitted slave address (11010001).
Data byte 2 is the MSB of the ADC data, but the MCP3425 stops sending any further data (you read back 1s because of the pullups on I2C bus), because you don't send ack after data byte 2. By enabling the ACK transmission (TWSR |= (1<<TWEA)) you should get the LSB in data byte 3. If you send another ACK, you will also get the control word in data byte 4.
« Last Edit: February 13, 2017, 11:06:52 am by bktemp »
 

Offline enz

  • Regular Contributor
  • *
  • Posts: 134
  • Country: de
Re: MCP3425 - 16 bit adc jumping every 256 units ?
« Reply #6 on: February 13, 2017, 11:08:53 am »
One thing that is true for every A/D-Converter:
If the LSB is rock solid stable for each and every sample, that it is not the LSB from the ADC-Data but something else  ;)
 

Offline DuncanSteelTopic starter

  • Contributor
  • Posts: 39
  • Country: ee
Re: MCP3425 - 16 bit adc jumping every 256 units ?
« Reply #7 on: February 13, 2017, 02:44:34 pm »
Thank you.

Weird tho, I had (TWCR |= (1<<TWEA)) already in my code, dunno why it didnt work, got it working now. First time i2c is a success :)  :popcorn:

In case anyone will ever have same issue, hire is the code that I got it working with:

Code: [Select]
void _I2C_ReadReg(uint8_t Slaveaddress){

uint8_t Databyte1 = 0;
uint8_t Databyte2 = 0;
//uint8_t Databyte3 = 0;
//uint8_t Databyte4 = 0;
uint16_t c = 0;

//USART_SendString("_I2C_ReadReg START"); USART_sendNewline();

// start - 2nd time
I2C_Start(); // 1. Application writes to TWCR to initiate transmission of START
I2CWaitFor_TWINT_FlagToBeSet(); // 2. Wait for TWINT Flag set. This indicates that the START condition has been transmitted
// Check value of TWI Status Register. Mask prescaler bits. If status different from START go to ERROR
I2CCheckStatusRegister(0x08); // 0x08 - is a START condition, If not error if yes continue

// Send SLAVR adress / Control Byte
TWDR = Slaveaddress; // loads SLA+W into TWDR
I2C_ClearFlagAndEnable(); // Clear TWINT bit in TWCR to start transmission of address
I2CWaitFor_TWINT_FlagToBeSet(); // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
//USART_SendString("TWSR: "); USART_send_byte(TWSR); USART_sendNewline();
I2CCheckStatusRegister(0x40); // ACK by MCP3425, Check value of TWI Status Register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR


TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); // Clear TWINT bit in TWCR to start transmission of address
while ((TWCR & (1<<TWINT)) == 0);
Databyte1 = TWDR;
//USART_SendString("Databyte1: "); USART_send_byte(Databyte1); USART_sendNewline();

TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); // Clear TWINT bit in TWCR to start transmission of address
while ((TWCR & (1<<TWINT)) == 0);
Databyte2 = TWDR;
//USART_SendString("Databyte2: "); USART_send_byte(Databyte2); USART_sendNewline();

TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); // Clear TWINT bit in TWCR to start transmission of address
while ((TWCR & (1<<TWINT)) == 0);
//Databyte3 = TWDR;

TWCR = (1<<TWINT)|(1<<TWEN)|(0<<TWEA); // Clear TWINT bit in TWCR to start transmission of address
while ((TWCR & (1<<TWINT)) == 0);

/*
USART_SendString("Db1: "); USART_send_byte(Databyte1); USART_SendString(" ");
USART_SendString("Db2: "); USART_send_byte(Databyte2); USART_SendString(" ");
USART_SendString("Db3: "); USART_send_byte(Databyte3); USART_SendString(" ");
USART_SendString("Db4: "); USART_send_byte(Databyte4); USART_SendString(" ");
*/

c = (Databyte1 << 8);
c |= Databyte2;

int radix = 10; // kümnendsüsteem
char buffer[23];
ltoa(c,buffer,radix);

USART_SendString(buffer);
USART_sendNewline();

// stop condition
TWCR  =(1<<TWEN)|(1<<TWSTO)|(1<<TWINT);

}
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf