Go Down

Topic: n00b SPI problem (Read 14661 times) previous topic - next topic

Willy

I copied this code from Conor Re: n00b SPI problem Reply #5
and I have received following result:

Initialize High Speed Constant Reading Mode
PRESSURE [1073740710]
TEMP F [75]
PRESSURE [1073740717]
TEMP F [75]
PRESSURE [1073740718]
TEMP F [75]

The temperature agrees well but the pressure ?????
My board is a Ardunio Pro 328 3,3V 8 MHz and I have installed the IDE 0017. (Windows)
Do you have an explanation for this result ? and perhaps you know where the error could be (Timing?).
Willy

#31
Dec 29, 2009, 05:58 pm Last Edit: Dec 29, 2009, 06:03 pm by glasspusher Reason: 1
Willy,
read my post, just before yours. Change the read_register16 function to a unsigned long from a float. That helped me.


unsigned long read_register16(char register_name)

Willy

Thank you for your advice to change the read_register function
but unfortunately it did not help. I received the same result.
Willy

Hi Willy,
Here is the code I use. It prints out in Centigrade. What helped me debug this was printing out the low and high parts of the pressure reading in hex, but I have since removed that. See if this works for you. Good luck!

Dave
Code: [Select]
// define spi bus pins
#define CSB 10 //  SLAVESELECT
#define SPICLOCK 13  // SCK
#define DATAOUT 11      //MOSI
#define DATAIN 12       //MISO

#define UBLB(a,b)  ( ( (a) << 8) | (b) )
#define UBLB19(a,b) ( ( (a) << 16 ) | (b) )

//Addresses
#define REVID 0x00      //ASIC Revision Number
#define OPSTATUS 0x04   //Operation Status
#define STATUS 0x07     //ASIC Status
#define START 0x0A      //Constant Readings
#define PRESSURE 0x1F   //Pressure 3 MSB
#define PRESSURE_LSB 0x20 //Pressure 16 LSB
#define TEMP 0x21       //16 bit temp

char rev_in_byte;          
int temp_in;
unsigned long pressure_lsb;
unsigned long pressure_msb;
unsigned long temp_pressure;
unsigned long pressure;

void setup()
{
 byte clr;
 pinMode(DATAOUT, OUTPUT);
 pinMode(DATAIN, INPUT);
 pinMode(SPICLOCK,OUTPUT);
 pinMode(CSB,OUTPUT);
 digitalWrite(CSB,HIGH); //disable device  
 
 SPCR = B01010011; //MPIE=0, SPE=1 (on), DORD=0 (MSB first), MSTR=1 (master), CPOL=0 (clock idle when low), CPHA=0 (samples MOSI on rising edge), SPR1=0 & SPR0=0 (500kHz)
 clr=SPSR;
 clr=SPDR;
 delay(10);
 Serial.begin(9600);
 delay(500);

 Serial.println("Initialize High Speed Constant Reading Mode");
 write_register(0x03,0x09);
}

void loop()
{

 rev_in_byte = read_register(REVID);
 
 pressure_msb = read_register(PRESSURE);
 pressure_msb &= B00000111;
 pressure_lsb = read_register16(PRESSURE_LSB);
 pressure_lsb &=0xFFFF;
 pressure = UBLB19(pressure_msb, pressure_lsb);
 pressure /= 4;
 pressure +=4500;    //correction in pascals to 1250 feet elevation, which is where I am at
 
 Serial.print(" P = ");
 Serial.print(pressure, DEC);
 
 temp_in = read_register16(TEMP);
 temp_in = temp_in / 2;
 Serial.print(", T x 10 = ");
 Serial.print(temp_in , DEC);
 Serial.println(" C");

 delay(1500);
}

char spi_transfer(volatile char data)
{
 SPDR = data;                    // Start the transmission
 while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
 {
 };
 return SPDR;                    // return the received byte
}


char read_register(char register_name)
{
   char in_byte;
   register_name <<= 2;
   register_name &= B11111100; //Read command
 
   digitalWrite(CSB,LOW); //Select SPI Device
   spi_transfer(register_name); //Write byte to device
   in_byte = spi_transfer(0x00); //Send nothing, but we should get back the register value
   digitalWrite(CSB,HIGH);
   delay(10);
   return(in_byte);
 
}

unsigned long read_register16(char register_name)
{
   byte in_byte1;
   byte in_byte2;
   unsigned long in_word;
   
   register_name <<= 2;
   register_name &= B11111100; //Read command

   digitalWrite(CSB,LOW); //Select SPI Device
   spi_transfer(register_name); //Write byte to device
   in_byte1 = spi_transfer(0x00);    
   in_byte2 = spi_transfer(0x00);
   digitalWrite(CSB,HIGH);
   in_word = UBLB(in_byte1,in_byte2);
   return(in_word);
}

void write_register(char register_name, char register_value)
{
   register_name <<= 2;
   register_name |= B00000010; //Write command

   digitalWrite(CSB,LOW); //Select SPI device
   spi_transfer(register_name); //Send register location
   spi_transfer(register_value); //Send value to record into register
   digitalWrite(CSB,HIGH);
}


Willy

Hi Dave
Great your code works perfectly.
Thanks a  lot .
Greetings from Switzerland.
Willy  :)

Willy,

Good to hear it works for you! A true validation of my code!

Greetings from Northern California. One of these days I have to make it out to Switzerland, my father worked for CIBA-Geigy (now Novartis) for 33 years and the company calendars were always filled with pictures of the alps. I am an avid hiker and they're on my to-do list.

Cheers,
Dave

Willy

Dear Dave , send me your E-Mail Adress and I will send you picture from the Mountains in Switzerland. I'm also avid hiker.
Cheers Willy  :)
wimon@sunrise.ch

yennifs

My first post, and I wanted to share a URL which is not permitted, so please excuse this dummy.

Sam

yennifs

Folks:

This link contains code I found to be quite helpful, as none of the posted solutions worked for me.  It provides easy access to all modes and features of the SPC1000(version D01) via Arduino.  You do need to set your pin numbers as you wish at the top of the file.  If the chip generates errors, the code even points you to the proper page in the documentation!  Finally, I am using an Arduino Duemilenova with a 3.3V output direct from the card to the sparkFun breakout board.

http://www.embedded.arch.ethz.ch/Examples/ExampleSensorboardPressure


Perhaps the older code examples worked with the older chip with a P01 designation rather than the newer D01.

Sam

madepablo

Hi yennifs,

I was taking a look to your code, and i looks very interesting. I will read it carefully.

However, in order to use it, how it works? I mean: there are two files in your webpage: modPressureSCP1000 and main. The second one, main, looks like the .pde file to the arduino ide, however, what is the other file, a library? How should i save it? In other case,.. how can i use it with arduino?

I am noob so maybe other users don´t need that information, but it could be great for me that info.

Thanks!

yennifs

Hi,
Just copy/paste everything into your arduino ide.  There are a few lines of formatting info in the code you will need to remove or comment out.

The code is in two sections. The first section includes code that is called by the second section: that is, the "typical" arduino 'setup' and 'loop' routines.  You could move the first section of code into a separate file(aka library), but it is not necessary.

If it compiles, then the code is good as is.  If you get errors, try commenting out the offending lines.  Once you get it compiled and loaded to arduino, all should work fine.  If you don't get good data, check your wiring.

--Sam

madepablo

Hi yennifs,

Thanks for your reply...

I copied both on a single sketch of arduino, and tried to compile. It return only one error at under void loop() section:
Quote
In function 'void loop()':
error: 'scp1000_getHeightCM' was not declared in this scope


and this is the code of line that runs the problem:
Code: [Select]
long heightCm = scp1000_getHeightCM (pressure);
I think that it is a function to convert pressure to height. However, it is true that is was not declared or write anywere. The full code of this function does not exist.

By the way, to convert the "modPressureSCP1000" seems to me to be a usefull thing since it made shorter and clear the final pde.file. How could i do that? I think that it could be by saving this file such an .h file and include its file in the code at the head of the main file. Am i correct? Thanks!

Anyway, Thanks so much for  your efforts to prepare those files. There looks really usefull and what  I really need.

Cheers!

yennifs

Yes, you could move the initial code to an .h file.  I did not write the code, I just found it and posted the link. It is very well documented and implements all the functions of the sensor.

--Sam

madepablo

Thanks Sam,

Oh, Thanks!
However, just only this function is not implemented. However, it is not so important, and temperature and pressure prodecures are complete. So...

Thanks!

quiensoy

Hi¡¡,
I have  an arduino board promini328_5v and  a sensor  spc1000 SparkFun.
I loaded the glasspusher program(Reply #33) in the arduino board, and in the readings, my temp gives correct, but the pressure varies widely. Is this normal?, Thanks very much

P = 900.28, T = 21.30 C,
P = 900.22, T = 21.30 C,
P = 900.23, T = 21.30 C,
P = 900.20, T = 21.30 C,
P = 900.27, T = 21.30 C,
P = 900.28, T = 21.30 C,
P = 900.23, T = 21.30 C,
P = 900.29, T = 21.30 C,
P = 900.35, T = 21.30 C,
P = 900.20, T = 21.30 C,
P = 900.27, T = 21.30 C,
P = 900.34, T = 21.30 C,
P = 900.20, T = 21.30 C,
P = 900.34, T = 21.30 C,
P = 900.21, T = 21.30 C,

I live to 1090 meters

Go Up