[error] I2C Temperature Sensors derived from the LM75

I used the library in PlatformIO extension for VS Code, while, it just show: -0.50

Has anyone here met with this and how maybe it?

My chip is LM75A.

LM75-UNO-1

Does the same code give the same result when uploaded through the Arduino IDE? Then it’s a library code error or an error in your user code. In that case you can ask the library authors (on their Github or whatever) what may be wrong with either the software or hardware setup.

1 Like

Can you write a tiny sketch to narrow it down? You might find it works fine. Does the library you are using have an example sketch? Have you tested that? Did it work?

I’m assuming your room is indeed warmer than -0.5 dgrees C! :grinning:

Cheers,
Norm.

1 Like

I haven’t tested it in Arduino IDE, and my sketch was tiny.
I haven’t tested the example sketch.
I changed the chip, result was the same, since I haven’t received mail from the authors, now I want to changed into other library.

Ok, I’m playing with an LM75A at the moment.

When it powers up, the defaults are such that the register holding themerature data, can be read directly without any further configuration. Just connect and read two bytes of data.

The first byte is the two’s complement, ie signed, value of the temperature in degrees C, the second ANDed with 0x80, gives .0 or .5 degrees C.

I’m wondering if your LM75 based sensor needs to be configured first? Maybe you need to write the desired temperature register before you can read from it? Check the data sheet.

Maybe you didn’t set the TWI speed? I forgot with mine and got garbage results. My data sheet says 400 KHz (400,000 as most libraries take the value in Hz) maximum. Some devices can’t run reliably at their maximum documented speeds - this is especially true on breadboards where stray capacitance affects things.

You do have a pull-up resistor between SCL and VCC; and another between SDA and VCC? You need one on each line. The data sheet says 10K for an actual LM75.

HTH

Cheers,
Norm.

1 Like

I wired it this way, all the 3 resistors is 10Kohm.

Looks ok. I think you might need to check the data sheet for the actual sensor. Everything looks ok.

Check power up defaults.

Cheers,
Norm.

Ok, let’s cut out the middleman! The code below is a simple Arduino sketch to use direct register access to read the temperature data from register 0, the default at power up for an LM75A sensor. It cuts out all known libraries so talks directly to the sensor usingthe ATMega328P’s built in TWI/I2C hardware.

When uploaded, it will display the current temperature in degrees C on the serial monitor. My sensor address is used, you will need to adjust the 7 bit address for your sensor to suit. The code works out the read and write addresses as necessary.

First up, some useful defines in twi_defines.h:

#ifndef TWI_DEFINES_H
#define TWI_DEFINES_H

//------------------------------------------------------------
// DEFINES FOR CONTROLLER RECEIVER. (No Interrupts)
//------------------------------------------------------------


// TWCR settings ...

#define CTX_START             (1 << TWINT) | \
                              (1 << TWSTA) | \
                              (1 << TWEN) 

#define CTX_REP_START         (CTX_START)

#define CTX_STOP              (1 << TWINT) | \
                              (1 << TWSTO) | \
                              (1 << TWEN)

#define CTX_READ_NACK         (1 << TWINT) | \
                              (1 << TWEN) 


#define CTX_READ_ACK          (CTX_READ_NACK) | \
                              (1 << TWEA)  

#define CTX_SEND_READ_ADDRESS (CTX_READ_NACK)


// Status codes.

#define CTX_STATUS ((TWSR) & 0xF8)

#define CTX_ILLEGAL_START_STOP 0x00

#define CTX_START_SENT         0x08
#define CTX_RESTART_SENT       0x10
#define CTX_ARBIT_LOST         0x38
#define CTX_SLAR_ACK_RCVD      0x40
#define CTX_SLAR_NACK_RCVD     0x48
#define CTX_DATA_ACK_SENT      0x50
#define CTX_DATA_NACK_SENT     0x58


# endif // TWI_DEFINES_H

Next, the actual sketch, TWI_Read.ino:

//
// A sketch to use direct register access to read data from 
// an LM75A temperature sensor.
//
// No interrupts are used. Polling only.
//
// The Arduino is running in "controller-receiver" mode.
//

#include "twi_defines.h"

#define LM75A_ADDRESS 0x4F

// Default prescaler = 1. Atmel says leave alone!
#define PSCALER 1

// Calculate TWBR from desired SCL frequency.
#define SCL_HZ_TO_TWBR(F)   (0.5 * PSCALER) * ((F_CPU/(F)) - 16)

// Calculate SCL frequency (Hz) from TWBR.
#define TWBR_TO_SCL_HZ(T)   F_CPU / (16 + (2 * (T)) * (PSCALER)


void setup() {
    Serial.begin(9600);
    Serial.println("LM75A - Temperature Measurement\n");
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    // VERY VERY IMPORTANT!
    // Set  the SCL clock speed to 200 KHz.
    TWBR = SCL_HZ_TO_TWBR(200000);
}


void waitForStatus(byte requiredStatus) {

    // Wait for the TWI to respond.
    while (!(TWCR & (1 << TWINT)));

    // Grab & print the status byte.
    byte ctxStatus = CTX_STATUS;
    //Serial.println(ctxStatus, HEX);

    // Did we expect that status?
    if (ctxStatus != requiredStatus) {
        Serial.print("Invalid status, expected 0x");
        Serial.print(requiredStatus, HEX);
        Serial.print(", received 0x");
        Serial.println(requiredStatus, HEX);

        
        // Light the LED on errors.
        digitalWrite(LED_BUILTIN, HIGH);

        // Try to stop TWI communications.
        //Serial.print("Sending STOP....Status = 0x");
        TWCR = CTX_STOP;
        
        // Loop the loop forever.
        while (1) ;
    }
}


void loop() {
    byte tempData[2];
    
    // Send start condition.
    //Serial.print("Sending START....Status = 0x");
    TWCR = CTX_START;
    waitForStatus(CTX_START_SENT);

    // Send LM75A read address.
    //Serial.print("Sending LM75A Address = 0x"); 
    TWDR = (((LM75A_ADDRESS) << 1) | 1);
    //Serial.print(TWDR, HEX);
    //Serial.print("...Status = 0x");
    TWCR = CTX_SEND_READ_ADDRESS;
    waitForStatus(CTX_SLAR_ACK_RCVD);

    // Read two bytes, first with ack, second with nack.
    //Serial.print("Reading byte 1....Status = 0x");
    TWCR = CTX_READ_ACK;
    waitForStatus(CTX_DATA_ACK_SENT);
    tempData[0] = TWDR;
    
    //Serial.print("Reading byte 2....Status = 0x");
    TWCR = CTX_READ_NACK;
    waitForStatus(CTX_DATA_NACK_SENT);
    tempData[1] = TWDR;

    //Serial.print("Sending STOP....Status = 0x");
    TWCR = CTX_STOP;


    // Did we get a temperature?
    Serial.print(" ");
    Serial.print(tempData[0]);
    Serial.println((tempData[1] & 0x80) ? ".5 C" : ".0 C");

    delay(5000);
}

There are lots of commented out Serial.print() statements to show how we are doing. Uncomment them if necessary if you see problems.

The sketch will loop around printing the current temperature to the Serial Monitor.

Try running this sketch and we can then determine if the library you are using is broken, or if your sensor(s) are not working etc.

Cheers,
Norm.

1 Like

I bought some new LM75A chips, the result was the same, but I haven’t test your code upper.

I want to test the library and chip on Ubuntu, but I just don’t know where to set the port in PlatformIO extension of VS Code on Ubuntu, since it would not be recognized automatically。

Found, but all the buttons in PlatformIO useless, since I haven’t used this way before, it may take some time to familiar.

I tried your code in Arduino IDE, what’s wrong with this:

fatal error: twi_defines.h: No such file or directory

I posted two files, the first is twi_defines.h, the second was the sketch. If you copied both to the sketch, just delete the line `#include “twi_defines.h”.

To set the port for uploading, edit the platformio.ini file and add something like upload_port = /dev/ttyUSB0, or similar port name. See Redirecting... for full detail.

Cheers,
Norm.

I tested your code just now, it was ok:

Screenshot-from-2020-08-21-15-20-14

I tested it in Arduino IDE, Now the problem is I couldn’t tested it in VS Code. The Arduino IDE and VS Code are all on Ubuntu, it seemed that, all the PlatformIO buttons were disable.

I’m on Linux Mint 19.3 using VSCodium, as opposed to VSCode, but an older version that allows PlatformIO.

Mint is based on Ubuntu so that’s not the problem.

Can you open the terminal in VSCode, and type pio run to compile? Then, if that works, pio run --target upload to upload to the Arduino. If the upload fails as itcannot determine the port, then add upload_port = /dev/ttyUSB0 (or the correct port) to platformio.ini and try again.

The command pio device monitor --eol=CRLF --echo --filter send_on_enter should bring up the monitor.

If those work fine, “something” is broken in VSCode, and I don’t know what.

Cheers,
Norm.

This might explain why the buttons are not working…

I usually open folder in VSCodium and navigate to where the project file platformio.ini is to open a project. I suspect you are doing something different and when the PlatformIO extension doesn’t see the project file in the current folder, it disables the buttons.

That’s a guess, not tested as I’m not near my laptop at the moment.

Cheers,
Norm.