1

I am trying to sense the temperature using the LM70 temperature sensor with an Arduino Mega. As you can see in the Datasheet, it uses the SPI protocol. I have made the following connections (VSSOP-8 Package):

  • SI/O pin --> Pin 50 Arduino Mega.
  • SC pin --> Pin 52 Arduino Mega.
  • CS pin --> Pin 53 Arduino Mega.
  • V+ pin --> 3.3V Arduino Mega.
  • GND pin --> GND Arduino Mega.

My code does not work (it does not print the right temperature), and I think it can be for two reasons:

  1. I am not reading correctly the information from the sensor. It sends 16 bits, from which the 11 first bits store the data for the temperature.
  2. I am not calculating the temperature in the right way.

This is my code:

// the sensor communicates using SPI, so include the library:
#include <SPI.h>

void setup() {
  pinMode(51,OUTPUT); //MOSI
  pinMode(50,INPUT); //MISO
  pinMode(52,OUTPUT); //CLOCK PIN
  digitalWrite(53,HIGH); //slave select stays high. When we set this to low, the sensor will start to send data.
  SPI.begin();
  Serial.begin(9600);

  //time to set up
  delay(500);
}

void loop() {
    //enable Slave
    digitalWrite(A0,LOW); //Enable communication with slave
    delay(500); //wait for conversion
    
    int val = SPI.transfer(0x00); // read from sensor
    Serial.println(val); //display reading on serial monitor
    int temperature = val * 0.25;
    Serial.println(temperature); //display temperature on serial monitor


    //disable Slave
    digitalWrite(53,HIGH); //set to High again
}

Please, if you see something wrong in my code, let me know. Thank you in advance.

2
  • digitalWrite(A0,LOW) -- Are you sure about that one?
    – Majenko
    Commented Oct 8, 2020 at 9:53
  • 1
    You are right, it should be digitalWrite(53, LOW). Thank you!!! However, the code still does not work. Any ideas?
    – Fakiko
    Commented Oct 8, 2020 at 14:23

2 Answers 2

2

There are several things that are not doing correctly. This is not a complete answer but to provide you some directions on how to get it right.

  1. A0 is pin 54, it is not SS which is pin 53;

  2. On how to use the SPI library properly, I would suggest that you read my blog on SPI, it will also help you to get the data out of data sheet that you need for SPI programming. Based on the timing diagram on the data sheet, you will need to configure the SPI as SPI_MODE2;

  3. LM70 SI/O pin is used as both MOSI and MISO, you will need to connect MOSI to SI/O via a 10k resistor, and connect SI/O direct to MISO, this information is available in the data sheet;

  4. LM70's temperature data is in Two's complement format, To convert it, it needs a little bit work. It is then need to shift down/right using bitshift operator by 5 bits to get ride of the first 5-bits, before finally multiply by 0.25C as per data sheet.

int value = 0x4b1f;  //value from SPI, temp = 125 degree C
int mask = 0x8000;   // mask for MSB
int temp = (-(value & mask) + (value & ~mask)) >> 5;
Serial.print("Temp");
Serial.println(temp*.25);

Read all links that I provided to understand the subjects and give it a try. Good luck!

1

Your problem lies here:

    int val = SPI.transfer(0x00); // read from sensor
    Serial.println(val); //display reading on serial monitor
    int temperature = val * 0.25;

And it's a twofold problem.

First:

int val = SPI.transfer(0x00);

That only reads the first 8 bits of the data. To get all 16 bits you have to do two transfers and then combine them together with bitshifting:

int bh = SPI.transfer(0x00);
int bl = SPI.transfer(0x00);
int val = (bh << 8) | bl;

That then gives you a value that is right-aligned. you then need to shift it to the left the right number of bits and "sign extend" it to keep it negative if needed. If you're not interested in the fractional part then it's as simple as:

val >>= 7;
if (val & 0x0100) {
    val |= 0xFE00;
}

Now... what does that all mean? Well, assume it's currently 25°C. From the datasheet we can see that would give us a reading of 0000 1100 1001 1111 (note there is a typo in the datasheet saying that is 0b9f in hex when in fact it's 0c9f).

Let's do those operations - first the bit shift:

Dec   Hex   Bin
3231  0C9F  0000110010011111 >> 7
25    0019  0000000000011001

Then we look to see if bit 8 is set or not (bit 8 was the most significant bit). If it is then we OR it with bits 9-15 also set. This "sign extends" it.

Let's take a look at -25°C from the datasheet:

Dec   Hex  Bin
-3169 f39f 1111001110011111 >> 7      Shift right 7 bits
487   01e7 0000000111100111 & 0x0100  And with 8th bit
256   0100 0000000100000000           Result is not 0 so is true

"Or" the shifted value with 0xFE00:

487   01e7 0000000111100111 or
65024 fe00 1111111000000000 =
-25   ffe7 1111111111100111

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.