SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By nick26
#65488
Hi all,

First time in the forums, but have been following the site for a while. Keep up the good work!

I'm trying to get a PIC24 talking to a VTI SCP1000 barometric pressure sensor. I've used the code samples from this forum, VTI and other sources to try and clobber something together using the Hi-tech dsPICC compiler. I've sucessfully got comms using the PIC24Fs SPI uart and can read the STATUS, REV_ID registers.

The issue I'm having is after software resetting and initialising a read, the SCP does not seem to put the DRDY pin high, so my program gets stuck... :(

I've checked that I've set the PIC pin correctly as an input and have tried the seocnd SCP I have. Do I need to set the pullup resistor on the pin? No one elses circutis suggest that.

Any ideas?

EDIT:
I've included the main code below. The data being sent for the 'High Resolution Read' seems good on the scope... Will play with that just to make sure I'm not doing something silly. :wink:
Code: Select all
//FROM MAIN

{
	write_uart_string("\n\r");
	write_uart_string("Power up...\n\r");

	timer_wait(200);				//Make sure power is settled for SCP

	//Perform software reset
	printf("Resetting...\n\r");
	write_register(0x06, 0x01);		//RESET ASIC
	timer_wait(60);

	//Check comms
	read_register8(0x00);			//Get ASIC REVISION
	printf("REV_ID: %d\n\r",byte_returned);
	read_register8(0x1F);			//Get Checksum
	printf("CHECKSUM: %d\n\r",byte_returned);
	read_register8(0x07);			//Get STATUS
	printf("STATUS: %d\n\r",byte_returned);

	printf("Set to high res mode\n\r");
	write_register(0x03, 0x0A);		//Set to high res mode

	timer_wait(100);

	read_register8(0x04);			//Get OPSTATUS
	printf("OPSTATUS: %d\n\r",byte_returned);
	read_register8(0x07);			//Get STATUS
	printf("STATUS: %d\n\r",byte_returned);

//STICKS HERE?!
	while(DRDY == 0)
		{
			timer_wait(100);
		}				//Wait for conversion to compelte
//STICKS HERE?!

	temp_data = read_register16(0x21);	//Get TEMPERATURE
	temp_data = temp_data & 0x3fff;
	temp_data = temp_data/20;
	printf("TEMP: %d\n\r",int_returned);

	while(1)
	{
		RIGHT_LED = 1;			//Show read is complete
	}
}

//SPI SEND/RECV 1 byte
//===============
char spi_comm(char spi_byte_out)
{
	SPI1BUF = spi_byte_out;
	while(!(SPI1STAT==0x8001)){};  	//Wait for RX buffer to fill up (tx complete)
	return (SPI1BUF);
}

//WRITE 8 bit REGISTER
//===================
void write_register(char register_name, char register_value)
{
	register_name <<= 2;
	register_name &= 0b11111100;	//Read Command
	CS = 0;
	spi_comm(register_name);		//Write byte to device, ignore returned byte
	spi_comm(register_value);		//Write byte to device, ignore returned byte
	CS = 1;
	return;
}

//READ 8 bit REGISTER
//===================
char read_register8(char register_name)
{
	register_name <<= 2;
	register_name &= 0b11111100;		//Read Command
	CS = 0;
	spi_comm(register_name);		//Write byte to device, ignore returned byte
	byte_returned = spi_comm(0x00);	//Send 8 zeros and get back result
	CS = 1;
	return(byte_returned);
}

//READ 16 bit REGISTER
//===================
int read_register16(char register_name)
{
	char b1,b2;		//temp vars
	register_name <<= 2;
	register_name &= 0b11111100;		//Read Command
	CS = 0;
	spi_comm(register_name);		//Write byte to device, ignore returned byte
	b1 = spi_comm(0x00);	//Send 8 zeros and get back result
	b2 = spi_comm(0x00);	//Send 8 zeros and get back result
	CS = 1;
	int_returned = b1;
	int_returned <<= 8;
	int_returned |= b2;
	return(int_returned);
}
By nick26
#70706
Hi again,

I've decided to pick up the code again and I've realised that after all this time, I've been looking in the wrong registers! :roll:

I've now got working register result fetching code. But when I try to follow the C example off the VTI website, I get Pressure results that are 1x10^9! :( :?

Hitech DsPICc code snippets:
(I've got my compiler to show long ints in the printf function)
Code: Select all
//8 bit
unsigned char spi_byte_out, register_name, register_value, read_byte, byte_returned, press_high;
//16 bit
unsigned int int_returned, temp_data, press_low;
//32 bit
unsigned long int press_total;

//SCP1000 Sensor reading
//======================
void scp_read(void)
{
	TRIG = 1;					//Set off measurement
	TRIG = 0;

	while(DRDY == 0)			//Wait for conversion to complete
	{
	}

	//DISPLAY TEMPERATURE
	temp_data = read_register16(0x21);
	temp_data &= 0x3fff;
	temp_data = (temp_data/20);
	printf("\n\rTEMP(2s comp)(degC): %d\n\r",temp_data);

	//DISPLAY PRESSURE
	press_total = 0;
	press_total = (0x0007 & read_register8(0x1F));
	press_total <<= 16;
	press_total |= read_register16(0x20);
	press_total >>= 2;
        //Convert to Pascals by div 4 (right-shift by 2)
	printf("Pressure(Pa): %li\n\r",press_total);
}

I've set the sensor to be in 17 bit low power triggered mode. I did try right shifting the result by another 2 (only want 17 of 19bit result), but that still gave 2x10^8.

Have I missed something obvious and any ideas? :cry:
By emf
#70717
Your read_register16 returns a signed int, so it will probably be sign-extended when you bitwise-or it into press_total. Try masking off the lower 16 bits.
By nick26
#70821
Thanks for the suggestion, I realised that a short while after sending the post. All is well now and getting about 98kPa on a sunny day.

Ta. :wink:
By nick26
#80795
Hello again,

After a small hiatus I decided to test my sensor code, by borrowing someones vacuum vessel. to my dismay, once the pressure was taken down a bit, my sensor readings were way off a relative pressure meter that was connected to the same chamber. On one particular low pressure day, the sensor was reading about 89kPa, whilst calculating it from the pressure of the day, it should have been 96kPa! I've checked the code again and can't find anythign obvious... :cry:

I understand the pressure word is 19 bits long, but the data generated by the sensor is 15/17bits. I assume this is 'big endian'? I'm thinking this may be the source of my issues... i.e. on a good day I get the normal 98kPa, but if it goes off a bit, it goes all wrong?

Comments/questions welcome!