Jump to content

Real time clock DS3231


IgorS

Recommended Posts

 I have seen many tutorials about connecting real time clock hardware on Orange Pi and Raspberry Pi.
What i didn't like was removing of fake-hwclock service, because I want that RTC works when it is connected, and fake-hwclock when RTC is not connected.
Therefore, I changed /sbin/fake-hwclock script to work in this way.
 

So, here is how to do this, tested on OrangePi+2E, Armbian Ubuntu legacy kernel:

Purchase cheap DS3231 module on eBay (cca. $1) like this one:

http://www.ebay.com/itm/DS3231-AT24C32-IIC-Modul-High-Precision-Real-Time-Clock-Module-Arduino-New-/292041844936?hash=item43ff0ce8c8:g:d80AAOSwdGFYtsFP

Put battery in module.

Shutdown and powerof OPi and connect module:

Orange (i2c0 bus)							RTC module (DS3231 RTC + 24C32 eeprom)
1   3.3V                                    2 VCC
3   PA12 (TWI0_SDA/DI_RX/PA_EINT12)         3 SDA
5   PA11 (TWI0_SCK/DI_TX/PA_EINT11)         4 SCL
9   GND										1 GND

Power up OPi

Install i2c-tools.

sudo apt install i2c-tools

Type command:

i2cdetect -y 0

You should see:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

This means that module is connected properly and that we have DS3231 on address 0x68 and eeprom 24C32 on address 0x57.

Type:

sudo echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
i2cdetect -y 0

You should see:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

This means that system is now using our RTC. Also, now should exist new device /dev/rtc1

Be sure that your system time is right, and type:

sudo hwclock -w -f /dev/rtc1

Now our RTC must have right time. Check with:

sudo hwclock -r -f /dev/rtc1

If everithing was ok, copy /sbin/fake-hwclock to bacup (just in case)

sudo cp ~/programming/sh/fake_hwclock/sbin/fake-hwclock /sbin/fake-hwclock

Edit /sbin/fake-hwclock and place this code in it:

Spoiler

 


!/bin/sh
#
# script: /sbin/fake-hwclock
# Changed by I.S. to use RTC if it is connected
#
#
# Trivial script to load/save current contents of the kernel clock
# from/to a file. Helpful as a *bootstrap* clock on machines where
# there isn't a useful RTC driver (e.g. on development boards). Using
# NTP is still recommended on these machines to get to real time sync
# once more of the system is up and running.
#
# Copyright 2012 Steve McIntyre <93sam@debian.org>
#
# License: GPLv2, see COPYING

# Config variables

# RTC is attached on bus...
i2c_bus=0
eeprom_address="57"
rtc_address="68"

# Orange  PI +2e have RTC, so our device will be:
rtc_device="rtc1"

# fake-hwclock is using cron.hourly to periodically save system clock
cronfile="/etc/cron.hourly/fake-hwclock"

# If you want to periodically synchronize rtc with system time, change this to true
update_rtc_periodically=false

# End of config variables


# I don't know are all needed programs in PATH,
# therefore I'll declare all mine
echo="/bin/echo"
i2cdetect="/usr/sbin/i2cdetect"
grep="/bin/grep"
awk="/usr/bin/awk"
ln="/bin/ln"
hwclock="/sbin/hwclock"
readlink="/bin/readlink"

progs="$echo $i2cdetect $grep $awk $ln $hwclock $readlink"

check_external_progs(){
  not_found=""
  prog=""
  for prog in ${progs}
  do
    if [ ! -e "$prog" ]; then
      not_found=$prog" "$not_found
      echo "Required program not found: $prog"
    fi
  done

  if [ "$not_found"x = ""x ] ; then
    progs_ok=true
  else
    progs_ok=false
  fi
  unset not_found
  unset prog
}

recreate_cronjob() {
if [ ! -e "$1" ]; then
cat << 'EOF' > "$1"
#!/bin/sh
#
# Simple cron script - save the current clock periodically in case of
# a power failure or other crash

if (command -v fake-hwclock >/dev/null 2>&1) ; then
  fake-hwclock save
fi
EOF
fi
}

is_rtc_connected(){
  check_external_progs
  if $progs_ok; then
    list=$($i2cdetect -y "$i2c_bus")
    rtc=$(echo "$list" | $grep "60:" | $awk '{print $10}')
    eeprom=$(echo "$list" | $grep "50:" | $awk '{print $9}')

    if [ "$eeprom" -eq "$eeprom_address" ]; then
      case $rtc in
        "UU")
          t="/dev/$rtc_device"
          r=$($readlink -f /dev/rtc)
          if [ "$r"="$t" ]; then
            $echo "true"
          else
            $ln -sf /dev/$rtc_device /dev/rtc >/dev/null 2>&1
            if [ "$r"="$t" ]; then
              $echo "true"
            else
              $echo "false"
            fi
          fi;;

        $rtc_address)
          $echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device

          sleep 5
          
          $ln -sf /dev/$rtc_device /dev/rtc >/dev/null 2>&1
          
          t="/dev/$rtc_device"
          r=$($readlink -f /dev/rtc)

          if [ "$r"="$t" ]; then
            $echo "true"
          else
            $echo "false"
          fi;;

        *)
          $echo "false";;
      esac
    else
      $echo "false"
    fi
  else
    $echo "false"
  fi
}


# Is RTC installed?
rtc_installed=$(is_rtc_connected)

if $rtc_installed; then
  # We dont need periodically saving
  rm -f "$cronfile" >/dev/null 2>&1
else
  # Restore periodically saving
  recreate_cronjob "$cronfile"
fi


if [ "$FILE"x = ""x ] ; then
    FILE=/etc/fake-hwclock.data
fi

COMMAND=$1
if [ "$COMMAND"x = ""x ] ; then
    COMMAND="save"
fi

FORCE=false
if [ "$2"x = "force"x ] ; then
    FORCE=true
fi

case $COMMAND in
    save)
        if $rtc_installed; then
          #$echo "RTC save"
          $hwclock -w
          if $update_rtc_periodically; then
            $echo "cronjob restore"
            recreate_cronjob "$cronfile"
          fi
        else
          if [ -e $FILE ] ; then
              SAVED="$(cat $FILE)"
              SAVED_SEC=$(date -u -d "$SAVED" '+%s')
              NOW_SEC=$(date -u '+%s')
              if $FORCE || [ $NOW_SEC -ge $SAVED_SEC ] ; then
                  date -u '+%Y-%m-%d %H:%M:%S' > $FILE
              else
                  echo "Current system time: $(date -u '+%Y-%m-%d %H:%M:%S')"
                  echo "fake-hwclock saved clock information is in the future: $SAVED"
                  echo "To force the saved system clock backwards anyway, use \"force\""
              fi
          else
              date -u '+%Y-%m-%d %H:%M:%S' > $FILE
          fi
        fi
        ;;
    load)
        if $rtc_installed; then
          #$echo "RTC load"
          $hwclock -s
        else
          if [ -e $FILE ] ; then
              SAVED="$(cat $FILE)"
              SAVED_SEC=$(date -u -d "$SAVED" '+%s')
              NOW_SEC=$(date -u '+%s')
              if $FORCE || [ $NOW_SEC -le $SAVED_SEC ] ; then
                  date -u -s "$SAVED"
              else
                  echo "Current system time: $(date -u '+%Y-%m-%d %H:%M:%S')"
                  echo "fake-hwclock saved clock information is in the past: $SAVED"
                  echo "To set system time to this saved clock anyway, use \"force\""
              fi
          else
              echo "Unable to read saved clock information: $FILE does not exist"
          fi
        fi
        ;;
    *)
        echo $0: Unknown command $COMMAND
        exit 1
        ;;
esac

Reboot.
Now you should have right system time backed up by RTC.

 

Edited by Tido
added Spoiler
Link to comment
Share on other sites

Armbian & Khadas are rewarding contributors

New version of fake-hwclock script, some mistakes corrected:

Spoiler

 


#!/bin/sh
#
# script: /sbin/fake-hwclock
# Changed by I.S. to use RTC if it is connected
#
#
# Trivial script to load/save current contents of the kernel clock
# from/to a file. Helpful as a *bootstrap* clock on machines where
# there isn't a useful RTC driver (e.g. on development boards). Using
# NTP is still recommended on these machines to get to real time sync
# once more of the system is up and running.
#
# Copyright 2012 Steve McIntyre <93sam@debian.org>
#
# License: GPLv2, see COPYING

# Config variables

# RTC is attached on bus...
i2c_bus=0
eeprom_address="57"
rtc_address="68"

# Orange  PI +2e have RTC, so our device will be:
rtc_device="rtc1"

# fake-hwclock is using cron.hourly to periodically save system clock
cronfile="/etc/cron.hourly/fake-hwclock"

# If you want to periodically synchronize rtc with system time, change this to true
update_rtc_periodically=false

# End of config variables

i2c=false

# I don't know are all needed programs in PATH,
# therefore I'll declare all mine
echo="/bin/echo"
i2cdetect="/usr/sbin/i2cdetect"
grep="/bin/grep"
awk="/usr/bin/awk"
ln="/bin/ln"
hwclock="/sbin/hwclock"
readlink="/bin/readlink"

progs="$echo $i2cdetect $grep $awk $ln $hwclock $readlink"

check_external_progs(){
  not_found=""
  prog=""
  for prog in ${progs}
  do
    if [ ! -e "$prog" ]; then
      not_found=$prog" "$not_found
      echo "Required program not found: $prog"
    fi
  done

  if [ "$not_found"x = ""x ] ; then
    progs_ok=true
  else
    progs_ok=false
  fi
  unset not_found
  unset prog
}

recreate_cronjob() {
if [ ! -e "$1" ]; then
cat << 'EOF' > "$1"
#!/bin/sh
#
# Simple cron script - save the current clock periodically in case of
# a power failure or other crash

if (command -v fake-hwclock >/dev/null 2>&1) ; then
  fake-hwclock save
fi
EOF
fi
}

is_rtc_connected(){
  check_external_progs
  if $progs_ok; then
    #
    if $i2c; then
      list=$($i2cdetect -y "$i2c_bus")
      rtc=$(echo "$list" | $grep "60:" | $awk '{print $10}')
      eeprom=$(echo "$list" | $grep "50:" | $awk '{print $9}')

      #rtc=68

      if [ "$eeprom" -eq "$eeprom_address" ]; then
        case $rtc in
          "UU")
            t="/dev/$rtc_device"
            r=$($readlink -f /dev/rtc)
            if [ "$r" = "$t" ]; then
              $echo "true"
            else
              $ln -sf /dev/$rtc_device /dev/rtc >/dev/null 2>&1
              r=$($readlink -f /dev/rtc)
              if [ "$r" = "$t" ]; then
                $echo "true"
              else
                $echo "false"
              fi
            fi;;

          $rtc_address)
            $echo ds1307 0x$rtc_address > /sys/class/i2c-adapter/i2c-$i2c_bus/new_device

            sleep 5

            $ln -sf /dev/$rtc_device /dev/rtc >/dev/null 2>&1

            t="/dev/$rtc_device"
            r=$($readlink -f /dev/rtc)

            if [ "$r" = "$t" ]; then
              $echo "true"
            else
              $echo "false"
            fi;;

          *)
            $echo "false";;
        esac
      else
        $echo "false"
      fi
    else
      $echo "false"
    fi
    #
  else
    $echo "false"
  fi
}

#i2c=true
#is_rtc_connected
#exit


if [ "$FILE"x = ""x ] ; then
    FILE=/etc/fake-hwclock.data
fi

COMMAND=$1
if [ "$COMMAND"x = ""x ] ; then
    COMMAND="save"
fi

FORCE=false
if [ "$2"x = "force"x ] ; then
    FORCE=true
fi

# Wait for i2c
$i2cdetect -y "$i2c_bus" >/dev/null 2>&1
r=$?
if [ "$COMMAND" = "load" ] || [ "$r" -eq 0 ]; then
  c=20
  r=1

  until [ "$r" -eq 0 ] || [ "$c" -eq 0 ]
  do
    $i2cdetect -y "$i2c_bus" >/dev/null 2>&1
    r=$?
    c=$(($c - 1))
    if [ "$r" -eq 0 ]; then
      i2c=true
    else
      sleep 1
    fi
  done
fi

# Is RTC installed?
rtc_installed=$(is_rtc_connected)

if $rtc_installed; then
  # We dont need periodically saving
  rm -f "$cronfile" >/dev/null 2>&1
else
  # Restore periodically saving
  recreate_cronjob "$cronfile"
fi

case $COMMAND in
    save)
        if $rtc_installed; then
          #$echo "RTC save"
          $hwclock -w
          if $update_rtc_periodically; then
            $echo "cronjob restore"
            recreate_cronjob "$cronfile"
          fi
        else
          if [ -e $FILE ] ; then
              SAVED="$(cat $FILE)"
              SAVED_SEC=$(date -u -d "$SAVED" '+%s')
              NOW_SEC=$(date -u '+%s')
              if $FORCE || [ $NOW_SEC -ge $SAVED_SEC ] ; then
                  date -u '+%Y-%m-%d %H:%M:%S' > $FILE
              else
                  echo "Current system time: $(date -u '+%Y-%m-%d %H:%M:%S')"
                  echo "fake-hwclock saved clock information is in the future: $SAVED"
                  echo "To force the saved system clock backwards anyway, use \"force\""
              fi
          else
              date -u '+%Y-%m-%d %H:%M:%S' > $FILE
          fi
        fi
        ;;
    load)
        if $rtc_installed; then
          #$echo "RTC load"
          $hwclock -s
        else
          if [ -e $FILE ] ; then
              SAVED="$(cat $FILE)"
              SAVED_SEC=$(date -u -d "$SAVED" '+%s')
              NOW_SEC=$(date -u '+%s')
              if $FORCE || [ $NOW_SEC -le $SAVED_SEC ] ; then
                  date -u -s "$SAVED"
              else
                  echo "Current system time: $(date -u '+%Y-%m-%d %H:%M:%S')"
                  echo "fake-hwclock saved clock information is in the past: $SAVED"
                  echo "To set system time to this saved clock anyway, use \"force\""
              fi
          else
              echo "Unable to read saved clock information: $FILE does not exist"
          fi
        fi
        ;;
    check)
        if $rtc_installed; then
          echo "RTC installed"
        else
          echo "RTC not installed"
        fi
        ;;
    *)
        echo $0: Unknown command $COMMAND
        exit 1
        ;;
esac

 

Link to comment
Share on other sites

Today I connected a I2C RTC to my NanoPi Neo Core2, worked without a problem....but if anyone is getting the same RTC (ZS-042) and using a CR2032 battery - please remove the smd resistor in the upper right corner, because this board does charge the battery, because there should normally be a LIR2032 rechargeable battery.

 

see https://www.youtube.com/watch?v=ND2shVqV9s4

at 02:00

 

and I2C instructions at
https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/

I2C_RTC.jpg

Link to comment
Share on other sites

Hi all, I'm looking to connect a DS3231 battery-backed RTC to my OPI PC Plus, and I want to confirm I'm connecting it properly.  Here's an image of a Raspberry Pi with the module I'm using (I'm assuming the GPIO is the same config as my OPI).  Is this correct? I'm not seeing the eeprom at address 57 when using i2cdetect.

 

 

rtc.PNG

Link to comment
Share on other sites

Yes, since the DS3231 is using I2C bus and that both RPi and OPi are using the same pins for I2C/GND/3.3V, you're are safe to use this small module.

About EEPROM, that is normal you can't find it with i2cdetect since the EEPROM isn't present on your module, it is a searate chip also attached on I2C bus, on previous picture, it is the 24C32.

 

Link to comment
Share on other sites

33 minutes ago, MarshallMCH said:

Hi all, I'm looking to connect a DS3231 battery-backed RTC to my OPI PC Plus, and I want to confirm I'm connecting it properly.  Here's an image of a Raspberry Pi with the module I'm using (I'm assuming the GPIO is the same config as my OPI).  Is this correct? I'm not seeing the eeprom at address 57 when using i2cdetect.

 

 

rtc.PNG

Yes, those little modules are great; they don't contain any EEPROM, that's why the address isn't visible. Just note the direction of the header on your OrangePi PC Plus. I couldn't find the info for your board, but for my Orange Pi Lite, the header is "backwards"

 

 

20180315_151546.jpg

Link to comment
Share on other sites

3 minutes ago, martinayotte said:

Yes, since the DS3231 is using I2C bus and that both RPi and OPi are using the same pins for I2C/GND/3.3V, you're are safe to use this small module.

About EEPROM, that is normal you can't find it with i2cdetect since the EEPROM isn't present on your module, it is a searate chip also attached on I2C bus, on previous picture, it is the 24C32.

 

 

My module seems to have a eeprom (68 = UU after I2C init):
 

root@nanopi-core2:~# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

NanoPi, OrangePi and RPi does have the same signals:
(1) 3.3V

(3) I2C SDA

(5) I2C SCK

(7) not used on RTC Module

(9) GND

 

 

OPi_Pins_I2C.jpg

Link to comment
Share on other sites

2 minutes ago, Larry Bank said:

Yes, those little modules are great; they don't contain any EEPROM, that's why the address isn't visible.

but I dont like the soldered battery :( therefore I used the external module :) after disabling the charging circuit now with CR2032 Battery on the back.

 

I did like the documentation at
https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/

but it was for the RPi which has at that pins I2C-1 and the OPi and NanoPi has at this Pins I2C-0 connected...

 

So I used such commands:

i2c DS3231N Clock:
apt install i2c-tools
armbian-config: activate I2C-0
i2cdetect -y 0
(modprobe) rtc-ds1307  ==> /etc/modules

in /etc/rc.local:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
hwclock -s

Once correct you can write the system date and time to the RTC module using :
sudo hwclock -w

You should be able to read the date and time back from the RTC using :
sudo date; hwclock -r

compare hwclock
sudo hwclock -c

NeoCore2 Mini Shield:
Number#	Name	Number#	Name
1	SYS_3.3V		2	VDD_5V
3	I2C0_SDA / GPIOA12	4	VDD_5V
5	I2C0_SCL / GPIOA11	6	GND

https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/
https://manpages.debian.org/stretch/manpages-de/hwclock.8.de.html
https://www.youtube.com/watch?v=ND2shVqV9s4

echo "Updating time via ntp from ptbtime3.pt.de"
ntpdate -q ptbtime3.ptb.de
echo "writing actual time to hwclock..."
hwclock -w
echo "reading actual time from hwclock..."
date; hwclock -r

 

Link to comment
Share on other sites

Spoiler

 

17 hours ago, guidol said:

but I dont like the soldered battery :( therefore I used the external module :) after disabling the charging circuit now with CR2032 Battery on the back.

 

I did like the documentation at
https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/

but it was for the RPi which has at that pins I2C-1 and the OPi and NanoPi has at this Pins I2C-0 connected...

 

So I used such commands:



i2c DS3231N Clock:
apt install i2c-tools
armbian-config: activate I2C-0
i2cdetect -y 0
(modprobe) rtc-ds1307  ==> /etc/modules

in /etc/rc.local:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
hwclock -s

Once correct you can write the system date and time to the RTC module using :
sudo hwclock -w

You should be able to read the date and time back from the RTC using :
sudo date; hwclock -r

compare hwclock
sudo hwclock -c

NeoCore2 Mini Shield:
Number#	Name	Number#	Name
1	SYS_3.3V		2	VDD_5V
3	I2C0_SDA / GPIOA12	4	VDD_5V
5	I2C0_SCL / GPIOA11	6	GND

https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/
https://manpages.debian.org/stretch/manpages-de/hwclock.8.de.html
https://www.youtube.com/watch?v=ND2shVqV9s4

echo "Updating time via ntp from ptbtime3.pt.de"
ntpdate -q ptbtime3.ptb.de
echo "writing actual time to hwclock..."
hwclock -w
echo "reading actual time from hwclock..."
date; hwclock -r

 

 

It's not a battery soldered on to that small module, it's a tiny supercapacitor

Edited by Tido
Added spoiler
Link to comment
Share on other sites

Hi Igor

 

Thank you for this tutorial - and it works

Spoiler

orangepi@orangepiplus2e:~$ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                         

 

orangepi@orangepiplus2e:~$ timedatectl
      Local time: So 2018-04-08 18:03:35 CEST
  Universal time: So 2018-04-08 16:03:35 UTC
        RTC time: So 2018-04-08 16:03:34
       Time zone: Europe/Berlin (CEST, +0200)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no
orangepi@orangepiplus2e:~$ sudo hwclock -w
[sudo] password for orangepi:
orangepi@orangepiplus2e:~$ timedatectl
      Local time: So 2018-04-08 18:04:04 CEST
  Universal time: So 2018-04-08 16:04:04 UTC
        RTC time: So 2018-04-08 16:04:03
       Time zone: Europe/Berlin (CEST, +0200)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no

 

I want to use rtcwake, but

Quote

sudo rtcwake -n -m off -t $(date -d '20180408 18:45' +%s)
rtcwake: wakeup from "off" using /dev/rtc0 at Mon Jun  9 01:11:54 1930 ;)

logical:

lrwxrwxrwx 1 root root          9 Feb 11  2016 rtc -> /dev/rtc1
crw------- 1 root root   254,   0 Feb 11  2016 rtc0
crw------- 1 root root   254,   1 Feb 11  2016 rtc1

but

sudo rtcwake -n -d /dev/rtc1 -m off -t $(date -d '20180408 18:45' +%s)
rtcwake: cannot open /sys/class/rtc/rtc1/device/power/wakeup: No such file or directory
rtcwake: /dev/rtc1 not enabled for wakeup events

 

What must I do to use rtcwake ?

 

Bye nepo!

Link to comment
Share on other sites

Update:

Newer kernels have module rtc_ds3232 and using this module you will be able to read temperature from DS3231 sensor board via hwmon.

example:

rtctemp=$(cat /sys/class/i2c-adapter/i2c-0/0-0068/hwmon/hwmon0/temp1_input)
rtctemp=$(bc -l <<< "$rtctemp / 1000")

echo "RTC temp = $rtctemp"

Attached is changed fake-hwclock which tryes to load rtc_ds3232 module if ds3231attached variable = yes, and falls back to rtc_ds1307 module on older kernels.

fake-hwclock.tar.gz

Link to comment
Share on other sites

9 minutes ago, IgorS said:

Update:

Newer kernels have module rtc_ds3232 and using this module you will be able to read temperature from DS3231 sensor board via hwmon.

example:

rtctemp=$(cat /sys/class/i2c-adapter/i2c-0/0-0068/hwmon/hwmon0/temp1_input)
rtctemp=$(bc -l <<< "$rtctemp / 1000")

echo "RTC temp = $rtctemp"

Attached is changed fake-hwclock which tryes to load rtc_ds3232 module if ds3231attached variable = yes, and falls back to rtc_ds1307 module on older kernels.

fake-hwclock.tar.gz

Tested on OPi+2E, OPi One, OPi Zero with mainline kernel 4.14.18-sunxi.

Link to comment
Share on other sites

hi

I have tested and read a lot of tutorials, but nothing works - I can't used rtcwake for wakeevents!

Quote

e.g.

orangepi@orangepiplus2e:~$ sudo rtcwake -m off -d /dev/rtc1 -s 300
[sudo] password for orangepi:
rtcwake: assuming RTC uses UTC ...
rtcwake: cannot open /sys/class/rtc/rtc1/device/power/wakeup: No such file or directory
rtcwake: /dev/rtc1 not enabled for wakeup events

but the rtc-modul ds3231 works

Spoiler

orangepi@orangepiplus2e:~$ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                         

orangepi@orangepiplus2e:~$ dmesg |grep rtc
[    3.786757] sun6i-rtc 1f00000.rtc: rtc core: registered rtc-sun6i as rtc0
[    3.786763] sun6i-rtc 1f00000.rtc: RTC enabled
[    8.372324] [drm] Cannot find any crtc or sizes
[    9.440407] [drm] Cannot find any crtc or sizes
[   14.920990] rtc-ds1307 0-0068: registered as rtc1

 

orangepi@orangepiplus2e:~$ sudo hwclock -D -r -f /dev/rtc1
hwclock from util-linux 2.29.2
Using the /dev interface to the clock.
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc1 does not have interrupt functions. Waiting in loop for time from /dev/rtc1 to change
...got clock tick
Time read from Hardware Clock: 2018/04/15 13:58:56
Hw clock time : 2018/04/15 13:58:56 = 1523800736 seconds since 1969
Time since last adjustment is 1523800736 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2018-04-15 15:58:55.297307+0200

 

armbianmonitor -u

 

Can I use my Orange Pi +2e with DS3231 to wake up ?  Anybody has success ?

And why I have not a /proc/driver/rtc ?

Quote

cat /proc/driver/rtc
cat: /proc/driver/rtc: No such file or directory

With my Raspberry 3 and rtc-ds3231 it exist.

 

Bye nepo!

Link to comment
Share on other sites

On 4/15/2018 at 4:26 PM, nepo said:

hi

I have tested and read a lot of tutorials, but nothing works - I can't used rtcwake for wakeevents!

but the rtc-modul ds3231 works

  Reveal hidden contents

orangepi@orangepiplus2e:~$ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                         

orangepi@orangepiplus2e:~$ dmesg |grep rtc
[    3.786757] sun6i-rtc 1f00000.rtc: rtc core: registered rtc-sun6i as rtc0
[    3.786763] sun6i-rtc 1f00000.rtc: RTC enabled
[    8.372324] [drm] Cannot find any crtc or sizes
[    9.440407] [drm] Cannot find any crtc or sizes
[   14.920990] rtc-ds1307 0-0068: registered as rtc1

 

orangepi@orangepiplus2e:~$ sudo hwclock -D -r -f /dev/rtc1
hwclock from util-linux 2.29.2
Using the /dev interface to the clock.
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc1 does not have interrupt functions. Waiting in loop for time from /dev/rtc1 to change
...got clock tick
Time read from Hardware Clock: 2018/04/15 13:58:56
Hw clock time : 2018/04/15 13:58:56 = 1523800736 seconds since 1969
Time since last adjustment is 1523800736 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2018-04-15 15:58:55.297307+0200

 

armbianmonitor -u

 

Can I use my Orange Pi +2e with DS3231 to wake up ?  Anybody has success ?

And why I have not a /proc/driver/rtc ?

With my Raspberry 3 and rtc-ds3231 it exist.

 

Bye nepo!

As far as I know there is no way to wake Orange Pi +2e with DS3231 widouth additional circuitry.

Link to comment
Share on other sites

/proc/driver/rtc ... the system clock RTC may expose itself

https://www.kernel.org/doc/Documentation/rtc.txt

Obviously kernel dependent

 

Rasperry3b:

igor@pi-ubuntu:~$ uname -a
Linux pi-ubuntu 4.14.34-v7+ #1110 SMP Mon Apr 16 15:18:51 BST 2018 armv7l armv7l armv7l GNU/Linux
igor@pi-ubuntu:~$ ls /proc/driver/rtc
/proc/driver/rtc
igor@pi-ubuntu:~$ cat /proc/driver/rtc
rtc_time    : 17:23:12
rtc_date    : 2018-04-17
alrm_time    : 06:17:00
alrm_date    : 2018-04-18
alarm_IRQ    : no
alrm_pending    : no
update IRQ enabled    : no
periodic IRQ enabled    : no
periodic IRQ frequency    : 1
max user IRQ frequency    : 64
24hr        : yes
igor@pi-ubuntu:~$ sudo hwclock
[sudo] password for igor: 
Uto 17 Tra 2018 19:23:48  .676962 seconds

 

OrangePi +2e, legacy kernel:

igor@orangepiplus2e:~$ uname -a
Linux orangepiplus2e 3.4.113-sun8i #18 SMP PREEMPT Wed Jan 24 22:10:49 CET 2018 armv7l armv7l armv7l GNU/Linux
igor@orangepiplus2e:~$ ls /proc/driver/rtc
/proc/driver/rtc
igor@orangepiplus2e:~$ cat /proc/driver/rtc
rtc_time    : 06:05:49
rtc_date    : 1970-01-09
alrm_time    : 11:53:47
alrm_date    : 1970-01-08
alarm_IRQ    : no
alrm_pending    : no
update IRQ enabled    : no
periodic IRQ enabled    : no
periodic IRQ frequency    : 1
max user IRQ frequency    : 64
24hr        : yes
igor@orangepiplus2e:~$ sudo hwclock
[sudo] password for igor: 
Tue 17 Apr 2018 07:20:29 PM CEST  .904616 seconds
igor@orangepiplus2e:~$

 

OrangePi +2e, mainline kernel:

igor@websrv:~$ uname -a
Linux websrv 4.14.18-sunxi #24 SMP Fri Feb 9 16:24:32 CET 2018 armv7l armv7l armv7l GNU/Linux
igor@websrv:~$ ls /proc/driver/rtc
ls: cannot access '/proc/driver/rtc': No such file or directory
igor@websrv:~$ sudo hwclock
[sudo] password for igor: 
Tue 17 Apr 2018 07:39:22 PM CEST  .052402 seconds

 

Link to comment
Share on other sites

Thanks for the script... 

 

I had to adapt it a little, since the script assumes there is a module installed with EEPROM...  My question is why...?  I have a module without EEPROM ( https://www.aliexpress.com/item/New-I2C-RTC-DS1307-High-Precision-RTC-Module-Real-Time-Clock-Module-for-Raspberry-Pi/32610072259.html ) and had to change line 95 into " if [ TRUE ]; then " , since the original line doesn't work for boards without EEPROM. (It tries to evaluate "--" as a number...)

Maybe you want to adapt the script in such a way that it is not depending on the presence of the EEPROM... :-)

 

Link to comment
Share on other sites

Fought this for a while ..... Had weird outputs on a i2cdetect -y 0 , and a DS3231 w. eeprom

Using This kernel :
uname -a
Linux opio2 4.14.18-sunxi #24 SMP Fri Feb 9 16:24:32 CET 2018 armv7l GNU/Linux

I had to add/activate i2c0 and/or i2c1 via overlays.


In /boot/armbianEnv.txt

Add the below i2c0 (and i2c1 if needed) to the overlays line (or create the line if needed).

overlays= ....... i2c0 i2c1

/Bingo

Link to comment
Share on other sites

Hi

 

i'm trying to include a ds3231 rtc module but i'm facing an issue with Opi+2E nightly 5.54 and 4.17.11 kernel

 

I2c-0 and I2c-1 activated through armbian-config : check

i2c-tools installed : check

module correctly wired

i2cdetect -y 0 show me the 0x68 for DS3231 and 0x57 for EEprom

 

but adding new_device returns :

root@orangepiplus2e:~# echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
echo: command not found
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr

 

I seen that link https://www.kernel.org/doc/Documentation/rtc.txt

pointing on "tools/testing/selftests/timers/rtctest.c" but googling said nothing to me, i'm not skilled to do something.

does anyone has a clue please ?

 

Link to comment
Share on other sites

The error you got is a bit strange, it is usually not "command not found" but "permission denied".

 

You can try to do "echo 'ds1307 0x68' | sudo tee /sys/class/i2c-adapter/i2c-0/new_device"

 

Alternatively, you can use your RTC with python script using some python libraries ...

Link to comment
Share on other sites

Thanks martinayotte. 

 

The strange thing is echo works well in some case, eg :

 

echo 1234 > test.txt

 

Works perfectly... 

 

I understood rtc was entirely rewritten in last kernel release. 

I'll try your advice tomorrow thanks a lot. 

Link to comment
Share on other sites

Hi could someone publish a modified version IgorS's custom script (the 3rd version above) for ds3231 RTC's that don't have EEPROMs?

 

I tried to do it myself, but my programming skills just aren't up to it. :(

Any help much appreciated.

 

(Here's the script to save having to download and extract the .tar.gz above.)

 

Spoiler

 

#!/bin/sh
#
# script: /sbin/fake-hwclock
# Changed by I.S. to use RTC if it is connected
# modified to take advantage of module ds3232 on newer kernels.
# if ds3231 attached, change ds3231attached to yes, else to no
# if ds3231 attached and module rtc_ds3232 available on your kernel,
# you will be able to read temperature from rtc module via hwmon
#
# Trivial script to load/save current contents of the kernel clock
# from/to a file. Helpful as a *bootstrap* clock on machines where
# there isn't a useful RTC driver (e.g. on development boards). Using
# NTP is still recommended on these machines to get to real time sync
# once more of the system is up and running.
#
# Copyright 2012 Steve McIntyre <93sam@debian.org>
#
# License: GPLv2, see COPYING

# Config variables

# RTC is attached on bus...
i2c_bus=0
eeprom_address="57"
rtc_address="68"
ds3231attached=yes

# Orange  PI +2e have RTC, so our device will be:
rtc_device="rtc1"

# fake-hwclock is using cron.hourly to periodically save system clock
cronfile="/etc/cron.hourly/fake-hwclock"

# If you want to periodically synchronize rtc with system time, change this to true
update_rtc_periodically=false

# End of config variables

i2c=false
if [ "$ds3231attached" = "yes" ]; then
  modprobe rtc_ds3232 > /dev/null 2>&1
    module=$?
  if [ "$module" != "0" ]; then
    ds3231attached=no
  fi
fi


# I don't know are all needed programs in PATH,
# therefore I'll declare all mine
echo="/bin/echo"
i2cdetect="/usr/sbin/i2cdetect"
grep="/bin/grep"
awk="/usr/bin/awk"
ln="/bin/ln"
hwclock="/sbin/hwclock"
readlink="/bin/readlink"

progs="$echo $i2cdetect $grep $awk $ln $hwclock $readlink"

check_external_progs(){
  not_found=""
  prog=""
  for prog in ${progs}
  do
    if [ ! -e "$prog" ]; then
      not_found=$prog" "$not_found
      echo "Required program not found: $prog"
    fi
  done

  if [ "$not_found"x = ""x ] ; then
    progs_ok=true
  else
    progs_ok=false
  fi
  unset not_found
  unset prog
}

recreate_cronjob() {
if [ ! -e "$1" ]; then
cat << 'EOF' > "$1"
#!/bin/sh
#
# Simple cron script - save the current clock periodically in case of
# a power failure or other crash

if (command -v fake-hwclock >/dev/null 2>&1) ; then
  fake-hwclock save
fi
EOF
fi
}

is_rtc_connected(){
  check_external_progs
  if $progs_ok; then
    #
    if $i2c; then
      list=$($i2cdetect -y "$i2c_bus")
      rtc=$(echo "$list" | $grep "60:" | $awk '{print $10}')
      eeprom=$(echo "$list" | $grep "50:" | $awk '{print $9}')

      #rtc=68

      if [ "$eeprom" -eq "$eeprom_address" ]; then
        
        case $rtc in
          "UU")
            t="/dev/$rtc_device"
            r=$($readlink -f /dev/rtc)
            if [ "$r" = "$t" ]; then
              $echo "true"
            else
              $ln -sf /dev/$rtc_device /dev/rtc >/dev/null 2>&1
              r=$($readlink -f /dev/rtc)
              if [ "$r" = "$t" ]; then
                $echo "true"
              else
                $echo "false"
              fi
            fi;;

          $rtc_address)
            if [ "$ds3231attached" = "yes" ]; then
                $echo ds3232 0x$rtc_address > /sys/class/i2c-adapter/i2c-$i2c_bus/new_device
              else
                $echo ds1307 0x$rtc_address > /sys/class/i2c-adapter/i2c-$i2c_bus/new_device
              fi
              
            sleep 5

            $ln -sf /dev/$rtc_device /dev/rtc >/dev/null 2>&1

            t="/dev/$rtc_device"
            r=$($readlink -f /dev/rtc)

            if [ "$r" = "$t" ]; then
              $echo "true"
            else
              $echo "false"
            fi;;

          *)
            $echo "false";;
        esac
      else
        $echo "false"
      fi
    else
      $echo "false"
    fi
    #
  else
    $echo "false"
  fi
}

#i2c=true
#is_rtc_connected
#exit


if [ "$FILE"x = ""x ] ; then
    FILE=/etc/fake-hwclock.data
fi

COMMAND=$1
if [ "$COMMAND"x = ""x ] ; then
    COMMAND="save"
fi

FORCE=false
if [ "$2"x = "force"x ] ; then
    FORCE=true
fi

# Wait for i2c
$i2cdetect -y "$i2c_bus" >/dev/null 2>&1
r=$?
if [ "$COMMAND" = "load" ] || [ "$r" -eq 0 ]; then
  c=20
  r=1

  until [ "$r" -eq 0 ] || [ "$c" -eq 0 ]
  do
    $i2cdetect -y "$i2c_bus" >/dev/null 2>&1
    r=$?
    c=$(($c - 1))
    if [ "$r" -eq 0 ]; then
      i2c=true
    else
      sleep 1
    fi
  done
fi

# Is RTC installed?
rtc_installed=$(is_rtc_connected)

if $rtc_installed; then
  # We dont need periodically saving
  rm -f "$cronfile" >/dev/null 2>&1
else
  # Restore periodically saving
  recreate_cronjob "$cronfile"
fi

case $COMMAND in
    save)
        if $rtc_installed; then
          #$echo "RTC save"
          $hwclock -w
          if $update_rtc_periodically; then
            $echo "cronjob restore"
            recreate_cronjob "$cronfile"
          fi
        else
          if [ -e $FILE ] ; then
              SAVED="$(cat $FILE)"
              SAVED_SEC=$(date -u -d "$SAVED" '+%s')
              NOW_SEC=$(date -u '+%s')
              if $FORCE || [ $NOW_SEC -ge $SAVED_SEC ] ; then
                  date -u '+%Y-%m-%d %H:%M:%S' > $FILE
              else
                  echo "Current system time: $(date -u '+%Y-%m-%d %H:%M:%S')"
                  echo "fake-hwclock saved clock information is in the future: $SAVED"
                  echo "To force the saved system clock backwards anyway, use \"force\""
              fi
          else
              date -u '+%Y-%m-%d %H:%M:%S' > $FILE
          fi
        fi
        ;;
    load)
        if $rtc_installed; then
          #$echo "RTC load"
          $hwclock -s
        else
          if [ -e $FILE ] ; then
              SAVED="$(cat $FILE)"
              SAVED_SEC=$(date -u -d "$SAVED" '+%s')
              NOW_SEC=$(date -u '+%s')
              if $FORCE || [ $NOW_SEC -le $SAVED_SEC ] ; then
                  date -u -s "$SAVED"
              else
                  echo "Current system time: $(date -u '+%Y-%m-%d %H:%M:%S')"
                  echo "fake-hwclock saved clock information is in the past: $SAVED"
                  echo "To set system time to this saved clock anyway, use \"force\""
              fi
          else
              echo "Unable to read saved clock information: $FILE does not exist"
          fi
        fi
        ;;
    check)
        if $rtc_installed; then
          echo "RTC installed"
        else
          echo "RTC not installed"
        fi
        ;;
    *)
        echo $0: Unknown command $COMMAND
        exit 1
        ;;
esac

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines