Author Topic: Arduino-SPI-MCP3204  (Read 7303 times)

0 Members and 1 Guest are viewing this topic.

Offline shebu18Topic starter

  • Frequent Contributor
  • **
  • Posts: 309
  • Country: ro
Arduino-SPI-MCP3204
« on: July 02, 2012, 04:55:14 pm »
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: [Select]
#include  <SPI.h>
int value;
byte byte0;//highbyte for bit11-8
byte byte1;//lowbyte for bit7-0

int cs=9;//chipselect

void setup(){
  pinMode(cs, OUTPUT);
  digitalWrite(cs, HIGH);
  SPI.begin(); //initializing
  SPI.setBitOrder(MSBFIRST); //MSB goes first out
  SPI.setClockDivider(SPI_CLOCK_DIV16);/1Mhz SPI clock

  Serial.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 0
  byte0=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?


 

Offline andyg

  • Regular Contributor
  • *
  • Posts: 59
  • Country: au
    • gock.net
Re: Arduino-SPI-MCP3204
« Reply #1 on: July 02, 2012, 05:06:35 pm »
Quote
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?

I didn't look over your entire code, but I think for the question you asked, what you're after is something like this?

Code: [Select]
uint16_t myword;
myword = ( byte0 << 8 | byte1 ) & 0b111111111111;
Serial.print("merged word:");
Serial.println(myword, DEC);
« Last Edit: July 02, 2012, 05:08:24 pm by andyg »
 

Offline shebu18Topic starter

  • Frequent Contributor
  • **
  • Posts: 309
  • Country: ro
Re: Arduino-SPI-MCP3204
« Reply #2 on: July 02, 2012, 05:57:47 pm »
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 this http://www.arduino.cc/playground/Code/BitMath and 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?
« Last Edit: July 02, 2012, 06:44:24 pm by shebu18 »
 

Offline andyg

  • Regular Contributor
  • *
  • Posts: 59
  • Country: au
    • gock.net
Re: Arduino-SPI-MCP3204
« Reply #3 on: July 02, 2012, 11:49:52 pm »
Quote
I have read through this http://www.arduino.cc/playground/Code/BitMath and 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?

You've got it.

Actually a better way of doing it (I think) would be to cast byte0 to 16-bits wide:

Code: [Select]
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.
« Last Edit: July 03, 2012, 12:02:01 am by andyg »
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11620
  • Country: my
  • reassessing directives...
Re: Arduino-SPI-MCP3204
« Reply #4 on: July 03, 2012, 02:15:26 am »
Code: [Select]
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: [Select]
myword = ( byte1 & 0b00001111) << 8) | byte0;something you need to care about. YMMV.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline shebu18Topic starter

  • Frequent Contributor
  • **
  • Posts: 309
  • Country: ro
Re: Arduino-SPI-MCP3204
« Reply #5 on: July 03, 2012, 05:59:51 am »
Code: [Select]
myword = ( byte0 & 0b00001111) << | 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: [Select]
myword = ( byte1 & 0b00001111) << | byte0;something you need to care about. YMMV.


If 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?
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11620
  • Country: my
  • reassessing directives...
Re: Arduino-SPI-MCP3204
« Reply #6 on: July 03, 2012, 06:16:12 am »
sorry. i missed one bracket there (as usual :P) 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.
« Last Edit: July 03, 2012, 06:46:58 am by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline shebu18Topic starter

  • Frequent Contributor
  • **
  • Posts: 309
  • Country: ro
Re: Arduino-SPI-MCP3204
« Reply #7 on: July 03, 2012, 06:20:40 am »
<<8 disappeared because there fas a ) after 8 and you get the 8) out of it. I do the AND operation to discared the first 4 bits, i do not need them, i need the last 12.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf