You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BeagleBone Black(BBB)上DCF77信号读取与解码方法咨询

Hey there! Let's get your DCF77 RTC setup on the BeagleBone Black (BBB) sorted out—connecting it to UART4 is a solid choice, and we’ll walk through reading and decoding the signal step by step.

1. Double-Check Hardware Connections First

First, confirm your wiring matches this (critical to avoid damaging the BBB):

  • DCF77 module output pin → BBB P9.11 (UART4_RX)
  • DCF77 module GND → BBB GND (any P9/P8 GND pin, like P9.1)
  • DCF77 module power → BBB 3.3V (e.g., P9.3)

Note: BBB uses 3.3V logic—never feed 5V into its pins, or you’ll fry the UART port!

2. Enable UART4 on the BBB

By default, UART4 might not be enabled. Here's how to turn it on:

Option 1: Use config-pin (temporary, resets on reboot)

Run these commands in the terminal:

# Configure P9.11 as UART receive
sudo config-pin P9.11 uart
# Verify the setting
config-pin -q P9.11

You should see P9.11 Mode: uart as the output.

Option 2: Persist UART4 across reboots

Edit /boot/uEnv.txt with your favorite editor (e.g., sudo nano /boot/uEnv.txt), uncomment or add this line:

cape_enable=bone_capemgr.enable_partno=BB-UART4

Save the file and reboot with sudo reboot. After restarting, check if the UART4 device node exists:

ls /dev/ttyO3

You should see /dev/ttyO3 listed (this is the device file for UART4).

3. Read Raw DCF77 Signal

First, let's confirm we can receive data from the module. We'll use Python's pyserial library for this.

Install dependencies

sudo apt update && sudo apt install python3-pip
sudo pip3 install pyserial

Basic raw data reader script

Create a file named dcf77_raw.py:

import serial

# Initialize UART4 connection (DCF77 typically uses 75 baud, no parity, 8 data bits, 1 stop bit)
ser = serial.Serial(
    port='/dev/ttyO3',
    baudrate=75,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_1,
    bytesize=serial.EIGHTBITS,
    timeout=1
)

try:
    print("Reading raw DCF77 data (press Ctrl+C to stop)...")
    while True:
        data = ser.read(1)
        if data:
            # Print both hex and ASCII for debugging
            print(f"Raw byte: 0x{data.hex()} | ASCII: {data.decode('ascii', errors='replace')}")
finally:
    ser.close()

Run it with python3 dcf77_raw.py. You should see a steady stream of bytes—this confirms the module is sending data to UART4.

4. Decode the DCF77 Time Signal

DCF77 sends a 60-bit frame every minute, packed with date/time, parity checks, and daylight saving info. Here's a script to decode it:
Create dcf77_decoder.py:

import serial
import subprocess

# Initialize UART connection
ser = serial.Serial('/dev/ttyO3', baudrate=75, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_1, bytesize=serial.EIGHTBITS, timeout=1)

def decode_dcf77(bitstring):
    """Decode a 60-bit DCF77 frame into a readable datetime"""
    if len(bitstring) != 60:
        print(f"Invalid frame length: {len(bitstring)} bits")
        return None

    # --- Minute decoding + parity check ---
    min_units = int(bitstring[1:8], 2)
    min_tens = int(bitstring[8:14], 2)
    minute = min_tens * 10 + min_units
    min_parity = bitstring[14]
    # Check odd parity (total 1s should be odd)
    if bin(int(bitstring[1:14], 2)).count('1') % 2 != int(min_parity):
        print("Minute parity check failed")
        return None

    # --- Hour decoding + parity check ---
    hour_units = int(bitstring[16:21], 2)
    hour_tens = int(bitstring[21:23], 2)
    hour = hour_tens * 10 + hour_units
    hour_parity = bitstring[23]
    if bin(int(bitstring[16:23], 2)).count('1') % 2 != int(hour_parity):
        print("Hour parity check failed")
        return None

    # --- Date/Month/Year ---
    day_units = int(bitstring[25:29], 2)
    day_tens = int(bitstring[29:32], 2)
    day = day_tens * 10 + day_units

    weekday = int(bitstring[32:35], 2)  # 1=Monday, 7=Sunday

    month_units = int(bitstring[35:39], 2)
    month_tens = int(bitstring[39:40], 2)
    month = month_tens * 10 + month_units

    year_units = int(bitstring[40:44], 2)
    year_tens = int(bitstring[44:48], 2)
    year = 2000 + (year_tens * 10 + year_units)

    # --- Daylight Saving Time info ---
    dst_active = int(bitstring[49])  # 1 = DST is currently active
    dst_announce = int(bitstring[48])  # 1 = DST change coming next Sunday

    return {
        'datetime': f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}",
        'weekday': weekday,
        'dst_active': dst_active,
        'dst_announce': dst_announce
    }

try:
    bit_buffer = []
    print("Waiting for valid DCF77 frame (press Ctrl+C to stop)...")
    while True:
        data = ser.read(1)
        if data:
            # Convert byte to bit (adjust this based on your module's output)
            # If your module sends 0xFF for high (1) and 0x00 for low (0):
            bit = '1' if ord(data) > 127 else '0'
            bit_buffer.append(bit)

            # Once we have a full 60-bit frame, decode it
            if len(bit_buffer) == 60:
                frame = ''.join(bit_buffer)
                decoded = decode_dcf77(frame)
                if decoded:
                    print("\n--- Decoded DCF77 Time ---")
                    print(f"Datetime: {decoded['datetime']}")
                    print(f"Weekday: {decoded['weekday']} (1=Mon, 7=Sun)")
                    print(f"DST Active: {'Yes' if decoded['dst_active'] else 'No'}")
                    print(f"DST Change Coming: {'Yes' if decoded['dst_announce'] else 'No'}")
                    
                    # Optional: Set BBB system time (requires sudo)
                    datetime_cmd = f"{year:04d}{month:02d}{day:02d}{hour:02d}{minute:02d}.00"
                    subprocess.run(['sudo', 'date', '-s', datetime_cmd], check=True)
                    print("System time updated successfully!")
                # Reset buffer for next frame
                bit_buffer = []
except KeyboardInterrupt:
    print("\nStopping decoder...")
finally:
    ser.close()

Important Notes:

  • Adjust the bit conversion logic if your module outputs different values (e.g., ASCII '0'/'1' instead of raw bytes). Use the raw data reader script to confirm what your module sends.
  • Parity checks are critical—they filter out corrupted frames caused by signal interference.
5. Troubleshooting Tips
  • No data received? Check your wiring, confirm UART4 is enabled with ls /dev/ttyO3, and ensure your DCF77 module has a good antenna (DCF77 is a German longwave signal—you’ll need a clear line of sight or indoor antenna if you’re in Europe, otherwise signal might be weak).
  • Parity checks failing? This means the signal is corrupted—try repositioning the antenna, or add a small delay in the script to account for timing drift.
  • Permission errors? Run the script with sudo to access UART and modify system time.

内容的提问来源于stack exchange,提问作者Ben Jo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:51:35