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:
As you can see something is wrong. First of all the timing is wrong, at 9600baud each pulse should be 104usec.
- 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.
- will this method of sending pigpio waves still work for me once I start sending the larger complete packets(64bits)?
- 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)
`
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()
`