Erlangen, Germany
Offline
Jr. Member
Karma: 0
Posts: 50
|
 |
« Reply #15 on: August 25, 2011, 12:37:13 pm » |
.... and just because it was to much to put it in one post: MS5541_demo.pde /* MS5541 Pressure Sensor demonstration sketch To obtain the calibration factors run the read-calwords-sketch before. Circuit: MS5541 sensor attached to pins 10 - 13: MOSI: pin 11 MISO: pin 12 SCK: pin 13 MCLK: pin 9 CS is not in use, but might be pin 10 created August 2011 by SMStrauch based on application note AN510 from www.intersema.ch (http://www.meas-spec.com/downloads/Using_SPI_Protocol_with_Pressure_Sensor_Modules.pdf), and with help of robtillaart and ulrichard. Thanks! */
// include librariy: #include <SPI.h>
// generate a MCKL signal const int clock = 9;
//include the calibration factors according to your individual sensor; they MUST be long for internal calculation of the compensated values //intersema.ch provides a file with expected values const long c1 = 2723; const long c2 = 4648; const long c3 = 388; const long c4 = 224; const long c5 = 2309; const long c6 = 54;
void resetsensor() //this function keeps the sketch a little shorter { SPI.setDataMode(SPI_MODE0); SPI.transfer(0x15); SPI.transfer(0x55); SPI.transfer(0x40); }
void setup() { Serial.begin(9600); SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz pinMode(clock, OUTPUT); //sets clockpin on output }
void loop() { TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal analogWrite (clock, 128) ;
void resetsensor(); //resets the sensor, be aware SPI remains in Mode 0 afterwards!
//Temperature: unsigned int tempMSB = 0; //first byte of value unsigned int tempLSB = 0; //last byte of value unsigned int D2 = 0; SPI.transfer(0x0F); //send first byte of command to get temperature value SPI.transfer(0x20); //send second byte of command to get temperature value delay(35); //wait for conversion end SPI.setDataMode(SPI_MODE1); //change mode in order to listen tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value tempMSB = tempMSB << 8; //shift first byte tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value D2 = tempMSB | tempLSB; //combine first and second byte of value Serial.print("Temperature raw ="); Serial.println(D2); //voilá!
void resetsensor();//resets the sensor
//Pressure: unsigned int presMSB = 0; //first byte of value unsigned int presLSB =0; //last byte of value unsigned int D1 = 0; SPI.transfer(0x0F); //send first byte of command to get pressure value SPI.transfer(0x40); //send second byte of command to get pressure value delay(35); //wait for conversion end SPI.setDataMode(SPI_MODE1); //change mode in order to listen presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value presMSB = presMSB << 8; //shift first byte presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value D1 = presMSB | presLSB; //combine first and second byte of value Serial.print("Pressure raw ="); Serial.println(D1);
//calculation of the real values by means of the calibration factors and the maths //in the datasheet const long UT1 = (c5 << 3) + 10000; const long dT = D2 - UT1; const long TEMP = 200 + ((dT * (c6 + 100)) >> 11); const long OFF = c2 + (((c4 - 250) * dT) >> 12) + 10000; const long SENS = (c1/2) + (((c3 + 200) * dT) >> 13) + 3000; long PCOMP = (SENS * (D1 - OFF) >> 12) + 1000; float TEMPREAL = TEMP/10; //2nd order compensation only for T > 0°C const long dT2 = dT - ((dT >> 7 * dT >> 7) >> 3); const float TEMPCOMP = (200 + (dT2*(c6+100) >>11))/10;
Serial.print("Real Temperature [°C]="); Serial.println(TEMPREAL);
Serial.print("Compensated pressure [mbar] ="); Serial.println(PCOMP);
Serial.print("2nd order compensated temperature [°C] ="); Serial.println(TEMPCOMP);
delay(5000); }
Any comments are welcome, and please tell me about your applications with the sensor.
|
|
|
|
« Last Edit: August 25, 2011, 01:45:28 pm by godo »
|
Logged
|
Δεν ελπίζω τίποτα. Δε φοβούμαι τίποτα. Είμαι λέφτερος.
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9393
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #16 on: August 25, 2011, 01:30:11 pm » |
¡Bien hecho  Might include the link to the datasheet in the code
|
|
|
|
|
Logged
|
|
|
|
|
Erlangen, Germany
Offline
Jr. Member
Karma: 0
Posts: 50
|
 |
« Reply #17 on: August 25, 2011, 01:47:59 pm » |
¡Muchas gracias! Links are in.
|
|
|
|
|
Logged
|
Δεν ελπίζω τίποτα. Δε φοβούμαι τίποτα. Είμαι λέφτερος.
|
|
|
|
Erlangen, Germany
Offline
Jr. Member
Karma: 0
Posts: 50
|
 |
« Reply #18 on: October 12, 2011, 08:37:15 am » |
Hi folks, and on it goes: I have a new riddle to solve! Since my project requires quite some memory I decided to upgrade and made myself a neat little Sanguino clone board. It works nicely, I downloaded and installed awesome stuff from here http://avr-developers.com/corefiles/index.html and some Sanguino board data I do not remember from where. It runs both with the Ardu-Duino 644P and Sanguino board settings (but that's probably obvious). Then I tested sketches I already used on my 2009 as this one... no wait, it is far to long. It is the AnalogLogger example from the SdFat-library which I adapted and added a DS18B20. Unfortunately I only figured out the code formally and adapted it without deep understanding. But it runs like a charm logging 4 analog inputs and digital temperature via SPI onto a µSD-Card. So far so good. Now comes the riddle: I also adapted the code I displayed in this post but it won't work. There aren't even osci-spikes on the SCK line which I clearly saw running the SdFat-based code. So to me it looks like the sketch doesn't access the SPI-Bus at all, even though I adjusted the PINs to the right ones on the 644 (SS 4, MOSI 5, MISO 6, SCK 7). So - more of a general understanding question - where exactly does the SdFat library access the information about the PIN configuration? And where do I have to give the SPI library that information (I copied and included ArduinoPins.h from the SdFat diractory, but it didn't help)? Can anybody tell me more about the compiling process, I mean, by selecting a specific board, do I already direct the compiler to a specific file in which the PIN configuration is given or do the respective libraries do that independently of the board I chose; it seems to me a valuable general info and a good point to look for the problem. Thanks in advance, any comment is apreciated, greetings from Patagonia Seb PS: Problem solved with help from Nick. If you modify a .h-file NEVER copy-paste the code but type it. If copy-pasted the changes are visible, appear totally normal but the compiler does not read it properly.
|
|
|
|
« Last Edit: January 26, 2012, 09:03:55 am by godo »
|
Logged
|
Δεν ελπίζω τίποτα. Δε φοβούμαι τίποτα. Είμαι λέφτερος.
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #19 on: May 07, 2012, 09:18:05 am » |
Hey this is great I just bought the sensor and it is pretty small, how did you manage to solder it, any recommendations? What did you use for the 32.768. khz clock? I bought t a DS32khz/ 14-dip .. http://www.maxim-ic.com/datasheet/index.mvp/id/2940I will be using an arduino pro mini for the 3.3 volts that the sensor requires. I will be use this a diving depth logger.. So I will keep you inform. Thanks for the code I will try it, any more tips?
|
|
|
|
|
Logged
|
|
|
|
|
Erlangen, Germany
Offline
Jr. Member
Karma: 0
Posts: 50
|
 |
« Reply #20 on: May 07, 2012, 09:46:52 am » |
Hi there, soldering that little one is a royal pain in the ... soldering hand, I can tell you. End of this week I will try it with a reflow oven, but up to now I managed with no clean flux and a lot of patience. Good luck anyway; if you use SPI for datalogging you will have to put a 74HC125 or so into the DOUT line to avoid interfering of the sensor with the sd-card. And THAT one is a demanding little bugger to solder! This codeline TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal analogWrite (clock, 128) ; takes care of the signal on pin 9. It is not possible to use any pin but the timer pin, so do not simply switch it. It will allow you to skip the extra chip, so it might be an elegant possibility to keep it all small. Good luck and share your progress and chalenges, by all means!
|
|
|
|
|
Logged
|
Δεν ελπίζω τίποτα. Δε φοβούμαι τίποτα. Είμαι λέφτερος.
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #21 on: May 07, 2012, 12:16:43 pm » |
Thanks for the info..
did you ever tried to do it without using the SPI? i don really want to add the 74HC125...but i will have to try it.. or maybe storing values in an external memory and then export it through serial port will be another idea..
i will keep you posted..
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #22 on: May 09, 2012, 10:18:31 pm » |
it was quite a challenge to solder this but and i do not if i broke the sensor for over-heating  this is what i go on the serial port when reading the calibration words... Calibration word 1 =18820 Calibration word 2 =35237 Calibration word 3 =22501 Calibration word 4 =27826 2352 4646 351 217 2405 50 Temperature raw =65535 Pressure raw =65535 Real Temperature in °C=285.00 Compensated pressure in mbar =-209082 2nd order compensated temperature in °C =285.00 some of the values are pretty similar to yours... but the temperature somehow is not working.. another interesting think is that i am using a 8 MHZ arduino not the 16.... so i wonder if the divider is set correctly for the frequency... thanks
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #23 on: May 09, 2012, 11:21:25 pm » |
second try i hooked the 32.768 khz clock i bought directly to the sensor and things got better
first reading is good, second reading is bad...
Temperature raw =30027 Pressure raw =2047 Real Temperature [°C]=31.00 Compensated pressure [mbar] =-12747 2nd order compensated temperature [°C] =31.00 Temperature raw =49151 Pressure raw =2047 Real Temperature [°C]=175.00 Compensated pressure [mbar] =-16794 2nd order compensated temperature [°C] =175.00
i reset and put my finger and temperature increases
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #24 on: May 10, 2012, 09:50:19 am » |
second try i hooked the 32.768 khz clock i bought directly to the sensor and things got better
first reading is good, second reading is bad...
Temperature raw =30027 Pressure raw =2047 Real Temperature [°C]=31.00 Compensated pressure [mbar] =-12747 2nd order compensated temperature [°C] =31.00 Temperature raw =49151 Pressure raw =2047 Real Temperature [°C]=175.00 Compensated pressure [mbar] =-16794 2nd order compensated temperature [°C] =175.00
i reset and put my finger and temperature increases
I solder it again and it is working perfect thank you man.. the diving community really appreciate your effort Temperature raw =29659 Pressure raw =14623 Real Temperature [°C]=28.00 Compensated pressure [mbar] =981 2nd order compensated temperature [°C] =28.00
|
|
|
|
|
Logged
|
|
|
|
|
Erlangen, Germany
Offline
Jr. Member
Karma: 0
Posts: 50
|
 |
« Reply #25 on: May 10, 2012, 02:56:45 pm » |
Great, congratulations! Let me know if you by chance modify the code, because for some reason it only gives X.00 (point zero) temperature values and I would like to have a better resolution. It is great to contribute to the community after I received so much help and advice, I am very happy to share!
|
|
|
|
|
Logged
|
Δεν ελπίζω τίποτα. Δε φοβούμαι τίποτα. Είμαι λέφτερος.
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #26 on: May 12, 2012, 01:41:21 pm » |
Great, congratulations! Let me know if you by chance modify the code, because for some reason it only gives X.00 (point zero) temperature values and I would like to have a better resolution. It is great to contribute to the community after I received so much help and advice, I am very happy to share!
i think that i got it change the calculation of the temeperature to double const double TEMP = 200 + ((dT * (c6 + 100)) >> 11);
double TEMPREAL = TEMP/10; 
|
|
|
|
|
Logged
|
|
|
|
|
Erlangen, Germany
Offline
Jr. Member
Karma: 0
Posts: 50
|
 |
« Reply #27 on: May 14, 2012, 02:49:34 am » |
Wow, great, that is a bit of a surprise though, because: The double implementation on the Arduino is currently exactly the same as the float, with no gain in precision. But, on the other hand: Users who borrow code from other sources that includes double variables may wish to examine the code to see if the implied precision is different from that actually achieved on the Arduino. I will try that asap, thanks!
|
|
|
|
|
Logged
|
Δεν ελπίζω τίποτα. Δε φοβούμαι τίποτα. Είμαι λέφτερος.
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #28 on: May 25, 2012, 09:08:27 pm » |
I realized that having the microsd card and the sensor on the same buss will be too complicated due to the libray SDFAT.. and i dont want to add another IC so i was thingking about doing some bit banging to get the data... somehow i got it to work(i think) the reset and pressure conversion sequence works because i am getting data where i am having problems is on the reading, no reading the correct raw value...how ever if i manually press the sensor with my finger... i start getting numbers...also if i modify the delay on the clk while reading it also changes...  godo please helpme out if you see something weird.. i almost follow the datasheet and some insights of you spi code..
word start=0b1111010000000000;//start sequence unsigned int p1,p2; long reset=0b10101010101010100000000000000000;//reset sequence byte counts;//for debug int dout= 2;//pin for data out MOSI int din=3;//pin for data in MISO int clk=4;//data clock boolean data=0;
void setup() { // initialize the digital pin as an outputand input Serial.begin(9600); pinMode(dout, OUTPUT); pinMode(din, INPUT); pinMode(clk,OUTPUT); }
void loop() { pressure(); //main function delay(3000); // wait for a second }
void pressure() { Serial.println("start Reset"); //---start REset sequence... for(int i=31;i>10;i--) { boolean x; x=bitRead(reset,i); digitalWrite(dout,x); digitalWrite(clk,HIGH); digitalWrite(clk,LOW); } //--------Start Conversion sequence for(int i=15; i>5;i--) { boolean x; x=bitRead(start,i); digitalWrite(dout,x); //--DRIVE CLOCK digitalWrite(clk,HIGH); digitalWrite(clk,LOW); } //wait unti conversion // i keep runing the clock and wait until the Din(miso) detects that it went to 0 and the data is ready data= digitalRead(din); while(data==1) { digitalWrite(clk,HIGH); digitalWrite(clk,LOW); data=digitalRead(din); } //------------ //---start reading //Serial.println("Read raw pressure"); for(int i=16; i>=0;i--) { digitalWrite(clk,HIGH); // drive the clock down delay(10); digitalWrite(clk,LOW); delay(10); data= digitalRead(din);// i read on low cycle de input(output of the sensor) if(data==1) { bitWrite(p1,i,1);// write the value and i index the int to the right.. } else { bitWrite(p1,i,0); } counts++; } //testing to see if shifting will help also Serial.println(p1); p2=p1>>1; Serial.println(p2); Serial.println(counts);//test to se how many times went into for cycle counts=0; }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 69
|
 |
« Reply #29 on: June 04, 2012, 09:23:57 pm » |
|
|
|
|
|
Logged
|
|
|
|
|
|