Arduino-SPI-MCP3204 - Page 1
Forum section: electronics / general

author: shebu18
author_rank: Frequent Contributor
timestamp: July 02, 2012, 04:55:14 pm
content: Hello, i am trying to get some normal values from the chip but i get only non sense from it. I get like 13-14bits of data instead of 12.I use the 5V of the usb as a ref and as the adc input. I now wnat to see it comunicating ok bits, 12bits, even if they ar not the same every time. I know i do not have the right 5V ref voltage to measure.The code is this:Code:#include <SPI.h>int value;byte byte0;//highbyte for bit11-8byte byte1;//lowbyte for bit7-0int cs=9;//chipselectvoid setup(){pinMode(cs, OUTPUT);digitalWrite(cs, HIGH);SPI.begin(); //initializingSPI.setBitOrder(MSBFIRST); //MSB goes first outSPI.setClockDivider(SPI_CLOCK_DIV16);/1Mhz SPI clockSerial.begin(9600);}void loop(){digitalWrite(cs, LOW);SPI.transfer(0x18);//0b0000011000 configuration bits, five 0's, startbit, sind/diff, D2,D1,D0(in this case channel 0byte0=SPI.transfer(0x00);byte1=SPI.transfer(0x00);digitalWrite(cs, HIGH);Serial.print("high:");Serial.println(byte0, BIN);Serial.print("low :");Serial.println(byte1, BIN);Serial.print("hig+low");Serial.print(byte0,BIN);Serial.println(byte1, BIN);delay(2000);}I see the problem to be in the code, as i send 8 bits and another 2, then i send again 8bits and read the high data in but i do not get always back 8 bits, then i read low data and i get sometimes 8 bits.Solution:I found that i first need to sned 0x06, first 8 bits, then send the next 8 bits(0x00 for chanel 0) but at the same time read the data in pin, at at the end send 0x00 for the last 8 bits. Another important thing is that if the first bits from the 8 are 0 arduino does not show them.Question:How do i merge byte0 and byte1 into a 2 byte word, and read only the lst 12 bits and convert them into decimal?

author: andyg
author_rank: Regular Contributor
timestamp: July 02, 2012, 05:06:35 pm
content: QuoteI didn't look over your entire code, but I think for the question you asked, what you're after is something like this?Code:uint16_t myword;myword = ( byte0 << 8 | byte1 ) & 0b111111111111;Serial.print("merged word:");Serial.println(myword, DEC);

author: shebu18
author_rank: Frequent Contributor
timestamp: July 02, 2012, 05:57:47 pm
content: Thank you for the code, could you Explayn it with some comments?I wnat to understand this and know it from my head next time.I have read through thishttp://www.arduino.cc/playground/Code/BitMathand i kind of understand what you did there. So in myword, 16bit, you pusht the 8 MSB to left 8 positions than using OR you added the 8LSB and you used after this AND to remove the first 4 bits, make them 0. is this right?

author: andyg
author_rank: Regular Contributor
timestamp: July 02, 2012, 11:49:52 pm
content: QuoteYou've got it.Actually a better way of doing it (I think) would be to cast byte0 to 16-bits wide:Code:uint16_t myword;myword = ( ( (uint_16_t) byte0 ) << 8 | byte1 ) & 0b0000111111111111;Serial.print("merged word:");Serial.println(myword, DEC);That's because byte0 is 8-bits wide, and if you left shift that 8 bits, you may lose the value completely, and it will be evaluated as zero. But it depends on how to compiler treats it. So I would do it the safe way.

author: Mechatrommer
author_rank: Super Contributor
timestamp: July 03, 2012, 02:15:26 am
content: Code:myword = ( byte0 & 0b00001111) << 8) | byte1;same... except i think sompiler will make 8bit AND instead of 16bit AND as previous. what do you think?ps: i figured out, avr studio using big endian for word (or small endian), so i have to switch to make it correct...Code:myword = ( byte1 & 0b00001111) << 8) | byte0;something you need to care about. YMMV.

author: shebu18
author_rank: Frequent Contributor
timestamp: July 03, 2012, 05:59:51 am
content: Quote from: Mechatrommer on July 03, 2012, 02:15:26 amIf i do like in the last part i would have the low byte in the first 8 of the int and the high byte in the last 8 if the int. So i still need to do byte0 & 0b00001111 and after that move and use |. right or did i not understand something?

author: Mechatrommer
author_rank: Super Contributor
timestamp: July 03, 2012, 06:16:12 am
content: sorry. i missed one bracket there (as usual) it should be... myword = (( byte0 & 0b00001111) << 8 ) | byte1; (and in your quotes above, you deleted the << 8 why?)i dont quite understand your statement/question but yes you still need to do and AND operation to discard the 4 highest bits, unless you're pretty sure they are all zero.

author: shebu18
author_rank: Frequent Contributor
timestamp: July 03, 2012, 06:20:40 am
content: <<8 disappeared because there fas a ) after 8 and you get theout of it. I do the AND operation to discared the first 4 bits, i do not need them, i need the last 12.