MCP3425 - 16 bit adc jumping every 256 units ? - Page 1
Forum section: electronics / beginners

author: DuncanSteel
author_rank: Contributor
timestamp: February 13, 2017, 07:44:37 am
content: HiI 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/VS1-S0: Sample Rate Selection Bit - 10 = 15 SPS (16 bits)And Continuous Conversion ModeAfter 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) ?

author: cyr
author_rank: Frequent Contributor
timestamp: February 13, 2017, 08:10:07 am
content: 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?

author: DuncanSteel
author_rank: Contributor
timestamp: February 13, 2017, 08:31:42 am
content: Quote from: cyr on February 13, 2017, 08:10:07 amWell 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.

author: bktemp
author_rank: Super Contributor
timestamp: February 13, 2017, 08:51:40 am
content: +1 for a software problem:QuoteThat would be my guess: You are reading the configuration byte as low data byte.

author: DuncanSteel
author_rank: Contributor
timestamp: February 13, 2017, 10:47:45 am
content: Quote from: bktemp on February 13, 2017, 08:51:40 amHmm, maybe you are right, what Im getting is:Quotewhere 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.

author: bktemp
author_rank: Super Contributor
timestamp: February 13, 2017, 11:03:57 am
content: 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.

author: enz
author_rank: Regular Contributor
timestamp: February 13, 2017, 11:08:53 am
content: 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

author: DuncanSteel
author_rank: Contributor
timestamp: February 13, 2017, 02:44:34 pm
content: 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 successIn case anyone will ever have same issue, hire is the code that I got it working with:Code: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 timeI2C_Start();// 1. Application writes to TWCR to initiate transmission of STARTI2CWaitFor_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 ERRORI2CCheckStatusRegister(0x08);// 0x08 - is a START condition, If not error if yes continue// Send SLAVR adress / Control ByteTWDR = Slaveaddress;// loads SLA+W into TWDRI2C_ClearFlagAndEnable();// Clear TWINT bit in TWCR to start transmission of addressI2CWaitFor_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 ERRORTWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);// Clear TWINT bit in TWCR to start transmission of addresswhile ((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 addresswhile ((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 addresswhile ((TWCR & (1<<TWINT)) == 0);//Databyte3 = TWDR;TWCR = (1<<TWINT)|(1<<TWEN)|(0<<TWEA);// Clear TWINT bit in TWCR to start transmission of addresswhile ((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;intradix= 10;// kümnendsüsteemcharbuffer;ltoa(c,buffer,radix);USART_SendString(buffer);USART_sendNewline();// stop conditionTWCR =(1<<TWEN)|(1<<TWSTO)|(1<<TWINT);}