In the Arduino IDE there's a very nice little library called NewSoftSerial, which allows to establish a serial link on any digital pin of your Arduino board. Very neat stuff indeed and often used for 433MHz RF links.
Since this didn't exist on VIPER (yet), I've ported the "receive serial" part, using interrupt routines, to it (see below).
Now, I'm sure that there's better ways of coding this, but for the moment I'm quite happy with it.
################################################################################
# SoftRx
#
# Created: 2015-10-27 08:46:15.793526
#
################################################################################
#DO THESE THINGS IN THE MAIN PROGRAM
# import the streams module for USB serial port.
import streams
# open the default serial port
streams.serial()
#import necessary libraries
import timers
import pwm #needed to enable hwtimers to run (?)
import hwtimers
global RxBuffer
global RxByteDec
## end of things to do in main program
#########
#set up the SoftRx routine
#########
def SoftRx_setup(_rxpin, _baudrate, _timeUnit): # set _timeUnit=1 for microseconds, default is milliseconds
global last_Rx_time
global Rx_time
global Rxpin
global duration1bitMICROS
global duration1bitMILLIS
global RxBuffer
global TimeUnit
TimeUnit = _timeUnit
Rxpin = _rxpin
duration1bit = 1/_baudrate #duration of HIGH/LOW for 1 transmitted bit in seconds
#
duration1bitMILLIS = int(duration1bit*(10**3))
duration1bitMICROS = int(duration1bit*(10**6)) # 1s = 10^6 microseconds, rounded to next integer
RxBuffer = []
last_Rx_time = 0 #used for interrupt settling
Rx_time = timers.now() #used for interrupt settling, time in milliseconds
## debugging
# print("debugging")
# print(duration1bitMILLIS)
# print(3/2*duration1bitMILLIS)
# print(int(3/2*duration1bitMILLIS))
#########
# receive data on the software serial port
#########
def receive8bits():
global last_Rx_time
global Rx_time
global Rxpin
global duration1bitMICROS
global duration1bitMILLIS
global RxBuffer
Rx_time = timers.now()
time_test = Rx_time - last_Rx_time #time difference between last 2 interrupts, in milliseconds
if time_test > int(10*duration1bitMILLIS): #interrupt fires at each HIGH->LOW, hence need to ignore any interrupt during reception of 1 byte = 1 start bit + 8 bits+1 stopbit
if TimeUnit==1:
hwtimers.sleep_micros(int(duration1bitMICROS/2)) # read at bit centres
else:
sleep(int(duration1bitMILLIS/2)) #only works for baudrates <1000
#sleep(1)
for i in range(9): #now read 9 bits (start+8) at their respective centres
tmp = digitalRead(Rxpin)
if len(RxBuffer)>255: #don't store more than 32 bytes (=256 bits) in buffer
RxBuffer[0] = [] #remove oldest bit
RxBuffer.append(tmp)
#print(tmp) #use for debugging
if TimeUnit==1:
hwtimers.sleep_micros(duration1bitMICROS) # start bit: LOW for duration=1/baudrate, then read at bit centres
else:
sleep(duration1bitMILLIS) #only works for baudrates <1000
#sleep(2)
last_Rx_time = Rx_time
RxBuffer[0:1] = [] #remove start bit
return RxBuffer
else:
return
#########
# start up the serial port
#########
def SoftRx_start():
onPinFall(Rxpin,receive8bits) #start listening on the SoftSerial port
#########
# convert RxBuffer to decimal
#########
def SoftRx_Bin2Dec(_BinList):
tmpDec = 0
for i in range(8):
tmpDec += _BinList[i]*(2**i)
return tmpDec
##the following is just to test the above...
SoftRx_setup(D0,500,1) # set up all the necessary bits
SoftRx_start() #start listening on the SoftSerial port
while True:
sleep(1000)
if len(RxBuffer)>0:
RxData = RxBuffer[0:8]
RxBuffer[0:8] = []
RxByteDec = SoftRx_Bin2Dec(RxData)
print(RxData)
print(RxByteDec)
print("---")
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.