0
Offline
Newbie
Karma: 0
Posts: 10
Arduino rocks
|
 |
« Reply #45 on: March 16, 2010, 09:33:34 am » |
Here is what SparkFun says:
Four user selectable measuring modes combine 17-bit resolution (9cm of air column) with low or ultra-low power consumption, or alternatively 15-bit resolution (18cm of air column) with high speed data read (9Hz) or less than 5uA and power consumption. For example, at Low Power mode, the SCP1000 has an overall resolution of 2 Pa (15cm of air column) and a power consumption of 3.5uA.
I did not review the code from #33, but your values are not far from the 15cm column of air accuracy that SparkFun describes.
The code I linked to a few posts back is very well documented, and you could run it in any mode (high accuracy, low power, etc) so you could easily validate against the specs.
Sam
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 6
Arduino rocks
|
 |
« Reply #46 on: March 16, 2010, 01:18:14 pm » |
Ok, thanks very much, I'll look at that link now, thanks
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 1
Arduino rocks
|
 |
« Reply #47 on: March 31, 2010, 05:19:13 am » |
We have problems getting our Arduino Mega to work with a SPC1000-D01. We have tryed both Dave's code as listed in post #33, with the exception of editing the pins (of course) to : #define CSB 53 // SLAVESELECT #define SPICLOCK 52 // SCK #define DATAOUT 50 //MOSI #define DATAIN 51 //MISO ...and the result is: Initialize High Speed Constant Reading Mode P = 53907, T x 10 = 511 C P = 53907, T x 10 = 511 C P = 53907, T x 10 = 511 C P = 53907, T x 10 = 511 C
We also tryed the libary posted at this: arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236443720/8, but making just functions (and not objects and libaries) as dilbert98122 post #14. ... and the result is: Starting up Temprature (C/F): 51.15 / 124.07 Pressure (hPa): 494.0775146484 --------------------------------- Temprature (C/F): 51.15 / 124.07 Pressure (hPa): 494.0775146484 --------------------------------- Temprature (C/F): 51.15 / 124.07 Pressure (hPa): 494.0775146484 ... As you can see our values don't varries. Is there any logical explanation for this (I suppose YES)? Do we need to do something with the registers at the SCP1000-D01? We're stuck. The code that we would like to work looks like: #include "WProgram.h"
// Class global constants const byte DataOutPin = 50; const byte DataInPin = 51; const byte SPIClockPin = 52;
// Select master/slave pin const byte _selectPin = 53;
// Register Addresses const byte REVID = 0x00; // ASIC Revision Number const byte OPREG = 0x03; // Operation Register const byte OPSTATUS = 0x04; // Operation Status const byte STATUS = 0x07; // ASIC Status const byte PRESSURE = 0x1F; // Pressure 3 MSB const byte PRESSURE_LSB = 0x20; // Pressure 16 LSB const byte TEMP = 0x21; // 16 bit temp const byte RSTR = 0x06; // Soft Reset register
// Mode values const byte HiResMode = 0x0A; // Hi Resolution, Constant Readings const byte StandbyMode = 0x00; // No operation
// Values float TempC; // DegC float BaroP; // in hPa (mbar)
void setup() { Serial.begin(57600); // Open serial connection to report values to host Serial.println("Starting up"); // Set Pin directions pinMode(DataOutPin, OUTPUT); pinMode(DataInPin, INPUT); pinMode(SPIClockPin, OUTPUT); pinMode(_selectPin, OUTPUT); digitalWrite(_selectPin, HIGH); //disable device
// Set SPI control register // SPIE = 0 no interupt // SPE = 1 SPI enabled // DORD = 0 (MSB first) // MSTR = 1 (master) // CPOL = 0 (clock idle when low) // CPHA = 0 (samples MOSI on rising edge) // SPR1 = 1 & SPR0 = 1 (125kHz) SPCR = 0b01010011; SPSR = 0b00000000;
delay(100); // Allow SCP1000 to complete initialization write_register(OPREG, HiResMode); }
void loop() { readTemperature(); readPressure();
Serial.print("Temprature (C/F): "); Serial.print(TempC); Serial.print(" / "); Serial.println( (1.8*TempC + 32) ); Serial.print("Pressure (hPa): "); Serial.println(BaroP, 10); Serial.println("---------------------------------");
delay(1000); }
void write_register(byte register_name, byte data) { //SCP1000 command format is 6-bit address, 1-bit R/W, and 1-bit "0" register_name <<= 2; // Shift register address to upper bits register_name |= 0b00000010; // Write command
digitalWrite(_selectPin, LOW); // Select SPI device spi_transfer(register_name); // Send register location spi_transfer(data); // Send value to record into register digitalWrite(_selectPin, HIGH); // End Communication }
void readPressure() { unsigned long pressure;
// Pressure value is in 19-bit unsigned format // Value = Pa * 4 pressure = read_register(PRESSURE, 1); // Read MSB pressure &= 0b00000111; // mask unused bits pressure <<= 16; // shift into upper word
pressure |= read_register(PRESSURE_LSB, 2); // read low word
// Convert to real pressure in hPa BaroP = pressure / 400.0;
}
void readTemperature() { int temp_in;
// Temperature word is 14-bit signed int = (DegC * 20) temp_in = read_register(TEMP, 2);
// Shift sign bit (bit 13) to proper position for signed int (bit 15) // This is equivalent to multiplying by 4, so now temp_in = DegC * 80 temp_in <<= 2; TempC = temp_in / 80.0; // Convert to real DegC }
unsigned int read_register(byte register_name, byte numBytes) { unsigned int in_word;
// SCP1000 registers are either 1 or 2 bytes long numBytes = (numBytes > 2) ? 2 : numBytes; // ensure # of bytes is 0..2
// SCP1000 command format is 6-bit address, 1-bit R/W, and 1-bit "0" register_name <<= 2; // Shift register address to upper bits register_name &= 0b11111100; //Read command
digitalWrite(_selectPin,LOW); // Select SPI Device spi_transfer(register_name); // Send register address to device
for(; numBytes > 0; --numBytes) { in_word <<= 8; // move existing bits up by one byte in_word |= spi_transfer(0x00); // add next byte }
digitalWrite(_selectPin,HIGH); // End Communiction
return(in_word); }
byte spi_transfer(volatile byte data) { SPDR = data; // Start the transmission while (!(SPSR & (1<<SPIF))) // Wait for the end of the transmission {}; return SPDR; // return the received byte } dilbert98122s code, though edited as explained above. Thanks in advance.
|
|
|
|
« Last Edit: March 31, 2010, 05:21:22 am by Nudeln »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 17
Arduino rocks
|
 |
« Reply #48 on: May 30, 2010, 09:41:24 pm » |
Here is a compilation of code and code fixes from this thread that seems to be working for me. There is code for the Duemilanove. You'll find code for the Mega in the next post. First, use this Sparkfun page to hook the 3.3 volt board to the 5 volt Arduino: http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=65Here is a cheatsheet: Parallax SCP1000 Arduino Deumilanova/Mega 1 VSS/GND gnd 2 AVDD 3.3 v 3 TRIG Connect to gnd if not used 4 DRDY (Int) n/a 5 DVDD 3.3 V 6 PD connect to gnd if not used 7 SCLK pin 13/52 using 10K resistor 8 MOSI pin 11/51 using 10K resistor 9 MISO pin 12/50 straight through (no resistor needed) 10 CSB pin 10/53 using 1K with 10K 3.3v pull up from sensor side of 1K Here is the Adruno Duemilanove code (nothing new, just has fixes discussed) works in 018. Dividing temp by 19 instead of 20 (seemed more accurate for my board at least), and outputed pressure in atmospheres (because I get that). /* SCP1000 (parallax board on 5v arduino duelilanova) code from Conor with fixes by BLP from thread: ( http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213217330/5#5 ) uses pins 10, 11, 12 ,13 Must use resistors with 5volt Arduino talking to this 3.3 volt SPI sensor. See: (http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=65) Parallax SCP1000 Arduino 1 VSS/GND gnd 2 AVDD 3.3 v 3 TRIG Connect to gnd if not used 4 DRDY (Int) n/a 5 DVDD 3.3 V 6 PD connect to gnd if not used 7 SCLK pin 13 using 10K resistor 8 MOSI pin 11 using 10K resistor 9 MISO pin 12 straight through (no resistor needed) 10 CSB pin 10 using 1K with 10K 3.3v pull up from sensor side of 1K */
// define spi bus pins #define SLAVESELECT 10 #define SPICLOCK 13 #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(SLAVESELECT,OUTPUT); digitalWrite(SLAVESELECT,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 &= 0x0000FFFF; // this is BLP's fix pressure = UBLB19(pressure_msb, pressure_lsb); pressure /= 4; Serial.print("PRESSURE (Pa)["); Serial.print(pressure, DEC); Serial.println("]"); Serial.print("PRESSURE (Atm)["); float pAtm=float(pressure)/101325.0; Serial.print(pAtm, 3); Serial.println("]"); temp_in = read_register16(TEMP); float tempC = float(temp_in)/19.0; // use 20 by the spec sheet - my board seems closer to 19 Serial.print("TEMP C ["); Serial.print(tempC , 0); Serial.println("]"); float tempF = tempC*1.8 + 32; Serial.print("TEMP F ["); Serial.print(tempF , 0); Serial.println("]"); Serial.println("--------------------------"); delay(2500); }
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(SLAVESELECT,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(SLAVESELECT,HIGH); delay(10); return(in_byte); }
unsigned long read_register16(char register_name) { byte in_byte1; byte in_byte2; float in_word; register_name <<= 2; register_name &= B11111100; //Read command
digitalWrite(SLAVESELECT,LOW); //Select SPI Device spi_transfer(register_name); //Write byte to device in_byte1 = spi_transfer(0x00); in_byte2 = spi_transfer(0x00); digitalWrite(SLAVESELECT,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(SLAVESELECT,LOW); //Select SPI device spi_transfer(register_name); //Send register location spi_transfer(register_value); //Send value to record into register digitalWrite(SLAVESELECT,HIGH); }
|
|
|
|
« Last Edit: May 31, 2010, 10:06:26 am by itsthemedication »
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #49 on: May 31, 2010, 05:34:16 am » |
Notice how difficult that code is to read. It looks like you used the "Copy for forum" option on the Edit menu of the Arduino IDE.
When copying code for the forum, please don't use that option. It is meant to prepare the code for pasting as a quote, not as code.
The preferred method is to copy the code using Select All and Copy. Then, use the Code button (with the # symbol) and paste the code.
I wish that they would remove the Copy for Forum option from the Edit menu.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 17
Arduino rocks
|
 |
« Reply #50 on: May 31, 2010, 09:18:36 am » |
Thanks for the catch. Yes I did stupidly use the seemingly appropriately named "copy for forum." Sorry. It's fixed now. Here is scp1000 code for the MEGA (tested) Thanks for everyone that contributed in this thread. Mega code - remember the resistors and that the last two ports at the end of the row on the MEga are not 52 and 53, they are gnd ports!!!! /* SCP1000 (parallax board on 5v arduino mega) code from Conor with fixes by BLP from thread: ( http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213217330/5#5 ) uses pins 10, 11, 12 ,13 for Duemilanove or 53, 51, 50, 52 for Arduino Mega Must use resistors with 5volt Arduino talking to this 3.3 volt SPI sensor. See: (http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=65) Parallax SCP1000 ArduinoD/ArduinoMega 1 VSS/GND gnd 2 AVDD 3.3 v 3 TRIG Connect to gnd if not used 4 DRDY (Int) n/a 5 DVDD 3.3 V 6 PD connect to gnd if not used 7 SCLK pin 13/52 using 10K resistor 8 MOSI pin 11/51 using 10K resistor 9 MISO pin 12/50 straight through (no resistor needed) 10 CSB pin 10/53 using 1K with 10K 3.3v pull up from sensor side of 1K */
// define spi bus pins #define SLAVESELECT 53 // CS/SS pin 10 or 53 #define SPICLOCK 52 // clk pin 13 or 52 #define DATAOUT 51 //MOSI pin 11 or 51 #define DATAIN 50 //MISO pin 12 or 50 #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(SLAVESELECT,OUTPUT); digitalWrite(SLAVESELECT,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 &= 0x0000FFFF; // this is BLP's fix pressure = UBLB19(pressure_msb, pressure_lsb); pressure /= 4; Serial.print("PRESSURE (Pa)["); Serial.print(pressure, DEC); Serial.println("]"); Serial.print("PRESSURE (Atm)["); float pAtm=float(pressure)/101325.0; Serial.print(pAtm, 3); Serial.println("]"); temp_in = read_register16(TEMP); float tempC = float(temp_in)/19.0; // use 20 by the spec sheet - my board seems closer to 19 Serial.print("TEMP C ["); Serial.print(tempC , 0); Serial.println("]"); float tempF = tempC*1.8 + 32; Serial.print("TEMP F ["); Serial.print(tempF , 0); Serial.println("]"); Serial.println("--------------------------"); delay(2500); }
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(SLAVESELECT,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(SLAVESELECT,HIGH); delay(10); return(in_byte); }
unsigned long read_register16(char register_name) { byte in_byte1; byte in_byte2; float in_word; register_name <<= 2; register_name &= B11111100; //Read command
digitalWrite(SLAVESELECT,LOW); //Select SPI Device spi_transfer(register_name); //Write byte to device in_byte1 = spi_transfer(0x00); in_byte2 = spi_transfer(0x00); digitalWrite(SLAVESELECT,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(SLAVESELECT,LOW); //Select SPI device spi_transfer(register_name); //Send register location spi_transfer(register_value); //Send value to record into register digitalWrite(SLAVESELECT,HIGH); }
|
|
|
|
« Last Edit: June 01, 2010, 06:55:11 am by itsthemedication »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 3
Arduino rocks
|
 |
« Reply #51 on: June 22, 2010, 10:19:14 am » |
hi, im using the openLog board, this is also arduino compatibel , but much smaller. I get with the "conor" code correct pressure datas, but im little confused about the pins, because i think the pin definition is not the same as at the normal arduino board // define spi bus pins #define SLAVESELECT 10 #define SPICLOCK 17 //SCK 13 #define DATAOUT 11 //MOSI 11 , atmega spec 15 #define DATAIN 12 //MISO 12, atmega spec 16 #define UBLB(a,b) ( ( (a) << 8) | (b) ) #define UBLB19(a,b) ( ( (a) << 16 ) | (b) )
the pin definition have i read from the atmega 328p spec is in my opinion different, so the slaveselectpin is not clear and MOSI, MISO are also different pins. did anyone here also use this openLog Board together with the SCP 1000 over SPI ? have anyone here a method to calculate the heigth from the pressuredata ? Greetings Steffen
|
|
|
|
« Last Edit: June 22, 2010, 10:20:50 am by sbod »
|
Logged
|
|
|
|
|
London, England
Offline
Edison Member
Karma: 3
Posts: 1026
Go! Go! Arduinoooo !!!
|
 |
« Reply #52 on: August 20, 2010, 03:44:08 am » |
Anybody know how I can get in touch with Conor? He was last seen on the forum in 2008.
|
|
|
|
|
Logged
|
|
|
|
|
London, England
Offline
Edison Member
Karma: 3
Posts: 1026
Go! Go! Arduinoooo !!!
|
 |
« Reply #53 on: August 23, 2010, 09:36:32 am » |
Can anyone explain why these commands are necessary? { char in_byte; register_name <<= 2; register_name &= B11111100; //Read command
I've read the SCP1000 datasheet and it makes no sense to me. Also, the AND function doesn't change the number so it is irrelevant as far as I can see. Can anyone explain?
|
|
|
|
|
Logged
|
|
|
|
|
|