CANbus project question

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
ilium007
Posts: 37
Joined: Tue Feb 16, 2021 10:29 am

CANbus project question

Post by ilium007 » Tue Apr 05, 2022 3:58 am

I am trying to get my CANbus project going and look at the Peter Hinch pushbutton asyncio class. I have two Adafruit STMF405's with CANbus transceivers connected and communicating.

UC1 is running the pushbutton class with a button and sending the CANbus msg:

Code: Select all

from machine import Pin
import uasyncio as asyncio
from primitives import Pushbutton

from pyb import CAN

can1 = CAN(1, CAN.NORMAL, extframe=True)

buf = bytearray(1)
buf[0] = 0

msg_id = 123

def printmsg(msg):
    buf[0] += 1
    print('msg: {} count: {}'.format(msg,buf[0]))
    can1.send(msg, msg_id)

async def main():
    pin = Pin(Pin.cpu.C4, Pin.IN, Pin.PULL_UP)
    pb = Pushbutton(pin)
    pb.press_func(printmsg, ('push', ))
    #pb.long_func(printmsg, ('long',))
    while True:
        await asyncio.sleep(60)       #keep the uasyncio loop alive

try:
    asyncio.run(main())
except (KeyboardInterrupt, Exception) as e:
    print('Exception {} {}\n'.format(type(e).__name__, e))
#finally:
#    ret = asyncio.new_event_loop()  # Clear retained uasyncio state
UC2 is receiving and displaying:

Code: Select all

import math, time
import uasyncio as asyncio
from pyb import Timer, Pin
from pyb import CAN

#lookup table for LED sin values
breath_lookup = []

def breath(x):
    return (0.5 + (0.5 * (math.sin(math.pi * x - (0.5 * math.pi)))))

for i in range(101):
    breath_lookup.append(breath(i/50)*100)

can1 = CAN(1, CAN.NORMAL, extframe=True)
can1.setfilter(0,CAN.MASK32,0,(0,0))

buf = bytearray(8)
lst = [0, 0, 0, memoryview(buf)]

buf1 = bytearray(1)
buf1[0] = 0

def cb(bus, reason):
    if reason == 0:
        #print('pending')
        bus.recv(0, lst)
        buf1[0] += 1
        #print('msg: {} count: {}'.format(bytes(lst[3]), buf1[0]))
    if reason == 1:
        print('full')
    if reason == 2:
        print('overflow')

can1.rxcallback(0, cb)

tim = Timer(3, freq=1000)
ch1 = tim.channel(1, Timer.PWM, pin=Pin.cpu.C6, pulse_width=0)

async def breathe():
    while True:
        for i in range(len(breath_lookup)):
            ch1.pulse_width_percent(breath_lookup[i])
            await asyncio.sleep_ms(30)
        await asyncio.sleep_ms(400)

async def main():
    count_old = 0
    asyncio.create_task(breathe())

    while True:
        if buf1[0] != count_old:
            print('msg: {} count: {}'.format(bytes(lst[3]), buf1[0]))
            count_old = buf1[0]
        await asyncio.sleep_ms(0)       #keep the uasyncio loop alive

try:
    asyncio.run(main())
except (KeyboardInterrupt, Exception) as e:
    print('Exception {} {}\n'.format(type(e).__name__, e))
#finally:
#    ret = asyncio.new_event_loop()  # Clear retained uasyncio state
I noticed that occasionally UC2 can receive a string of 1 - 4 extra CANbus messages relating to button presses. The pushbutton class should apply a 50ms debounce so I don't see how these additional messages are being sent. As far as I can tell the only way it can occur is if the pushbutton instance sends the additional messages via the callback.

The below output shows an additional message (count: 251) that does not relate to a physical button press. The only way I can see that message being generated is by the pushbutton class callback:

Code: Select all

UC1	                    UC2
	
msg: push count: 230	    msg: b'push' count: 230
msg: push count: 231	    msg: b'push' count: 231
msg: push count: 232	    msg: b'push' count: 232
msg: push count: 233	    msg: b'push' count: 233
msg: push count: 234	    msg: b'push' count: 234
msg: push count: 235	    msg: b'push' count: 235
msg: push count: 236	    msg: b'push' count: 236
msg: push count: 237	    msg: b'push' count: 237
msg: push count: 238	    msg: b'push' count: 238
msg: push count: 239	    msg: b'push' count: 239
msg: push count: 240	    msg: b'push' count: 240
msg: push count: 241	    msg: b'push' count: 241
msg: push count: 242	    msg: b'push' count: 242
msg: push count: 243	    msg: b'push' count: 243
msg: push count: 244	    msg: b'push' count: 244
msg: push count: 245	    msg: b'push' count: 245
msg: push count: 246	    msg: b'push' count: 246
msg: push count: 247	    msg: b'push' count: 247
msg: push count: 248	    msg: b'push' count: 248
msg: push count: 249	    msg: b'push' count: 249
msg: push count: 250	    msg: b'push' count: 250
	                    msg: b'push' count: 251
The other thing I am trying to understand is this error when i try to execute this:

Code: Select all

print('msg: {} count: {}'.format(bytes(lst[3]), buf1[0]))
from within the cb callback function:

Code: Select all

def cb(bus, reason):
    if reason == 0:
        #print('pending')
        bus.recv(0, lst)
        buf1[0] += 1
        print('msg: {} count: {}'.format(bytes(lst[3]), buf1[0]))
    if reason == 1:
        print('full')
    if reason == 2:
        print('overflow')
Error:

Code: Select all

>>>
MPY: sync filesystems
MPY: soft reboot
uncaught exception in CAN(1) rx interrupt handler
MemoryError:
If I run the same line:

Code: Select all

print('msg: {} count: {}'.format(bytes(lst[3]), buf1[0]))

outside of the callback in async def main() it works fine.

ilium007
Posts: 37
Joined: Tue Feb 16, 2021 10:29 am

Re: CANbus project question

Post by ilium007 » Tue Apr 05, 2022 9:46 am

The project has been sitting on my desk running for the past 7 hours and I just pressed the button 5 times and it registered an additional 11 CANbus messages on the second microcontroller.
Screen Shot 2022-04-05 at 7.45.09 pm.png
Screen Shot 2022-04-05 at 7.45.09 pm.png (262.02 KiB) Viewed 1656 times

ilium007
Posts: 37
Joined: Tue Feb 16, 2021 10:29 am

Re: CANbus project question

Post by ilium007 » Tue Apr 05, 2022 10:34 am

I noticed that the SN65HVD230 3.3 V CAN Transceiver breakout board that I'm prototyping with did not have bypass capacitors on the 3.3v pin. I placed a 100 nF cap on this pin and it seems to be working.

Post Reply