msmithy12
Posts: 94
Joined: Fri Aug 10, 2012 8:57 am

SPI ADC MCP3301

Tue Jun 10, 2014 8:09 am

Hello, I am having issues with my ADC in C. I`m new to SPI and reasonably new to C and I believe I am close to having this ADC read done but i feel the last 10% of the code is taking 90% of the time. The code has no real practical use yet but reading the ADC would help me communicate with the outside world.

After reading the MCP3301 data sheet (I liberated these ADC from a component bin at work, they came as a microchip sample for another project a few years back) I believe that I need to clock 2 Bytes of data each 8 bits long and then mask off 4 of those bits, and read the remaining 12 bits. I usually just build hardware type stuff this is my first real big move into mechatronics and interfacing with the outside world beyond a few LEDs flashing and an I2C RTC.

My ADC reads 0 - 25ohms (or will if it ever works)

Code: Select all

//includes omitted for clarity

char adc[2], ohm, ohm1;

int main()
{

for(;;){
getchar();
SpiOpenPort(0);
SpiWriteAndRead(0,adc,2);
SpiClosePort(0);
ohm = (adc[0] << 8 | adc[1]);
ohm1 = ohm &0xfff;
float ohms = ohm1 * 0.00610350;
printf("%.3f ohms",ohms);
}
}
So the ADC should be read every time I press return, Unfortunately I either get 24.994 ohms or 0 ohms.

Im sure I have missed something very simple, I hope I haven't shot too far from the correct code, I have read the spi.h file and cant find an issue.

I would prefer to complete this in C because I have some C to read a DS18B20 and to do some I2C port expanding that I would like to add and make a full environment control system later. Any help would be great. I have tried google and always just find microcontroller stuff using:-

Code: Select all

   adc_value1 = spi_read(0);
   adc_value2 = spi_read(0);
On a side not if anyone is struggling with the DS18b20 or the MCP23017 I can upload my code.

"Share and Share alike"
I assume I know what I`m talking about... I probably don`t

Home: 256mb Made in UK, Rasbmc, 40" Sony Bravia KDL-40v3000
Work: 2b+, Rasbian, 6" Lilliput touchscreen

User avatar
joan
Posts: 15094
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: SPI ADC MCP3301

Tue Jun 10, 2014 8:19 am

chars are 8-bit quantities. Fine for reading bytes from a SPI device. Not so fine for storing a 12-bit quantity.

Perhaps

char adc[2];
int ohm, ohm1;

rather than.

char adc[2], ohm, ohm1;

msmithy12
Posts: 94
Joined: Fri Aug 10, 2012 8:57 am

Re: SPI ADC MCP3301

Tue Jun 10, 2014 10:25 am

Thank you for the speedy response, but that has made no difference to the output, i still get 24.994 ohms or 0 ohms in a seemingly random order. I will keep tapping away, Thanks
I assume I know what I`m talking about... I probably don`t

Home: 256mb Made in UK, Rasbmc, 40" Sony Bravia KDL-40v3000
Work: 2b+, Rasbian, 6" Lilliput touchscreen

ddahms
Posts: 68
Joined: Tue Mar 18, 2014 3:38 pm

Re: SPI ADC MCP3301

Tue Jun 10, 2014 4:10 pm

The two values you see, 0 or 24.994, are what you would get if the input was a constant 0 or 1, respectively. The input pin could just be floating around, giving the result you are seeing. So I have to ask the embarrassing question, are you sure the hardware is wired up correctly? Dout to MISO? CE0 to /CS? A voltage on Vref?

One potential problem I see is the MCP3301 needs +5V on Vdd, which means it will drive its Dout pin to +5V and that is higher than the Pi's 3.3V limit. You need a two-resistor voltage divider on that signal.

Return to “Interfacing (DSI, CSI, I2C, etc.)”