OpenWrt Forum Archive

Topic: DS1307 - I2C Real Time Clock

The content of this topic has been archived on 21 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hello,

I have a couple of LaFonera routers with Attitude Adjustment fully working with I2C and 1-Wire protocols.
I added a DS-1307 RTC and it was detected in the I2C bus, so I tried to load it with

echo ds1307 0x68 > /sys/bus/i2c/devices/i2c-0/new_device

However, nothing happened as the hwclock command still returns the same:

root@OpenWrt:~# hwclock -r
hwclock: can't open '/dev/misc/rtc': No such file or directory

Any idea if DS1307 is even supposed to work with openwrt?

Thanks,
Jabss

Quick answer: no.
There are two reasons I see: First off, nobody has ported the ds1307 driver to openwrt, yet. Secondly, the rtc drivers I found all depend on something like a cmos-clock on the platform, which is not available on the common router platforms (atheros, ar71xx, brcm, ramips, ...).

OK, that makes sense, I was just hopping something could be possible to do because the hwclock command is comming with the openwrt releases.

Anyway, I guess I'll have to rethink about my project. Let me share it with you:

Basically I have a distance sensor (HC-SR04) to measure the water level of a tank. This sensor is on the top of the tank and has one input (trigger) and an output (echo).
In order to know the water level, I measure the distance from the sensor to the water. And how can it measure the distance with this device? We have to put the trigger pin at "1" and the sensor will send an ultrasound "ping" that will be reflected in the object (in this case, the water). When the reflection ("pong") reaches the sensor, the echo pin turns "1".
Measuring the time between "ping" and "pong", with some math and  knowing the speed of sound (~340m/s) we can get an approximate distance.

Since the fonera router is not really reliable to measure time (multi tasking OS), I was thinking in somehow using the RTC to measure it, but since its not supported in OpenWRT, I have to come with other alternative.

An additional detail is that the sensor pins are connected to a PCF8574 (I2C port extender) and this may have impact on the measurement time. However, I'm not able to quantify it in order to know if it should be considered in the calculations.

So, any suggestion on how to make this work?

Thanks,
Jabss

Well, I don't think the DS1307 would be a good part for your case. I would use a PCF8583, which is able to run as event counter. Additionally a RS-Flip-Flop and a timer.
What you would do is connect the trigger pin of the PCF8574 to the S-input of the flip-flop, as well as to the Trig pin of the HC-SR04. The echo pin needs to be connected to the R-input of the flip-flop. So this way, you would get a high-output on the flip-flop for the duration of the sonic. Now connect a timer (555) with a pulse-time of 58 µs that runs when the output of the flip-flop is high. Feed the output of the timer into the OSI of the PCF8583 and it will count your distance in cm (since that should work with 6 decimal digits, you could theoretically measure up to 10 km :-)
But, you need to communicate to the PCF8583 directly over I2C (using i2c-get/i2c-set or fopen/fread/fwrite), I haven't found event timer support in the kernel, yet.

Great stuff!!!!

I've just ordered a couple of PCF8583 and 74LS00 for the flip-flop.

I2C rules!

EDIT: Does this look ok?

https://dl.dropboxusercontent.com/u/15615798/Screenshot_2013-08-08-00-13-21.png

Thanks,
Jabss

(Last edited by jabss on 8 Aug 2013, 00:16)

That basically looks pretty good for a start. Now I thought, it might be better to let the 555 run all the time (since I don't know if it needs some time to power-up) and connect its output to one of the free inputs of the 7400. On the other NAND input, you connect your RS-flip flop output (Q or the inverted Q). So the timer will always put logical 0 and 1 on the NAND input, but only when the RS-part gets logical 1, the timer signal gets (inverted) out - into the PCF8583 OSCI. No need for the resistor and transistor - TTL logic is simple plug and play ;-)
For fine-tuning you might consider to place a monoflop between the PCF8574 and the 7400 (and maybe the HC-SR04), so you just have a short pulse to trigger the (I would call it) Set-input of the RS. Otherwise, after the echo has been received, R changes from 1 to 0, but if S is still 1, it will continue to pass-through the timer ticks.

MBS wrote:

Quick answer: no.
There are two reasons I see: First off, nobody has ported the ds1307 driver to openwrt, yet. Secondly, the rtc drivers I found all depend on something like a cmos-clock on the platform, which is not available on the common router platforms (atheros, ar71xx, brcm, ramips, ...).

Ah, just got rtc module off ebay [1] with DS1307 and wanted to implement rtc for my router via openwrt and now I see there is no support for it sad

Has there been any progress regarding driver for DS1307? Which RTC module would you suggets I get that would work out-of-the-box with openwrt?

UPDATE:
Why is DS1307 used as example both on old wiki [2] and there is even a page with perl script that reads and writes data from DS1307 [3]. Are you 100% sure there is no support for DS1307 in OpenWrt?

[1] http://www.ebay.com/itm/190934234297
[2] http://wiki.openwrt.org/oldwiki/port.i2c.rtc
[3] http://wiki.openwrt.org/oldwiki/port.i2c.source_code

(Last edited by valentt on 17 Jan 2014, 21:39)

Well, of course you can use any I2C-device on openwrt, but my definition of support is, that a kernel driver (which exists for the ds1307) is implemented. And this is not the case at the moment. So, you can either use some script to sync your router clock to your ds1307, or you could build your own image and with the additional step of running 'make kernel_menuconfig' enable rtc and ds1307 support in the kernel.
About current progress: I've seen a patch recently in the mailing list, to enable rtc for the ar71xx-platform, but so far it hasn't been applied to trunk. If it ever gets applied, the following I2C-rtc-chips would be supported: ds1672, isl1208, pcf8563, pt7c4338.

MBS wrote:

So, you can either use some script to sync your router clock to your ds1307, or you could build your own image and with the additional step of running 'make kernel_menuconfig' enable rtc and ds1307 support in the kernel.

If there is no driver in current trunk source code hod can I enable rtc and ds1307? Can you please explain how to use some script to sync my router to clock on ds1307? Do you have some example? So it is possible to access ds1307 rtc even without kernel driver?

MBS wrote:

About current progress: I've seen a patch recently in the mailing list, to enable rtc for the ar71xx-platform, but so far it hasn't been applied to trunk. If it ever gets applied, the following I2C-rtc-chips would be supported: ds1672, isl1208, pcf8563, pt7c4338.

Thanks, I'll look into this and apply this patch myself to test it out.

Well, if you like to build your own firmware image, you could do a very simple hack: enter the directory target/linux/generic and edit the config-3.xx file corresponding to your desired kernel version (or all, if you are not sure). Search for the line with

# CONFIG_RTC_CLASS is not set

and change it to

CONFIG_RTC_CLASS=y

And while you are at it, do the same with CONFIG_RTC_DRV_DS1307. Thus, you will have those two modules already in the kernel. Then continue "make menuconfig" where you select the packages you need (including the i2c-driver! and hwclock) and finally issue "make".

(Last edited by MBS on 23 Feb 2014, 12:28)

Hello.
I have a problem with the operation of my modifications to the script /etc/init.d/sysfixtime for RTC DS1307.
So at the beginning I added i2c-gpio-custom bus0=0,1,3 to  /etc/modules.d/rtc-ds1307
next
I mody I have modified script sysfixtime:

#!/bin/sh /etc/rc.common
# Copyright (C) 2013-2014 OpenWrt.org

START=00

boot() {

    if [ -e /sys/bus/i2c/devices/i2c-0/new_device ]; then
        
        echo ds1307 0x68 > /sys/bus/i2c/devices/i2c-0/new_device

        local hardware_time="$(cat /sys/bus/i2c/devices/i2c-0/0-0068/rtc/rtc0/since_epoch)"
        local curtime="$(date +%s)"
        local maxtime="$(find /etc -type f -exec date -r {} +%s \; | sort -nr | head -n1)"

    
        if [ $maxtime -lt $hardware_time ]; then
            date -s @$hardware_time
        elif [ $curtime -lt $maxtime ]; then
            date -s @$maxtime
        fi
        
    fi
}

But it does not work to add the device RTC to the I2C bus in this script.
What could be wrong?

DarioX7 wrote:

But it does not work to add the device RTC to the I2C bus in this script.
What could be wrong?

Please provide some information about which router you are using and what modules you have installed. My first guess would be, that your configuration doesn't have RTC support built in.

I have a TL-WDR3600 and try adding the automatic reading of the DS1307 RTC module AVR voltage converter.

http://www.ojtushwhelectronics.republika.pl/DS1307/Modul.jpg

I have a module in the system:

root@WDR3600:~# cat /etc/modules.d/rtc-ds1307
rtc-ds1307
i2c-gpio-custom bus0=0,1,3

When I'm doing everything manually it works read the RTC from hwlock.

And now it all depends on the script in sysfixtime.

(Last edited by DarioX7 on 8 Feb 2015, 23:02)

Maybe the script gets started before the i2c and ds1307 modules are loaded. Try to add some debug messages to the script to see which code gets executed.

Looks like may be "START=00" is problem.

can you try with START=98 which is same as ntpd and last at boot ?

also why not to use if your rtc is detected well as /dev/rtc0 instead of script-

hwclock -s

so simple set device clock from rtc if you belive rtc clock is most accurate and thats what for
rtc is !

(Last edited by geek007 on 8 Jan 2016, 11:15)

The discussion might have continued from here.