[I want a node] DS3231 RTC-Temp

node-name DS3231-rtc-temp

DS3231 Real Time Clock and Temperature

Inputs

  • ‘I2C’ xod/i2c/i2c
  • ‘ADDR’ byte - I2C address of the device
  • ‘UPD’ pulse - Triggers a new read

Outputs

  • `DT’ xod/datetime/datetime
  • ‘TMP’ A temperature value (in Celsius)
  • ‘DONE’ pulse - Fires on successful read

The DS3231 RTC includes a thermometer so it should be possible to read this with an XOD node. I have not been able to find one anywhere. The currently available ‘xod-dev/ds-rtc’ does a good job but lacks the output for temperature.
Unfortunately I am new to XOD so am unable to figure out how to extract this data.
There are lots of C++ sample projects (Arduino) that show how to extract temperature with
a ‘int tempC = DS3231_get_treg();’ command.

Thanks,
kurt

Looks like the built-in RTC nodes should work with that hardware. They are under xod-dev/ds-rtc/ in the project browser.

Sure, if you only want the date and time. No temperature function can be collected. I can’t find a node that takes data from the ‘DT’ output and turns it into temperature string data.
There’s a node ‘unpack-datetime’ but not ‘unpack-temp’
If you can help, id be over the moon.
Thanks,
Kurt

I do have a separate DHT22 humidity/temperature sensor but when I created a XOD project with both RTC and HT the application used too much memory for an UNO. So as the RTC has temp on it might as well use it. The other option is to just use the Arduino IDE and save lots of memory.
I like XOD because it is very easy to teach my 10 year old grandson how to build his own projects. So I’m trying to persist with XOD. Maybe I need to look at the internals of the contributed nodes?

Judging from the xod-dev/ds-rtc/read code and what I found here: https://github.com/rodan/ds3231/blob/master/ds3231.h, you should be able to copy the read code, write byte “11h” instead of “00h”, then read just 2 bytes for the temperature. The following code converts those 2 bytes to a temperature (each Wire.read() is reading one byte; order is important; they get replace by read-byte nodes in your XOD code):

    temp_msb = Wire.read();
    temp_lsb = Wire.read() >> 6;

    if ((temp_msb & 0x80) != 0)
        nint = temp_msb | ~((1 << 8) - 1);      // if negative get two's complement
    else
        nint = temp_msb;

    rv = 0.25 * temp_lsb + nint;

>> can be performed using the shift-right node (# to the right of >> is “shift bits count” for the node); << using the shift-left node.
& is bitwise-and; | is bitwise-or; ~ is bitwise-not

The code can be pretty much directly converted into XOD nodes and will replace the datetime node in the current “read” node. The new node will return a number instead of a datetime object.

Hi Gweimer,
Thanks, that’s a great response.
My problem is that I wouldn’t know how to convert that into a XOD node. I’m no C++ programmer. I’m only on day 3 of XOD and never programmed in C before.
I’m currently looking at possibilities with ‘evgen30/ds3231-real-clock’ but no obvious solution there.

I think the code above has bugs with the negative calculations. I based my node off this from https://github.com/KeitetsuWorks/DS3231_Temperature/blob/master/DS3231/src/DS3231.c instead:

    temperature_work = (
                (temperature_msb & 7Fh)
            +   (0.25 * ((temperature_lsb & C0h) >> 6)));
    if((temperature_msb & 80h) != 0) {
        temperature_work *= -1;
    }

For LSB calculation, it is redundant to bit mask out the 1st 6 bits, then shift, then divide by 4 (which is what *0.25 is doing). I masked out the extra bits, then divided by 256, which is the same thing if my calculations are correct…

At the end, we multiply by 1 or -1. If the 80h bit of of MSB is set, then the number is negative, so we multiply by -1, else we multiply by 1 so the number is unchanged.

Temperature should be in Celsius.

I don’t have hardware to test with, but this code comes with a money back guarantee…I guarantee you won’t get any money back :slight_smile:

Here is my suggestion for a new read-temperature node:

The triangle nodes in this example are to-bus & from-bus nodes. They basically provide invisible wires to link same-named nodes so I could wire back to the top of the page without crossing wires through the whole patch (the same as the I2C and ADDR busses already on the original “read” node). I started with the xod-dev/ds-rtc/read node mentioned previously, deleted the extra read nodes and the nodes below them. I don’t know if the “defer” node before “DONE” is needed; the intent is to make sure temperature calculations are done before the DONE pin is pulsed.

1 Like

Whew!! Many thanks for all the effort. Very much appreciated.
Now for the feedback. This is my version of your XOD diagram to which I have added the DS3231 and my LCD i2e 20x4.


I think I have all the links and values correct. Sorry I couldn’t figure how to make the ‘arrow’ links so the links are shown.
After compiling and uploiading (no errors) the output is an incremental counter of 0 - 60 at one second increments. I suspect the output is actually ‘seconds’, not temperature.

I can see I’m on a high curve learning this stuff. However, as I’m currently at home in ‘lock-down’ I have lots of time. I trust you are all okay where you live.
Keep safe,
Kurt

1 Like

You are reading seconds. You need to change the write-byte-BYTE value from 00h to 11h to get temperature. The header files for either of the libraries I posted above list the values need for write-byte to retrieve any information like alarms, etc.

I recommend keeping this as separate patch as I posted it, then you can reuse it in many programs and tie the output to LCD, watch node, or just feed it to another part of the program. It will become a new node that you can use just like all the other nodes in XOD. To the right of “Project Browser” in the upper-left corner of you XOD screen, there are several icons. If you hover over them, they give a description. The 1st one that looks like a piece of paper with the corner turned down creates a new patch, which is what becomes a node if you give it input & output pins. Click on this icon & name it something like read-temp, then copy your code above and add input-* and output-* nodes to create pins for the node. You can now use read-temp node just like the original read node, but it will return temperature instead of date-time.

You can easily replace an existing wire with bus nodes (the triangles) by selecting a wire, then pressing “b”. To create a new triangle node, double-click where you want to create it to bring up the node search. Type “bus” (without the quotes) to see bus nodes & select the one you want to add that node to your patch. This works for all nodes (like “input-” or “output-”) so you don’t have to manually search through the browser to find them. If you don’t like the existing name of your bus, use the node inspector on the bottom-left where you change values for node pins and type a new Label. Bus nodes have to have the same name to be linked together.

1 Like

Hi Gweimer, progress… now we have temperature on the pin.
I have also updated the node with interconnecting arrows on several of the ‘busses’. I’m trying to figure out which ‘output-’ to select as I can’t find one that the datatype matched the multiply output (TEMP). I think I’d better get to the User Manual and start reading.
Edit…“Found a number bus that works”

As the web was impossibly slow this morning and unable to get to this forum, I decided to create a font with glyphs that match the LCD 16x2 and 20x4 square pixel dot matrix. Useful whan creating documentation.
Have fun!
Kurt

It is just a number, so output-number should work. You can name it TEMP once you add it to your patch.

@nkrkv Now that it looks like this code works for reading temperature, should it be added to the built-in nodes for xod-dev/ds-rtc? Additional nodes could be created for reading/setting alarms, etc. also.

1 Like

This is cool, gentlemen, thanks! Indeed, many hardware modules have many “special” functions to which we have no access with XOD standard lib nodes because doing it right takes much time, especially for careful testing, edge-case handling, and documentation.

I agree this particular node will be nice to see in xod-dev/ds-rtc but we are very tight at resources. So, I’m asking for help here. The best way is to make a community fork of ds-rtc: create a copy, add necessary functions, and publish as, say, kurt/ds-rtc. This way we and anyone can quickly verify if it works well or not and merge back to xod-dev/ eventually (keeping the credits, of course).

1 Like

Sounds good!!

However, I can’t take any credit for the code so would suggest gweimer/ds-rtc instead.

One thing I have learned is that the nodes constructed from other nodes are quite inefficient in memory use. My main concern is that anything relatively complex will blow the UNO capacity.

As I’m not capable of C++ programming I can’t do anything about it. My preference is that the node ‘rtc’ or ‘rtc-device’ has the other functions of the DS3231 RTC added and coded in C++.
My original request was because I couldn’t get XOD to support both the DS3231 (rtc) and the DHT22 (dht2x-hygrometer) inclding data formatting for output without blowing memory.

XOD is not the best choice if you want to optimize speed out memory usage. Any abstracted language is going to have extra overhead. You may need to either lower your expectations, or get a bigger Arduino.

gweimer/ds-rtc now exists with just the one new node read-temp

1 Like

Gweimer, you’re a champ!
Yes - I did start looking at upgrading to a MEGA2650.
Unfortunately right now everyone is in lock-down so no suppliers can operate in New Zealand.
Have fun!

1 Like

I’m having trouble getting a temp value out using the patch here. What am I doing wrong. I did change the value at the ‘write-byte’ node to ‘11h’.

read-temp

Sorry, I thought you had said it was working before. I found a bug that would affect any communication attempts after the 1st one. The “request” node specifies how many bytes to request. datetime needs 7 bytes. Temperature only needs 2 bytes. I have updated my library with this fix.

1 Like

Hi, here’s the patch which is working. The temperature indicated varies with actual. I can’t figure out what happened when it was replaced by a node although the first version had ‘00h’ at BYTE of the ‘write-byte’ node.

I’m on WhatsApp if it will ease the communication and reduce the large images here that aren’t of general interest.
Have fun!