4

I need to connect a serial device to gpio pin of a raspberry pi. My UART port is already used. For that, I need a simple code which can convert any gpio like Tx and Rx pin. I wrote a code but it could not receive data properly at higher baudrate.

My simple code of myuart is:

import RPi.GPIO as GPIO
import time,threading

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

baudrate = OneBitDelay = timeout = Tx = Rx = timeout_exit = False

def begin(tx=2,rx=3,Baudrate=9600,Timeout=float('inf')):
    global Tx,Rx,baudrate,OneBitDelay,timeout
    Tx = tx
    Rx = rx
    baudtate = Baudrate
    timeout = Timeout
    GPIO.setup(Tx, GPIO.OUT, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(Rx, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    OneBitDelay = 1/baudrate



def setBaudrate(BaudRate):
    global Baudrate,OneBitDelay
    Baudrate = BaudRate
    OneBitDelay = 1/Baudrate

def mytimer():
    global timeout_exit
    timeout_exit = True

def read(byte = 0):
    global Tx,Rx,OneBitDelay,timeout,timeout_exit
    data_array = ""
    if timeout != float('inf'):
        timer = threading.Timer(timeout, mytimer) 
        timer.start()
    while GPIO.input(Rx):

        if timeout_exit:
            timeout_exit = False
            return None
    data = readValue = ""
    if byte == 0:
        while True:
            time.sleep(OneBitDelay/baudrate)      ## I think synchronization problem arries due to this delay
            for count in range(0,8):
                readValue = readValue + str(GPIO.input(Rx))
                time.sleep(OneBitDelay)
            if readValue != "11111111":
                print("Received binary ",readValue)
                data = data + chr(int(readValue, 2))
                readValue = ""
            else:
                return data
    else:
        for r in range(0,int(byte/8)):
            for count in range(0,8):
                readValue = readValue + str(GPIO.input(Rx))
                time.sleep(OneBitDelay)
            data = data + chr(int(readValue, 2))
            readValue = ""
        return(data)
def write(data):
    global OneBitDelay
    if type(data) == int:
        data = str(data)
    data = getbinarystring(data)
    dataTemp =""

    for r in range(0,data.count(" ")+1):
        dataTemp = dataTemp + data.split()[r].zfill(8)
    for sendBit in range(0,len(dataTemp)):
        GPIO.output(Tx, int(dataTemp[sendBit]))
        time.sleep(OneBitDelay)
    GPIO.output(Tx, True)
    time.sleep(.005)   ## I think synchronization problem aeries due to this delay

def getbinarystring(data):
    return ' '.join(format(ord(x), 'b') for x in data)

Then I wrote a simple read.py and write.py code to transmit and receive data. but I am not getting whatever I send. also I am getting different data at different time. at lower baudrate this code works but at higher baudrate it's not working.

what are the mistakes I am making?? please help to improve synchronization.

for any kind of help thanks in advance.

write.py

import myuart,time
myuart.begin(tx=4,rx =17,Baudrate = 9600)
while True:
    myuart.write("hello")
    time.sleep(1)

read.py

import myuart,time
myuart.begin(tx=4,rx =17,Baudrate = 9600)
while True:
    print myuart.read()
Akash Nil
  • 693
  • 10
  • 26
  • My first suspicion is that a raspberry pi will not be fast enough for this, but I'm open to being proved wrong here. Have you looked at the tx signal on an oscilloscope to check that it is transmitting in the right format? – quamrana Apr 29 '19 at 08:31
  • Can you explain your synchronization scheme here? Also, try with a much lower baud rate to begin with; right now you're expecting your code to be able to reliably do `time.sleep(0.000104...)`. – AKX Apr 29 '19 at 08:35
  • @AKX: It looks like there is a start bit and data bits, but a fixed 0.005S stop bit. – quamrana Apr 29 '19 at 08:52
  • I used time.sleep(0.000104). result is same. @AKX – Akash Nil Apr 29 '19 at 08:57
  • you are right sir, does it need a change? I think the problem is in delay. I don't have sufficient knowledge about this delay calculation. did not get any library to serve my purpose. @quamrana – Akash Nil Apr 29 '19 at 09:00
  • 1
    @AkashNil Try a much lower baud rate, i.e. `baudrate = 50` for instance (which would be `time.sleep(0.02)`, or even lower – AKX Apr 29 '19 at 09:13
  • after a minor change and using of time.sleep(0.02) is working. I want to go to higher baudrates. what is the proper delay calculation formula? thank you.@AKX – Akash Nil Apr 29 '19 at 10:14

0 Answers0