Pages: [1]   Go Down
Author Topic: SPI with ADC slow and extra bit somehow  (Read 933 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, I have some questions about my SPI connection with an ADC (http://www.ti.com/product/ads7886)
Here's the code:
Code:
#include <SPI.h>
int time = 0;
long tot = 0;

void setup() {
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE3);
  const int SS = 10;
  SPI.begin();

}

void loop() {
  digitalWrite(SS,LOW); 
  byte MSB = SPI.transfer(0);
  byte LSB = SPI.transfer(0);
  unsigned int value = MSB*256 + LSB;
  digitalWrite(SS,HIGH);
  tot += 1;
  time = millis();
  if (time >= 1000) {
    Serial.begin(9600);
    Serial.println(tmp);
    Serial.println(time);
    Serial.println(tot);
    while(1){} 
  }
}

So with clock divider = 2, which should mean 8 Mhz, i should be getting 8M/16[bits] = 500,000 integer data per second.
I'm consistently getting 45081 smiley-sad
Another strange thing is that I'm getting results over 4095, which is 12 bits. For some reason it goes all the way up to 13 bits, though it's a 12 bit ADC. This happens with both of my adc's, so i think it isnt that I fried this part while soldering smiley any ideas?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Here's the code
That won't compile. Where is tmp defined?

Quote
Another strange thing is that I'm getting results over 4095, which is 12 bits. For some reason it goes all the way up to 13 bits, though it's a 12 bit ADC.
How do you know? You aren't printing MSB, LSB, or value anywhere.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 473
Posts: 18695
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The processor runs at 16 MHz (I am presuming as you didn't say) and instructions are an average of 2 clock cycles. So there is no way, in a single instruction, that you are going to do everything you have in "loop". It's even 8 lines of C++ code (assuming the branch isn't taken) plus entering and exiting loop itself.

Quote
Code:
  unsigned int value = MSB*256 + LSB;

You are better off shifting the byte left, hopefully the compiler will do that for you:

Code:
  unsigned int value = (MSB << 8) | LSB;

Quote
Code:
    Serial.println(tmp);
    Serial.println(time);

Your code doesn't compile. There is no "tmp" there.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh right sorry about the tmp. I cut some commented code out to make it easier to read and cut that out too by accident.
the commented code is also where i had it go slower and transmit everything over serial. I got some interesting stuff like 8100.

So about the SPI clock: does it continuously flicker (during rest of loop) or only when I call SPI.transfer()?

Also I ran some other tests, and I'm wondering if the arduino is limiting itself? Because i put in an extra if statement that was true sometimes, within which i put a sin, cos, tan, calculation on 'time' and I still got that same number of results: 45081.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 473
Posts: 18695
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Flicker? Sin? Sounds bad.

No the clock only does stuff during the transfer. The very essence of the clock is that it tells the "other end" there is data there. If it was active at other times, the other end would be getting garbage.

Perhaps post your code that produces this number 45081.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bleagh im not very good at explaining   smiley-roll-sweat

the code i posted originally is the code that produces the 45081 (which is the number of loops it has done in 1000 milliseconds).
The code I used to transmit the actual values is only slightly different:

Code:
#include <SPI.h>
int time = 0;
//long tot = 0;
//unsigned long tmp = 0;

void setup() {
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.setDataMode(SPI_MODE3);
  const int SS = 10;
  SPI.begin();
  Serial.begin(115000);

}

void loop() {
  digitalWrite(SS,LOW); 
  byte MSB = SPI.transfer(0);
  byte LSB = SPI.transfer(0);
//  unsigned int value = MSB*256 + LSB;
  unsigned int value = (MSB << 8) | LSB; //updated
  digitalWrite(SS,HIGH);
  sendByte(MSB);         //binary MSB
  sendByte(LSB);         //binary LSB
  Serial.println(value);  // value
  Serial.println(" ");     //separator
/*  tot += 1;
  time = millis();
  if ((time-tmp) >= 1000) {
    Serial.begin(115000);
    Serial.println(tmp);
    Serial.println(time);
    Serial.println(tot);
    while(1){} 
  }
*/
}
//made this so it won't chop of the leading 0's when sending binary over SPI
void sendByte(byte num){
  unsigned int i = 128; //binary: 10000000
  for (int x = 0; x < 8; x++) {
    if ((i&num) != 0) {
      Serial.print(1);
    }
    else {
      Serial.print(0);
    }
    i >>= 1;
  }
  Serial.print("\n");
}

here I'm not worried about the speed or number of transfers, just getting some of the data
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 473
Posts: 18695
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bear with me a bit here. I'm not trying to be difficult. I'm trying to help you.

Quote
the code i posted originally is the code that produces the 45081 (which is the number of loops it has done in 1000 milliseconds).

No, it doesn't. It won't compile. There is no "tmp" defined. So if you would be kind enough to post code, that compiles, that demonstrates your point, we can take it from there.

Your more recent post doesn't compile for me either, at least under version 0022 of the IDE:

Code:
void setup() {
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.setDataMode(SPI_MODE3);
  const int SS = 10;
  SPI.begin();
  Serial.begin(115000);

}

Note that SS goes out of scope at this point, so I get this:

Code:
sketch_jan02b.cpp: In function 'void loop()':
sketch_jan02b:16: error: 'SS' was not declared in this scope

So if you specify which version of the IDE you are using, that would help too. I don't personally use 1.0 unless I have to chase down a problem, because of major incompatibilities with previous versions.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pulled up a version of what i was using before, which compiles for me and gets the result of 45081
Code:
#include <SPI.h>
int time = 0;
long tot = 0;
long tmp = 0;

void setup() {
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.setDataMode(SPI_MODE3);
  const int SS = 10;
  SPI.begin();
  tmp = millis();
}

void loop() {
  digitalWrite(SS,LOW);  
  byte MSB = SPI.transfer(0);
  byte LSB = SPI.transfer(0);
  unsigned int value = (MSB << 8) | LSB; //just added this
  digitalWrite(SS,HIGH);
  tot += 1;
  time = millis();
  if ((time-tmp) >= 1000) {
    Serial.begin(115000);
    Serial.println(tmp);
    Serial.println(time);
    Serial.println(tot);
    while(1){}  
  }
}

turns out I'm using version 1.0. Not that it the backward incompatibilities would bother me much because i just started using arduino (and microprocs in general)
« Last Edit: January 02, 2012, 01:44:31 am by flyingsilverfin » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 473
Posts: 18695
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, well using version 1.0 of the IDE, and uploading your sketch, yes I can definitely confirm you get:

Code:
0
1000
45081

So what? This is without any hardware connected. You are basically timing how quickly you can do SPI transfers, and they will take the same time every time you test. Even with nothing connected.

As I explained above, you can't expect 500,000 transfers per second, because the processor has to "do stuff" apart from doing the SPI. Like, storing things in memory, checking the time, etc.

So the bigger issue, which you said above, is why you seem to be getting "bad" data.

Can you give examples of this data?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've attatched a txt doc with some data (obtained from the code I posted earlier)
Used a 1k pot and then turned it up toward the end of the data

3 serial transfers: MSB, LSB, then the total value

I'll be gone for the next few days (vacation's over... back to school smiley-sad), might be able to drop in once or twice in some airport, so no rush
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I've attatched a txt doc with some data (obtained from the code I posted earlier)
Attached it to what? Not your post.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Agh internet in developing countries can be a pain. I got booted out of the network right when i clicked post once.
Trying again

btw i fed the 1K pot the 5v from the arduino, forgot to mention that

* Data.txt (3.46 KB - downloaded 8 times.)
Logged

Pages: [1]   Go Up
Jump to: