1

I am trying to use joan's pigpio for python to try to write a command from a rpi3 GPIO pin to a peripheral device. the peripheral device uses UART and when it receives a data packet it will then perform the corresponding function.

example |-----dataBuffer----| start devID size packetCount index futureByte | highByte LowByte | 255 1 2 1 1 0 | 3 195 | |00000011 11000011|

start: beginning of packet
devID: id of device
size: # of command bytes, only one command at a time and each command is 2 bytes so this number is always 2
packetCount: total # of packets in the transmission.(only 1 packet at a time)
index: place of this packet within set of packets
futureByte: not used, keeps the data packet even
dataBuffer: 0 to 16 byte buffer. bc only 1 command is sent at a time, the buffer will only contain 2 bytes(the high byte and the low byte)

peripheral device byte format:
start bit: yes
bit order: 0...7
parity bit: no
baud rate: 9600

I have not yet reached the point where I am actually sending commands to the peripheral. For now I just trying to write on a GPIO using pi.wave_send_once() and verify that this is working correctly using joans piscope and my bench oscope. Here is my script:

`  
import sys
import difflib
import pigpio
import time
import os
from os import system

system('sudo pigpiod')

# GPIO pin constants
BAUD = 9600    # 9600
TX = 22        # NOT builtin gpio 14

#create instance of pigpio class
pi = pigpio.pi()
if not pi.connected:
    os.system("sudo pigpiod")
    time.sleep(1)
    pi = pigpio.pi()

pi.set_mode(TX, pigpio.OUTPUT) # set GPIO 14 as an output

def send_command(packet):
        pi.wave_clear()
        pi.wave_add_serial(TX, BAUD, packet, bb_bits=8) #bb_bits=16
        wid = pi.wave_create()
        pi.wave_send_once(wid)   # transmit serial data
        while pi.wave_tx_busy(): # wait until all data sent
            pass
        print('The packet\n{}\n was sent!'.format(packet))
        pi.wave_delete(wid)

packet = b'3'
#packet = b'00000011'
#packet = '00000011'
send_command(packet)

`

Here is the output of the wave_get functions:

control blocks: 14 max cbs: 25016 microseconds: 1146 max micros: 1800000000 pulses: 7 max pulses: 12000

Here is a screenshot of piscope:

piscope screenshot

As you can see something is wrong. First of all the timing is wrong, at 9600baud each pulse should be 104usec.

  1. Does anyone have any ideas how to fix the timing problem? I have tried fixing with the core_freq=250 and dtoverlay workarounds I read about, but this did not solve the problem.
  2. will this method of sending pigpio waves still work for me once I start sending the larger complete packets(64bits)?
  3. the pigpio library has a function for filtering glitches/noise. Should i be using these? If so i did not really understand how to use them please explain or point to tutorial/example.

script ot send command `

# GPIO pin constants     
BAUD = 9600    # 9600
TX = 5       

#create instance of pigpio class
pi = pigpio.pi()
if not pi.connected:
    os.system("sudo pigpiod")
    time.sleep(1)
    pi = pigpio.pi()

#set mode of tx pin
pi.set_mode(TX, pigpio.OUTPUT) # set GPIO 14 as an output

# fatal exceptions off (so that closing an unopened gpio doesn't error)
pigpio.exceptions = False

#pi.bb_serial_read_close(RX)
pi.serial_close(TX)

# fatal exceptions on
pigpio.exceptions = True


def wave_dbg(msg):
        cbs = pi.wave_get_cbs()
        max_cbs = pi.wave_get_max_cbs()
        micros = pi.wave_get_micros()
        max_micros = pi.wave_get_max_micros()
        pulses = pi.wave_get_pulses()
        max_pulses = pi.wave_get_max_pulses()
        print('-------------[DBG - wave]------------------------------')
        print('-------------[{}]-------------------'.format(msg))
        print('control blocks: {}    max cbs:    {}'.format(cbs,max_cbs))
        print('microseconds:   {}    max micros: 
{}'.format(micros,max_micros))
        print('pulses:         {}    max pulses: 
{}'.format(pulses,max_pulses))
        print('-------------------------------------------------------')

def send_command(packet):
        print('inside function:  {}'.format(type(packet)))
        print('inside function:  {}'.format(packet))
        #self.wave_dbg('before wave clear')
        pi.wave_clear()
        #self.wave_dbg('after wave clear')
        pi.wave_add_serial(TX, BAUD, packet, bb_bits = 32) #bb_bits=16
        #self.wave_dbg('after serial add')
        wid = pi.wave_create()
        #self.wave_dbg('after wave creation')
        pi.wave_send_once(wid)   # transmit serial data
        #self.wave_dbg('after wave sent')
        while pi.wave_tx_busy(): # wait until all data sent
            pass
        print('The packet\n{}\n was sent!'.format(packet))
        pi.wave_delete(wid)
        wave_dbg('end of function')

'''
commands returned from sniffer
r_eye_norm = bytearray(b'\xff\x01\x02\x01\x01\x00\x03\xc3')
r_eye_cons = bytearray(b'\xff\x01\x02\x01\x01\x00\x03\xc5')
r_eye_dila = bytearray(b'\xff\x01\x02\x01\x01\x00\x03\xc4')
br30 = bytearray(b'\xff\x01\x02\x01\x01\x00\x04d')
br_apnea = bytearray(b'\xff\x01\x02\x01\x01\x00\x04`')
br5 = bytearray(b'\xff\x01\x02\x01\x01\x00\x04a')
'''

r_eye_norm = bytearray(b'\x01\x02\x01\x01\x00\x03\xc3')
r_eye_cons = bytearray(b'\x01\x02\x01\x01\x00\x03\xc5')
r_eye_dila = bytearray(b'\x01\x02\x01\x01\x00\x03\xc4')
br30 = bytearray(b'\x01\x02\x01\x01\x00\x04d')
br_apnea = bytearray(b'\x01\x02\x01\x01\x00\x04`')
br5 = bytearray(b'\x01\x02\x01\x01\x00\x04a')

print(type(br30))
print(br30)
send_command(br30)
`

piscope screenshot

script for sniffer uart_sniffer.py '
import datetime as dt import time import pigpio

TX = 6 # pin 29

TX_data = []
try:
    pi = pigpio.pi() # connect to local host
    #pi.set_mode(RX, pigpio.INPUT)
    pi.set_mode(TX, pigpio.INPUT)

    pigpio.exceptions = False
    pi.bb_serial_read_close(TX)
    pigpio.exceptions = True

    #pi.bb_serial_read_open(RX, 9600, 8)
    pi.bb_serial_read_open(TX, 9600, 8)

    print('-----------------DATA SOFTWARE SERIAL------------------------')
    while True:
        (countTX, dataTX) = pi.bb_serial_read(TX)
        if countTX:
            print(dataTX)
            TX_data.append(dataTX)
            print('--------------------------------------------------')
        time.sleep(1)

except KeyboardInterrupt:
    with open('uart_read.txt', 'w') as f:
        for item in TX_data:
            f.write('%s\n' % item)

    pi.bb_serial_read_close(TX)
    pi.stop()
`

1 Answers1

1

This may be a misunderstanding of how traditional serial data is transmitted. If there is no level transition the line is not toggled. So if you send 0x00 there will be 8 bit times between a level change.

I changed packet to [0xaa, 0xaa, 0xaa] and got the following screen shot.

piscope

You can see that the bit time is 104µs.

Glitch filtering only applies to data being received by a GPIO.

joan
  • 71,852
  • 5
  • 76
  • 108