简体   繁体   中英

How to sync the clocks in Raspberry Pi?

I'm new to raspberry pi, trying to send a stream of bits from sender to receiver. However bits are not received in correct pattern most of the times, they seems to be shifted a little. I think i'm unable to synchronize them properly. Does anyone how I can sync the clocks

Python Code is here

# Sender
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.OUT)
while True:
  GPIO.output(23, GPIO.HIGH)
  time.sleep(1)
  GPIO.output(23, GPIO.LOW)
  time.sleep(1)
  # .... some more bits here

# Receiver
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN)
while True:
   bit = GPIO.input(17)
   print bit
   time.sleep(1)

You should not try to synchronize the sender and the receiver based on time. You should choose the frequency of sending on the sender side, and let receiver just sit there and wait for the bits to come, without sleeping. Because sleeping makes you miss stuff.

Use:

GPIO.add_event_detect(17, GPIO.BOTH, callback=my_callback)

to listen to a change on the PIN, and execute my_callaback when it happens. You can also choose to wait for rising edge via GPIO.RISING or the falling via GPIO.FALLING .

For your example, here is something to start with, not tested or anything:

import RPi.GPIO as GPIO  
from time import sleep     

GPIO.setmode(GPIO.BCM)     
GPIO.setup(17, GPIO.IN)    

def readbit(channel):  
    bit = GPIO.input(17)
    print bit

GPIO.add_event_detect(17, GPIO.BOTH, callback=readbit)  

while True:
    sleep(1)  # do something useful here

This probably won't be enough, since you can't detect bits that don't change the state. To tackle this, you have quite a few options, and I will only mention two most simple ones:

Control signal

You can use another PIN as a control signal, and use it to trigger the reads on the receiver. This way, you trigger the read on the rising edge of the control pin, and read the value of the data pin.

On the sender:

def send_bit(pin, bit):
    GPIO.output(24, GPIO.HIGH)  # first send the control bit 
    GPIO.output(pin, bit):  # then the data on another pin

while True:
  send_bit(23, GPIO.HIGH)
  time.sleep(1)
  send_bit(23, GPIO.LOW)
  time.sleep(1)

On the receiver:

DATA_PIN = 17
CONTROL_PIN = 18  # or whatever
def readbit(channel):
    bit = GPIO.input(DATA_PIN)
    print bit
GPIO.add_event_detect(CONTROL_PIN, GPIO.RISING, callback=readbit)

One wire protocol

Another solution, if you don't want to use two wires, is to create a simple protocol. For example:

  • Every transmission consists of two bits: 1 and X
  • Data bit to be transferred is X, whereas the first bit is always 1 and serves as a trigger for the receiver
  • The X bit is guaranteed to be active from 0.1 to 0.9 seconds after the first bit's rising edge.

This might be complicated, but it actually isn't. All you need to do now is to trigger the reading on the rising edge, and read the data somewhere between 0.1 and 0.9 seconds after that. Let's make it 0.5 seconds, to be sure we are in the middle of this time.

On the sender:

def send_bit(pin, bit):
    GPIO.output(pin, GPIO.HIGH)  # send the control bit first, always HIGH
    GPIO.output(pin, bit)  # send the actual data bit

while True:
  send_bit(23, GPIO.HIGH)
  time.sleep(1)
  send_bit(23, GPIO.LOW)
  time.sleep(1)
  # .... some more bits here

On the receiver:

def readbit(channel):
    time.sleep(0.5)  # waiting to be in the safe time for read
    bit = GPIO.input(17)
    print bit
GPIO.add_event_detect(17, GPIO.RISING, callback=readbit)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM