In uart4Sender function, get the data from q1.get(), the data[0] is Can Id, data[4] is Can bus data. If recieve two Frame, for example :first ID is: 0x18ff0719, the data is: 0x30 ,0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38.The second Id is: 0x18ff0720, the data is: 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,0x46, 0x47. when received first frame, print('uid:', index),is right. print("udata:",da), is 18ff0719's data.But when run to second print, the string content is second fram's data, is: 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,0x46, 0x47, it belongs to second frame data.what happend, how slove this issue.Thanks!
@micropython.native
def encode(self, data):
index = int(data[0])
da = data[4]
if index == 0x18ff0719:
print('uid:',index) #first print
print('udata:',da)
string = str(index) + ',' + str(len(da)) + ','
temp =','.join([str(i) for i in (list(da))])
string = string + temp
string = '<' + string[0: ] + '>' + '\n'
string = 'can' + string
if index == 0x18ff0719:
print(string) #second print
return string
Code: Select all
import gc # garbage collect
import micropython
import machine
from pyb import Pin, UART, ADC, ADCAll
import utime
from p import queue # queue class
from p import switch # switch class
from p import delay_ms
import uasyncio
from uasyncio import Lock
def timed_function(f, *args, **kwargs):
myname = str(f).split(' ')[1]
def new_func(*args, **kwargs):
t = utime.ticks_us()
result = f(*args, **kwargs)
delta = utime.ticks_diff(utime.ticks_us(), t)
print('Function {} Time = {:6.3f}ms'.format(myname, delta/1000))
return result
return new_func
micropython.alloc_emergency_exception_buf(100)
class device:
""" IO define for PMU """
def __init__(self, debug = False, Initvalue = 0):
self.debug = debug
self.pmicenable = Pin('B1', Pin.OUT_PP)
self.pmicpoweron = Pin('C2', Pin.OUT_PP)
self.externaldevice = Pin('B0', Pin.OUT_PP)
self.stby = Pin('C5', Pin.OUT_PP)
self.ahdfunction = Pin('A8', Pin.OUT_PP)
self.pmicenable.value(Initvalue)
self.pmicpoweron.value(Initvalue)
self.externaldevice.value(Initvalue)
self.stby.value(Initvalue)
self.ahdfunction(Initvalue)
async def io_on(self, val, timeout):
self.pmicenable.value(val) # PB1 Port
await uasyncio.sleep_ms(100)
self.externaldevice.value(val) # PB0
await uasyncio.sleep_ms(50)
self.stby.value(val) # PC5
await uasyncio.sleep_ms(timeout)
"""
self.pmicpoweron.value(val) # PC2 Port
await uasyncio.sleep_ms(timeout)
"""
self.ahdfunction.value(val) # PA8
await uasyncio.sleep_ms(timeout)
self.debug and print("Io On ok!\r\n")
async def io_off(self, val, timeout):
""" Power Off Sequence """
self.pmicpoweron.value(val)
await uasyncio.sleep_ms(timeout)
self.ahdfunction.value(val)
await uasyncio.sleep_ms(timeout)
self.stby.value(val)
await uasyncio.sleep_ms(timeout)
self.debug and print("Io Off ok!\r\n")
class adc:
"""
Read the DC voltage to power on Android.
when the adc voltage more than 0.87v(DC value is 9v) and
less than 2.80(DC value is 32v) power up the Android pmu.
"""
def __init__(self, pin = ADC('C0'), filtercount = 10, debug = False):
self.adcall = ADCAll(12, 0x70000) # 12 bit resolution, internal channel
self.vref = self.adcall.read_core_vref( ) # vref voltage
self.temp = self.adcall.read_core_temp( ) # core temp
self.pin = pin
self.filtercount = filtercount # filter count
self.debug = debug
self.value = self.pin.read()
self.samples = [] # store adc value
self.mean = 0
async def read(self):
'''read adc value '''
self.v = self.value
samples = []
for _ in range(self.filtercount):
samples.append(self.value)
await uasyncio.sleep_ms(10)
samples = sorted(samples)
self.mean = (samples[int(len(samples)/2)]) * 3.24 / 4095.00 # filter median_mean
self.debug and print("adc value is:%f", self.mean)
return self.mean
class canbus:
""" can bus driver """
def __init__(self, id = 0x01, channel = 0x01, bitrate = 250, verbose =False):
from pyb import CAN
self.verbose = verbose
self._channel = channel
self.fifo = channel - 1
self.can = CAN(self._channel, extframe=True, mode=CAN.NORMAL, prescaler=(2000 // bitrate), sjw=1, bs1=14, bs2=6)
self.can.setfilter(0, CAN.MASK16, self.fifo, (0, 0, 0, 0))
self._evt = uasyncio.Event()
self.buf = bytearray(8)
self._null_sink =[0, 0, 0, memoryview(self.buf), self.buf]
self._rx_buf =[0, 0, 0, memoryview(self.buf), self.buf]
self.can.rxcallback(self.fifo, self._rxcallback) # call back
def _rxcallback(self, bus, reason):
while self.can.any(self.fifo):
bus.recv(self.fifo, self._rx_buf)
self.verbose and print(self._rx_buf)
self._evt.set()
def cb_sched(self):
self._evt.set()
def flush_fifo(self):
while self.can.any(self.fifo):
self.can.recv(self.fifo, list=self._null_sink)
def read(self): # read can data from buffer
if self._evt. is_set():
self.res = self._rx_buf
self._evt.clear()
else:
self.res =''
self._evt.clear()
return (self.res)
def write(self, data, index):
try:
self.can.send(data, index, timeout=10)
except:
return False
return True
def state(self):
return self.can.state()
def restart(self):
self.can.restart()
@micropython.native
def encode(self, data):
index = int(data[0])
da = data[4]
[color=#FF0000] if index == 0x18ff0719:
print('uid:',index)
print('udata:',da)[/color]
string = str(index) + ',' + str(len(da)) + ','
temp =','.join([str(i) for i in (list(da))])
string = string + temp
string = '<' + string[0: ] + '>' + '\n'
string = 'can' + string
[color=#FF0000] if index == 0x18ff0719:
print(string)[/color]
return string
class App:
def __init__(self, verbose= False):
self.verbose = verbose
self.can1 = canbus(id = 0x01, channel = 0x01, bitrate = 250, verbose = False)
self.can2 = canbus(id = 0x02, channel = 0x02, bitrate = 250, verbose = False)
self.d = device()
self.v = adc()
self.sw = switch_ext()
self.q1 = queue.Queue(maxsize = 8192)
self.q2 = queue.Queue(maxsize = 8192)
self.q3 = queue.Queue(maxsize = 512) # forward to uart
self.q4 = queue.Queue(maxsize = 512) # forward to uart
self._rx_buff = None
self._ev = uasyncio.Event()
self.uart4 = UART(4, 1500000)
self.uart5 = UART(5, 1500000)
self.swriter4 = uasyncio.StreamWriter(self.uart4, {})
self.sreader4 = uasyncio.StreamReader(self.uart4, {})
self.swriter5 = uasyncio.StreamWriter(self.uart5, {})
self.sreader5 = uasyncio.StreamReader(self.uart5, {})
async def start(self):
self.verbose and print('App Start!\r\n')
uasyncio.create_task(self.can1Receiver())
uasyncio.create_task(self.can2Receiver())
uasyncio.create_task(self.uart4Sender())
uasyncio.create_task(self.uart4Receiver())
uasyncio.create_task(self.can1Sender())
uasyncio.create_task(self.uart5Receiver())
uasyncio.create_task(self.can2Sender())
uasyncio.create_task(self.power())
uasyncio.create_task(self.mem_manage())
while True:
await uasyncio.sleep(0.1)
async def can1Receiver(self):
'canbus(1) data receive'
while True:
data =self.can1.read()
if data is not '':
await self.q1.put(data)
await uasyncio.sleep_ms(100)
async def can1Sender(self):
""" Canbus Sender """
while True:
if self.can1.state() == 4:
self.can1.restart()
await uasyncio.sleep_ms(1)
msg = ''
if not self.q4.empty():
data = await self.q4.get()
id_ = int.from_bytes(data[:4], 'big')
msg = (data[4:13])
if (len(msg)) == 8:
self.can1.write(msg,id_)
await uasyncio.sleep_ms(20)
async def uart4Receiver(self):
'Receive data from Android and transfer to Can Bus'
'protocol1: 0xa5 + 4bytes(address1) + 8bytes(can data) + 1bytes(checksum) + 0x5a + \n'
while True:
sum =0
res = await self.sreader4.readline()
if len(res) == 16: # can data forward
if res[0] == 0xa5 and res[len(res)-2] == 0x5a:
for i in range(1,13):
sum = (sum + int(res[i]))&0xFF # checksum one byte
#print(sum)
if sum == int(res[len(res)- 3]):
await self.q4.put(res[1:13])
await uasyncio.sleep_ms(20)
async def uart4Sender(self):
'Forward canbus(1) to UART(4),before the data send,must be encode them '
string = ''
while True:
while not self.q1.empty():
data = await self.q1.get()
string = self.can1.encode(data)
self.swriter4.write((string))
await self.swriter4.drain()
await uasyncio.sleep_ms(0)
async def mem_manage(self): # garbage management
""" garbage collect """
while True:
await uasyncio.sleep_ms(1000) # delay 1000ms
gc.collect()
gc.threshold(gc.mem_free()//4 + gc.mem_alloc())
#self.verbose and print("mem", gc.mem_free())
app = None
async def main():
print(__version__)
gc.collect()
global app
app = App(verbose = False)
await app.start()
def run():
try:
gc.collect()
uasyncio.run(main())
except KeyboardInterrupt:
print('Interrupt')
finally:
uasyncio.new_event_loop()
print("run again.")
run()