Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //_____ M A C R O S
- #define TRUE 1
- #define FALSE 0
- //#define F_CPU 4000000UL // 4 MHz XTAL
- #define CMD_RESET 0x1E // ADC reset command
- #define CMD_ADC_READ 0x00 // ADC read command
- #define CMD_ADC_CONV 0x40 // ADC conversion command
- #define CMD_ADC_D1 0x00 // ADC D1 conversion
- #define CMD_ADC_D2 0x10 // ADC D2 conversion
- #define CMD_ADC_256 0x00 // ADC OSR=256
- #define CMD_ADC_512 0x02 // ADC OSR=512
- #define CMD_ADC_1024 0x04 // ADC OSR=1024
- #define CMD_ADC_2048 0x06 // ADC OSR=2056
- #define CMD_ADC_4096 0x08 // ADC OSR=4096
- #define CMD_PROM_RD 0xA0 // Prom read command
- //_____ I N C L U D E S
- #include <stdio.h>
- #include <math.h>
- #include <SPI.h>
- //_____ D E F I N I T I O N S
- unsigned long D1; // ADC value of the pressure conversion
- unsigned long D2; // ADC value of the temperature conversion
- unsigned int C[8]; // calibration coefficients
- double P; // compensated pressure value
- double T; // compensated temperature value
- double dT; // difference between actual and measured temperature
- double OFF; // offset at actual temperature
- double SENS; // sensitivity at actual temperature
- double T2; // compensated pressure value, 2nd order
- double OFF2; // compensated pressure value, 2nd order
- double SENS2; // compensated pressure value, 2nd order
- int i = 0;
- unsigned char n_crc;
- const int miso_port = 23;
- const int mosi_port = 22;
- const int sck_port = 14;
- const int slaveSelectPin = 21;
- SPISettings settings(4000000, MSBFIRST, SPI_MODE0);
- elapsedMillis looptime = 0;
- void setup() {
- delay(1000);
- pinMode(slaveSelectPin, OUTPUT);
- pinMode(miso_port, OUTPUT);
- pinMode(sck_port, OUTPUT);
- pinMode(mosi_port, INPUT);
- SPI.setMOSI(mosi_port);
- SPI.setMISO(miso_port);
- SPI.setSCK(sck_port);
- SPI.begin();
- SPI.beginTransaction(settings);
- //cmd_reset(); // reset the module after powerup
- for (i=0;i<8;i++){ C[i]=cmd_prom(i);} // read calibration coefficients
- n_crc=crc4(C);
- SPI.endTransaction();
- }
- void loop() {
- SPI.beginTransaction(settings);
- // put your main code here, to run repeatedly:
- D1 = cmd_adc(CMD_ADC_D1 + CMD_ADC_256); // read uncompensated pressure
- D2 = cmd_adc(CMD_ADC_D2 + CMD_ADC_4096); // read uncompensated temperature
- // calcualte 1st order temperature (MS5803_01b 1st order algorithm), base for 2nd order temperature and pressure
- dT = D2 - C[5] * pow(2, 8);
- OFF = C[2] * pow(2, 16) + dT * C[4] / pow(2, 7);
- SENS = C[1] * pow(2, 15) + dT * C[3] / pow(2, 8);
- T = (2000 + (dT * C[6]) / pow(2, 23)) / 100;
- // calcualte 2nd order pressure and temperature (MS5803_01b 2nd order algorithm)
- if (T > 20) {
- T2 = 0;
- OFF2 = 0;
- SENS2 = 0;
- if (T > 45) {
- SENS2 -= pow(T - 4500, 2) / pow(2, 3);
- }
- }
- else {
- T2 = pow(dT, 2) / pow(2, 31);
- OFF2 = 3 * pow(100*T - 2000, 2);
- SENS2 = 7 * pow(100*T - 2000, 2) / pow(2, 3);
- if (T < 15) {
- SENS2 += 2 * pow(100*T + 1500, 2);
- }
- }
- //Recalculate T, OFF, SENS based on T2, OFF2, SENS2
- T -= T2;
- OFF -= OFF2;
- SENS -= SENS2;
- P = (((D1 * SENS) / pow(2, 21) - OFF) / pow(2, 15)) / 100;
- SPI.endTransaction();
- Serial.println(T);
- delay(100);
- looptime = 0;
- }
- ////********************************************************
- ////! @brief send 8 bit using SPI hardware interface
- ////!
- ////! @return 0
- ////********************************************************
- //void spi_send(char cmd)
- //{
- // SPDR= cmd; // put the byte in the SPI hardware buffer and start sending
- // while (bit_is_clear(SPSR, 7)); // wait that the data is sent
- //}
- //********************************************************
- //! @brief send reset sequence
- //!
- //! @return 0
- //********************************************************
- void cmd_reset(void)
- {
- digitalWrite(slaveSelectPin, LOW); //csb_lo(); // pull CSB low to start the command
- SPI.transfer(CMD_RESET); // send reset sequence
- delay(3); // wait for the reset sequence timing
- digitalWrite(slaveSelectPin, HIGH); //csb_hi(); // pull CSB high to finish the command
- }
- //********************************************************
- //! @brief preform adc conversion
- //!
- //! @return 24bit result
- //********************************************************
- unsigned long cmd_adc(char cmd)
- {
- digitalWrite(slaveSelectPin, LOW);
- unsigned int ret;
- unsigned long temp = 0;
- cmd = SPI.transfer(CMD_ADC_CONV + cmd); // send conversion command
- switch (cmd & 0x0f) // wait necessary conversion time
- {
- case CMD_ADC_256 : delayMicroseconds(900); break;
- case CMD_ADC_512 : delay(3); break;
- case CMD_ADC_1024: delay(4); break;
- case CMD_ADC_2048: delay(6); break;
- case CMD_ADC_4096: delay(10); break;
- }
- digitalWrite(slaveSelectPin, HIGH); // csb_hi(); // pull CSB high to finish the conversion
- digitalWrite(slaveSelectPin, LOW); // csb_lo(); // pull CSB low to start new command
- SPI.transfer(CMD_ADC_READ); // send ADC read command
- SPDR = SPI.transfer(0x00); // send 0 to read 1st byte (MSB)
- ret = SPDR;
- temp = 65536 * ret;
- SPDR = SPI.transfer(0x00); // send 0 to read 2nd byte
- ret = SPDR;
- temp = temp + 256 * ret;
- SPDR = SPI.transfer(0x00); // send 0 to read 3rd byte (LSB)
- ret = SPDR;
- temp = temp + ret;
- digitalWrite(slaveSelectPin, HIGH); // csb_hi(); // pull CSB high to finish the read command
- return temp;
- }
- //********************************************************
- //! @brief Read calibration coefficients
- //!
- //! @return coefficient
- //********************************************************
- unsigned int cmd_prom(char coef_num)
- {
- unsigned int ret;
- unsigned int rC = 0;
- digitalWrite(slaveSelectPin, LOW); //csb_lo(); // pull CSB low
- SPI.transfer(CMD_PROM_RD + coef_num * 2); // send PROM READ command
- SPDR = SPI.transfer(0x00); // send 0 to read the MSB
- ret = SPDR;
- rC = 256 * ret;
- SPDR = SPI.transfer(0x00); // send 0 to read the LSB
- ret = SPDR;
- rC = rC + ret;
- digitalWrite(slaveSelectPin, HIGH); //csb_hi(); // pull CSB high
- return rC;
- }
- //********************************************************
- //! @brief calculate the CRC code for details look into CRC CODE NOTES
- //!
- //! @return crc code
- //********************************************************
- unsigned char crc4(unsigned int n_prom[])
- {
- int cnt; // simple counter
- unsigned int n_rem; // crc reminder
- unsigned int crc_read; // original value of the crc
- unsigned char n_bit;
- n_rem = 0x00;
- crc_read = n_prom[7]; //save read CRC
- n_prom[7] = (0xFF00 & (n_prom[7])); //CRC byte is replaced by 0
- for (cnt = 0; cnt < 16; cnt++) // operation is performed on bytes
- { // choose LSB or MSB
- if (cnt % 2 == 1) n_rem ^= (unsigned short) ((n_prom[cnt >> 1]) & 0x00FF);
- else n_rem ^= (unsigned short) (n_prom[cnt >> 1] >> 8);
- for (n_bit = 8; n_bit > 0; n_bit--)
- {
- if (n_rem & (0x8000))
- {
- n_rem = (n_rem << 1) ^ 0x3000;
- }
- else
- {
- n_rem = (n_rem << 1);
- }
- }
- }
- n_rem = (0x000F & (n_rem >> 12)); // // final 4-bit reminder is CRC code
- n_prom[7] = crc_read; // restore the crc_read to its original place
- return (n_rem ^ 0x00);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement