peterhinch / micropython-samples

Assorted code ideas, unofficial MP FAQ, plus index to my other repositories.
MIT License
459 stars 91 forks source link

Cheaper than DS3231 - alternative #36

Open beyonlo opened 1 year ago

beyonlo commented 1 year ago

Hi @peterhinch Thank you to write a driver for the DS3231.

Do you have a driver for another RTC than DS3231? Here follow: " This is a low cost precision battery backed real time clock (RTC) accurate to +-2 minutes/year. Two drivers are provided, one portable across platforms and one which is Pyboard specific. "

Unfortunately the DS3231 is not low cost, it is ~$8.62 for 100 units. I'm using ESP32 becouse need to be a cheap solution, but I need a RTC to not lost datetime when ESP is without energy (power off). Maybe what you want to say is that the DS3231 is low cost for the Extremely Accurate it is, around ~2 minutes per yeat. However I think that for this specific project that I'm doing I don't need to be so accurate, so a cheaper RTC is fine. Do you have a driver for another RTC, or has interest to write one, or know a ready driver for one that is cheaper than DS3231, and maybe not so accurate?

Thank you in advance!

peterhinch commented 1 year ago

In the UK there are boards with DS3231 and a backup battery for under £5. Cheaper if you buy from China. I have no plans to support other RTC devices, sorry.

beyonlo commented 9 months ago

Hello @peterhinch

Sorry to answering in this issue that you already closed, but I found a important information that maybe do you have interested! I at least liked it!

I was buying this Adafruit DS3231 Precision RTC Breakout but I found there also a Adrafruit ChronoDot - Ultra-precise Real Time Clock - v3. The The ChronoDot V3 use the newly-released MAX31328, and it has the same clock accuracy and drift specifications as DS3231. But the MAX31328 is a half of price than DS3231 in the market, in all places: mouser, octopart, digikey, etc. I believe that as this new chip uses newer manufacturing processes and new technologies, the price has decreased significantly on this new chip.

As both (MAX31328 and DS3231) are made by the same brand (analog devices), and datasheet of MAX31328 specs is very very similar with the DS3231, happen me that may be:

  1. I believe that Analog Devices released a new chip with same accuracy, but cheaper to people to migrate from DS3231 to the new MAX31328.
  2. As both are very similiar, is possible that your DS3231 driver works (with few changes) on the MAX31328 too?

Thank you very much!

peterhinch commented 9 months ago

The two Adafruit RTC's are exactly the same price ($17.50). They claim that the ChronoDot works with their DS3231 driver, so I guess it has a good chance of working with mine.

beyonlo commented 9 months ago

The two Adafruit RTC's are exactly the same price ($17.50).

Yes, I noticed that too, but that is just about the Adafruit boards brand - maybe Adafruit to decide (by convenience) let both boards with same same price, since they both have the same accuracy - but the chip used in each board has very different prices:

PN Qty Unit Price
DS3231SN 10 $10.92
MAX31328 10 $4.24

This table above are prices from the mouser: DS3231SN and the MAX31328. That very big difference price is not just in the mouser, in the all market around the world (octopart, digikey, etc) the MAX31328 has half of price than DS3231SN. I believe that happens because this new chip uses newer manufacturing processes and new technologies.

Ps: even choosing other quantities than 10, the price of MAX31328 has around half of price than DS3231SN. So, would be nice if your driver has support to the MAX31328 too :)

They claim that the ChronoDot works with their DS3231 driver, so I guess it has a good chance of working with mine.

Well, so I will buy the Adafruit ChronoDot as well to test with your driver :)

EDIT: Just to be clear, my intenttion (as many other peopler) is to use that RTC chip inside my hardware (without use external rtc boards), so to buy adafruit RTC board is just to test the chip before built my own hardware board using that RTC chip.

peterhinch commented 9 months ago

OK, fair comment.

I regularly receive requests to support new hardware. In practice this means buying a breakout board (I can design PCB's but it's not worth it for a one-off) - but I would need something to test. If problems arose, work would be required to diagnose, fix and document. In this case the cost and effort should be fairly small. However I'm busy with another project at the moment, so new development must wait.

If you are motivated to do this and report the outcome I'll be happy to update the docs and to credit you with the effort. If you encounter problems I'm happy to help.

beyonlo commented 9 months ago

Hello @peterhinch Happy new year for you! I wish you many achievements and good health!

I regularly receive requests to support new hardware. In practice this means buying a breakout board (I can design PCB's but it's not worth it for a one-off) - but I would need something to test. If problems arose, work would be required to diagnose, fix and document. In this case the cost and effort should be fairly small.

Nice. If even with your help I have no success, I can to donate a Adafruit ChronoDot for you - it will be a pleasure.

However I'm busy with another project at the moment, so new development must wait.

Understood!

If you are motivated to do this and report the outcome I'll be happy to update the docs and to credit you with the effort. If you encounter problems I'm happy to help.

Yes, I'm motivated! I have no knowleadge writing device drivers, but I will to try, because the diffrence price between that two chips is very big.

When boards came to me I will to do the initial tests and will report you the results!

Thank you very much!

peterhinch commented 9 months ago

I can to donate a Adafruit ChronoDot for you

I've had a chance to study the datasheet of the MAX31328 and I think I can make it work with my driver with minimal changes. If you can provide a means of contacting you I will give you my address.

beyonlo commented 9 months ago

I've had a chance to study the datasheet of the MAX31328 and I think I can make it work with my driver with minimal changes. If you can provide a means of contacting you I will give you my address.

Perfect! This is my email address: beyonlo@gmail.com

beyonlo commented 8 months ago

@peterhinch Is it possible to use the MAX31328 as RTC and also as an external hardware watchdog?

The idea is: set an alarm1 to: year, month, mday, hour, minute, second. So if I want a watchdog for 5 seconds, I need just to set the first alarm with datetime + 5 seconds, and always to reset/change that alarme to datetime + 5 seconds before that datetime match. If that does not happen (datetime match), an interrupt output will happen on the INT pin of MAX31328. So, the INT pin needs to be connected to the EN/RST pin of MicroController.

How much time does the alarm pin (INT) remain in low before back to high? I had readed the MAX31328 and DS3231 datasheets but I could not find how long that alarm is interrupted. But I found this in your code about alarms:

from machine import SoftI2C, Pin
from ds3231_gen import *
i2c = SoftI2C(scl=Pin(16, Pin.OPEN_DRAIN, value=1), sda=Pin(17, Pin.OPEN_DRAIN, value=1))
d = DS3231(i2c)
while True:
    d.alarm1.clear()  # Clear pending alarm
    while not d.alarm1():  # Wait for alarm
        pass
    time.sleep(0.3)  # Pin stays low for 300ms

So, according to your code, the pin stays low for 300ms and back to high. If that time is correct, so the MAX31328 (and DS3231 too) can work perfectly as a Watchdog too, because that 300ms time to connect to the EN/RST Pin is a good time to reset the MicroController right?

Ps: How did you discover that it is 300 ms? With empirical tests?

A very good thing about using that RTC as Watchdog too is that if for example I will execute an OTA where it takes 5 minutes for example, I need just change the next alarm (Watchdog) to that datetime + 5 minutes.

Does the idea to use RTC also as a powerful Watchdog make sense for you? Or am I missing something?

If that is possible, it would be amazing, use the same chip as RTC and Watchdog using just i2c.

Thank you in advance!

peterhinch commented 8 months ago

I think you have misunderstood the example which works as follows.

The 300ms is determined by the time.sleep(0.3). The code works as follows. On the first iteration of the loop, .clear() is issued to cater for the case where alarm1 is already triggered. The inner loop now waits for an alarm to occur. The alarm causes the pin to go low and the inner loop to terminate. There is then a 300ms delay, during which time the pin stays low. The outer loop then performs another iteration, clearing the alarm. This cause the pin to go high. It then waits for another alarm.

If you connect the pin to rst clearly the code will stop running. The RTC still has power applied, so its pin will remain low which will hold the processor in a reset state forever. Not what you want. It might be possible to do what you want by using a capacitor to drive the rst pin (the int pin would need a pullup resistor). This would ensure that the rst line was only driven low for a brief period. Component values would depend on the circuitry around the rst line.

beyonlo commented 8 months ago

I think you have misunderstood the example which works as follows.

The 300ms is determined by the time.sleep(0.3). The code works as follows. On the first iteration of the loop, .clear() is issued to cater for the case where alarm1 is already triggered. The inner loop now waits for an alarm to occur. The alarm causes the pin to go low and the inner loop to terminate. There is then a 300ms delay, during which time the pin stays low. The outer loop then performs another iteration, clearing the alarm. This cause the pin to go high. It then waits for another alarm.

Sorry for that, my bad. Understood now!

If you connect the pin to rst clearly the code will stop running. The RTC still has power applied, so its pin will remain low which will hold the processor in a reset state forever. Not what you want. It might be possible to do what you want by using a capacitor to drive the rst pin (the int pin would need a pullup resistor). This would ensure that the rst line was only driven low for a brief period. Component values would depend on the circuitry around the rst line.

That's a great news :tada:

Thank you, I will do that!

peterhinch commented 8 months ago

On further study of the datasheet the chip could be used as a WDT.

The int/sqw pin can be set up such that it goes low whenever the seconds of the RTC match those set in alarm1 regardless of the state of the other time registers (Table 2, "Alarm when seconds match" in the datasheet). This differs from the usage in my code sample where the RTC is configured such that all registers must match, and the pin's behaviour is determined by code.

The wdt.feed() operation would set alarm1 to be (say) 5s ahead of the current RTC seconds register. If fed more frequently than every 5s, alarm1 would never fire. If the system crashed, int/sqw would go low for 1s and reset the host (the pin goes low for the duration of the match). The key point here is that the behaviour of int/sqw is determined only by the RTC chip; it is independent of any code running on the host.

Three caveats.

  1. I haven't actually tested this.
  2. The int/sqw line requires a pullup (the host's reset line may provide one).
  3. When the int/sqw line is released after 1s, the host has 59s to start feeding the WDT before the seconds match again.

I think this is a better solution than using a capacitor to limit the pulse duration.

beyonlo commented 8 months ago

The int/sqw pin can be set up such that it goes low whenever the seconds of the RTC match those set in alarm1 regardless of the state of the other time registers (Table 2, "Alarm when seconds match" in the datasheet). This differs from the usage in my code sample where the RTC is configured such that all registers must match, and the pin's behaviour is determined by code.

OK, understood. I noticed that in the datasheet:

image

The wdt.feed() operation would set alarm1 to be (say) 5s ahead of the current RTC seconds register. If fed more frequently than every 5s, alarm1 would never fire.

Ok, understood.

If the system crashed, int/sqw would go low for 1s and reset the host (the pin goes low for the duration of the match).

This is the point where I do not understand. Where in the datasheet did you find that (when "Alarm when seconds match") the duration of pin INT to low will be only 1 second, and after that time pin back do high? I understand that "the pin goes low for the duration of the match", so in this case it will be 1 second in low, and back to high. Ok, but where in the datasheet is it saying something like "the pin goes low for the duration of the match"? Or that is not not explicitly written, but is it a correct interpretation?

  1. I haven't actually tested this.
  2. The int/sqw line requires a pullup (the host's reset line may provide one).
  3. When the int/sqw line is released after 1s, the host has 59s to start feeding the WDT before the seconds match again.

Understood!

I think this is a better solution than using a capacitor to limit the pulse duration.

Very better solution, thank you very much! :balloon:

peterhinch commented 8 months ago

If the pin behaves otherwise I would expect the datasheet to explicitly state its behaviour. My reading of the datasheet is that the pin is active for the duration of the match or until the alarm is cleared (as in my code sample).

It's easily tested.

beyonlo commented 8 months ago

If the pin behaves otherwise I would expect the datasheet to explicitly state its behaviour. My reading of the datasheet is that the pin is active for the duration of the match or until the alarm is cleared (as in my code sample).

Understood. I hope that the pin is active just for the duration of the match :) Otherwise will need that extra circuit to clear the alarm :(

It's easily tested.

I will test that when mine ChronoDot comes!

Thank you very much!