0

I'm sending bits as LED blinks from one Pi Pico, and using another Pico to receive voltage from a photodiode and read the bits.

When sending/receiving from the same PiPico, it works accurately at 60us a bit. However, when sending from one pico and receiving from a second pico, I can only send/receive bits accurately at 0.1s a bit. If I move to sending/receiving at 0.01s, I start losing information. This leads me to believe my issue is with the clocks or sampling rates on the two pipicos, that they are slightly different.

Is there a way to synchronize two pipico clocks using Thonny/Micropython?

Code for Pico #1 sending blinks/bits:

    led=Pin(13,Pin.OUT)        #Led to blink
    SaqVoltage = machine.ADC(28)      #receive an input signal, when over a certain voltage, send the time using bits

    #Ommitted code here to grab first low voltage values from SaqVoltage signal and use to determine if there is a high voltage received, when high voltage is received, send "hi" in led bits
    #More omitted calibration code here for led/photodiode

    hi = "0110100001101001"
    while True:
        SaqVoltage_value = SaqVoltage.read_u16()*3.3 / 65536    #read input signal to see if high voltage is sent
        finalBitString = ""
       
        if SaqVoltage_value > saQCutOff: #high voltage found, send "hi" sequence
            finalBitString = #hi plus some start/stop sequences
            for i in range (0, len(finalBitString)): 
                if finalBitString[i]=="1":
                    led(1)  
                elif finalBitString[i]=="0":
                    led(0)
                utime.sleep(.01)
        

Code for Pico#2 receiving bits:

    SaqDiode = machine.ADC(28)   #read photodiode
    #ommitted code here to calibrate leds/photodiodes

    startSeqSaq = []
    wordBits=[]
    while True:
        utime.sleep(.01)   #sample diode every 0.01 seconds
        SaqDiode_value = SaqDiode.read_u16()*3.3 / 65536
        if (saqDiodeHi - saqCutOff <= SaqDiode_value):      #read saq diode and determine 1 or 0
            bit=1  
        elif (SaqDiode_value <= saqDiodeLo + saqCutOff):
            bit=0
        if len(startSeqSaq)==10:    #record last 10 received bits to check if start sequence
            startSeqSaq.pop(0)
            startSeqSaq.append(bit)
        elif len(startSeqSaq)<10:
            startSeqSaq.append(bit)

        if startSeqSaq == startSeq: #found start sequence, start reading bits
            while True:
                utime.sleep(.01)
                SaqDiode_value = SaqDiode.read_u16()*3.3 / 65536
                if (saqDiodeHi - saqCutOff <= SaqDiode_value):
                    bit=1
                    wordBits.append(bit)
                elif (SaqDiode_value < saqDiodeLo + saqCutOff):
                    bit=0
                    wordBits.append(bit)
            
                if len(wordBits)>10:   #check for stop sequence
                    last14=wordBits[-10:]
                else:
                    last14 = []
                if last14==endSeq:
                    char = frombits(wordBits[:-10])
                    wordBits=[]
                    print("Function Generator Reset Signal Time in ms from Start: ", char)
                    break
  
  • 1
    Please show us a [mre]. Probably you need to adapt one of the many serial protocols that exist, and your receiver code cannot synchronize. Anyway, such transmissions shall work without synchronization on the MHz clock. – the busybee Jul 29 '22 at 16:42
  • I think thats on the right track, something like UART or SPI? – gradStudent Jul 29 '22 at 17:57
  • 1
    From your source we see that your receiver samples only once per bit, and it is not "centered" to the bit period. Please do some research how serial protocols work. For example, UARTs commonly sample 16 times per bit. You cannot use SPI because you have no clock "channel". – the busybee Jul 29 '22 at 19:10
  • You might want to learn how [manchester code](https://en.wikipedia.org/wiki/Manchester_code) works. Imagine that this coding was used in the 80s of the last century to record a home computer's data serially on a standard audio cassette tape. The same tape was later read by potentially another home computer with a completely different system clock replayed on another recorder with slightly different (some percent) tape speed, and with great success. – the busybee Jul 29 '22 at 19:13
  • I tried sampling many times per bit, and centering my sampling, and still was getting lots of errors. I am completely new to microcontrollers and need to look into how UART works some more. Thanks for your help! – gradStudent Jul 30 '22 at 00:21
  • you have to oversample. if you use biphase-l (manchster) then that halves your bandwidth but insures that there is a state change every one or two half bit cells. that may or may not help but since infra red works this way, granted it may be a slower bit rate depending on the encoding, and mcus signifcantly less powerful than this one can easily decode those with a reverse bit bang, you should be able to as well. what does the scope show for the signal on the receiver led? are you using IR leds and a carrier frequency (40khz give or take)? – old_timer Jul 30 '22 at 14:39
  • you could just feed uart through ir/irda pairs – old_timer Jul 30 '22 at 14:40
  • @old_timer I think that is the way to go, to just use uart and connect it to my LEDs and throw out my old method for now. They aren't ir but are around 610nm and hopefully will still do the trick – gradStudent Jul 31 '22 at 01:05

0 Answers0