-1

i have the below code

import can

def abcd():
    bus = can.interface.Bus(channel= '1', bustype='vector',app_name = 'python-can')
    MSG = bus.recv(0.5)
    while MSG is not None:
            MSG = bus.recv(1)
    return MSG

if __name__ == '__main__':
    abcd()

and i want to return MSG every time how can i do ? can some one help me?

  • Can you try to describe the behavior you want? I assume that the `bus.recv()` method returns the currently available data (one or more bytes). Do you want a result as soon as it is available, or after a certain amount of silence on the bus? And do you want all data (concatenated) or just the last byte? I think there are multiple problems with your code, but I need more information to provide a good answer. – wovano Apr 27 '19 at 13:50

3 Answers3

0

You probably want to consider turning your function into a generator, using the yield keyword instead of return. In this way, ending your cycle with yield MSG, your function will generate a sequence of messages, one per iteration in the cycle.

When your generator ends, thus MSG is None, a StopIteration exception will be raised, making the for loop terminate as expected.

Concluding, you can structure your code as follows:

def callee():
    while ...:
        elem = ...
        yield elem

def caller():
    for elem in callee():
        ...
Elia Geretto
  • 387
  • 4
  • 10
0

As mentioned by @Elia Geretto you may need to convert it into generator function.Let me know will this changes help.

import can

def abcd():
    bus = can.interface.Bus(channel= '1', bustype='vector',app_name = 'python-can')
    MSG = bus.recv(0.5)
    while MSG is not None:
        MSG = bus.recv(1)
        yield MSG

if __name__ == '__main__':
    for op in abcd():
        print(op)  # or you can use next() as well.
Preetham
  • 577
  • 5
  • 13
0

I'm not completely sure what you want, but I think one of the problems is that the bus object is created every time. You might try the following code. I cannot test it myself since I don't have a CAN bus available. I'm also not sure what the method should return. If you can improve the question, I can improve the answer too :-)

import can

def read_from_can(bus):
    msg = bus.recv(0.5)
    while msg is not None:
        msg = bus.recv(1)
    return msg


def main():
    # create bus interface only once
    bus = can.interface.Bus(channel='1', bustype='vector', app_name='python-can')
    # then read (for example) 10 times from bus
    for i in range(10):
        result = read_from_can(bus)
        print(result)


if __name__ == '__main__':
    main()  # Tip: avoid putting your code here; use a method instead
wovano
  • 4,543
  • 5
  • 22
  • 49