How to sync clock in Raspberry Pi?

I'm new to raspberry pi trying to send a stream of bits from sender to receiver. Most of the time, however, the bits are not received in the correct order, they seem to be shifted a little. I think I cannot sync them properly. Anyone how can I sync my watch

Python code 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)

      

+3


source to share


1 answer


You should not try to synchronize the sender and receiver based on time. You have to choose the sending frequency on the sender side and let the receiver just sit there and wait for the bit to come, awake. Because sleep makes you miss things.

Using:

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

      

to listen to the PIN change and execute my_callaback

when it does. You can also wait for the front to increase with GPIO.RISING

or fall through GPIO.FALLING

.

For your example, here's how to start, not tested and nothing:

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 will probably not be enough as you cannot detect bits that do not change state. To deal with this, you have quite a few options, and I will only focus on the two simplest ones:

Control signal

You can use another PIN-code as a control signal and use it to start reading on the receiver. Thus, you start reading 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 recipient:

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 wired protocol

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

  • Each transmission consists of two bits: 1 and X
  • The data bit to be transmitted is X, while the first bit is always 1 and serves as a trigger for the receiver.
  • The X bit is expected to be active 0.1 to 0.9 seconds after the first rising edge of the bit.

It can be tricky, but it really isn't. All you have to do is start a reading on the leading edge and read the data somewhere between 0.1 and 0.9 seconds after that. Let's do this for 0.5 seconds to make sure we're 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 recipient:

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)

      

+4


source







All Articles