help with E32 program (simple)

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
NateOdem
Posts: 13
Joined: Sun May 08, 2022 5:18 pm

help with E32 program (simple)

Post by NateOdem » Sun May 08, 2022 5:26 pm

Ok, I have been beating my head against a wall for a while trying to figure out how to get this working! I have a project I am working on, that I need to send a command string wirelessly, receive and parse on another board, to execute the commands. I am using (2) Pico boards with Ebytes E32 LoRa modules. The Tx side SEEMS to be fine, but for the life of me, I can't figure out how to cleanly receive that commands?
Anybody out there able to help?


Here is the TX side...

Code: Select all

from machine import Pin, UART, SPI,ADC
from time import sleep
#machine.freq(250000000)
direct=0
speed=0

uart = UART(1,115200, tx=Pin(4), rx=Pin(5))
led=Pin(25,Pin.OUT)
joy_y = ADC(Pin(27))
joy_x = ADC(Pin(26))
butA=Pin(15,Pin.IN, Pin.PULL_UP)
butB=Pin(14,Pin.IN, Pin.PULL_UP)
butC=Pin(13,Pin.IN, Pin.PULL_UP)
butD=Pin(12,Pin.IN, Pin.PULL_UP)
swA=Pin(11,Pin.IN, Pin.PULL_UP)
swB=Pin(10,Pin.IN, Pin.PULL_UP)
swC=Pin(9,Pin.IN, Pin.PULL_UP)
swD=Pin(8,Pin.IN, Pin.PULL_UP)

def map(x, in_min, in_max, out_min, out_max):
    return int((x-in_min)*(out_max-out_min)/(in_max-in_min))

while True:
    y=(joy_y.read_u16())
    x=(joy_x.read_u16())
    y_val=map(y,288,65535,0,255)
    x_val=map(x,288,65535,0,255)
    if(y_val>138 and x_val<138 and x_val>118):#Forward
        direct=1
        speed=map(y_val,138,255,0,255)
    elif(y_val<118 and x_val>118 and x_val<138):#Reverse
        direct=5
        speed=map(y_val,118,0,0,255)
    elif(y_val>138 and x_val<118):#Forward Left
        direct=8
        speed=map(y_val,138,255,0,255)
    elif(y_val>138 and x_val>138):#Forward Right
        direct=2
        speed=map(y_val,138,255,0,255)
    elif(y_val<118 and x_val<118):#Reverse Left
        direct=6
        speed=map(y_val,118,0,0,255)
    elif(y_val<118 and x_val>138):#Reverse Right
        direct=4
        speed=map(y_val,118,0,0,255)
    elif(x_val<118 and y_val>118 and y_val<138):#Left
        direct=7
        speed=map(x_val,118,0,0,255)
    elif(x_val>138 and y_val>118 and y_val<138):#Right
        direct=3
        speed=map(x_val,138,255,0,255)
    else:#Stop
        direct=0
        speed=0
    
    
    Ba=butA.value()
    Bb=butB.value()
    Bc=butC.value()
    Bd=butD.value()
    Sa=swA.value()
    Sb=swB.value()
    Sc=swC.value()
    Sd=swD.value()
    potA=255
    potB=103
    joyA=217
    joyB=163
    lead=0
    instruction=(lead,direct,speed,Ba,Bb,Bc,Bd,Sa,Sb,Sc,Sd,potA,potB,joyA,joyB)
    command=str(instruction)
    
    print(command)
    uart.write(command)
    uart.sendbreak()
    led.value(1)
    sleep(.1)
    led.value(0)
    sleep(.1)

and the RX side for reference...

Code: Select all

from machine import Pin, UART
from time import sleep


radio=UART(1,115200, tx=Pin(4), rx=Pin(5))
global speed
global direction
global butA
global butB
global butC
global swA
global swB
global swC
global swD
global potA
global potB
global potC
global potD

while True:
    if radio.any():
        info=str(radio.readline())
        print(info)
        (list(info))
        command= (info.split(','))
        print(command)
I am still new somewhat new to Micropython (comming from Arduino), so be easy on me. I would appreciate any help.

Thanks,

tepalia02
Posts: 99
Joined: Mon Mar 21, 2022 5:13 am

Re: help with E32 program (simple)

Post by tepalia02 » Mon May 09, 2022 3:09 pm

I think there will be more responses if you share the output that you're getting on the receiver's side.

NateOdem
Posts: 13
Joined: Sun May 08, 2022 5:18 pm

Re: help with E32 program (simple)

Post by NateOdem » Mon May 09, 2022 5:49 pm

Ah, I forgot to add that. I suppose it would help. I'll add it when I get to the house tonight. It reads, but can't seem to differentiate where the line ends (despite having the .sendbreak() in the TX side), it just all runs together.

I'll add the output tonight....

NateOdem
Posts: 13
Joined: Sun May 08, 2022 5:18 pm

Re: help with E32 program (simple)

Post by NateOdem » Tue May 10, 2022 12:48 am

Ok, Below is what is being spit out on the receiver side...

Code: Select all

["b'\\x000", ' 0', ' 0', ' 1', ' 1', ' 1', ' 1', " 1'"]
b', 1, 1, 1, 255, 103, 13360, 12896)'
["b'", ' 1', ' 1', ' 1', ' 255', ' 103', ' 13360', " 12896)'"]
b'('
["b'('"]
b'\x000, 0, 0, 1, 1, 1, 1, 1'
["b'\\x000", ' 0', ' 0', ' 1', ' 1', ' 1', ' 1', " 1'"]
b', 1, 1, 1, 255, 103, 13360, 12912)'
["b'", ' 1', ' 1', ' 1', ' 255', ' 103', ' 13360', " 12912)'"]
b'('
["b'('"]
b'\x000, 0, 0, 1, 1, 1, 1, 1'
["b'\\x000", ' 0', ' 0', ' 1', ' 1', ' 1', ' 1', " 1'"]
b', 1, 1, 1, 255, 103, 13360, 12912)'
["b'", ' 1', ' 1', ' 1', ' 255', ' 103', ' 13360', " 12912)'"]
b'('
["b'('"]
b'\x000, 0, 0, 1, 1, 1, 1, 1'
["b'\\x000", ' 0', ' 0', ' 1', ' 1', ' 1', ' 1', " 1'"]
b', 1, 1, 1, 255, 103, 13360, 12912)'
["b'", ' 1', ' 1', ' 1', ' 255', ' 103', ' 13360', " 12912)'"]
b'('
["b'('"]
b'\x000, 0, 0, 1, 1, 1, 1, 1'
["b'\\x000", ' 0', ' 0', ' 1', ' 1', ' 1', ' 1', " 1'"]
b', 1, 1, 1, 255, 103, 13360, 12912)'
["b'", ' 1', ' 1', ' 1', ' 255', ' 103', ' 13360', " 12912)'"]
b'('
["b'('"]
b'\x000, 0, 0, 1, 1, 1, 1, 1'
["b'\\x000", ' 0', ' 0', ' 1', ' 1', ' 1', ' 1', " 1'"]
b', 1, 1, 1, 255, 103, 13328, 12880)'
["b'", ' 1', ' 1', ' 1', ' 255', ' 103', ' 13328', " 12880)'"]
b'('
["b'('"]
b'\x000, 0, 0, 1, 1, 1, 1, 1'
["b'\\x000", ' 0', ' 0', ' 1', ' 1', ' 1', ' 1', " 1'"]
b', 1, 1, 1, 255, 103, 13328, 12880)'
["b'", ' 1', ' 1', ' 1', ' 255', ' 103', ' 13328', " 12880)'"]

NateOdem
Posts: 13
Joined: Sun May 08, 2022 5:18 pm

Re: help with E32 program (simple)

Post by NateOdem » Wed May 11, 2022 3:42 pm

Anyone.......Bueller......Bueller.....?

User avatar
francis
Posts: 28
Joined: Sat Aug 14, 2021 8:14 am

Re: help with E32 program (simple)

Post by francis » Wed May 11, 2022 3:58 pm

You are assuming that if you send exactly 10 characters as a conceptual packet, then on the receive side you will read exactly 10 characters as if the UART is organising packets for you.

But a UART is completely unstructured with data being sent byte by byte. When you read from a UART you all the bytes currently received. So imagine you call UART.read() after 5 bytes have been successfully received. You will get those 5.

How does the UART let you know there are more bytes that will be received? It doesn't. It can't. If you had read a few microseconds earlier you'de have got nothing, a few later all 10.

You have to structure your data so you know when the entire packet has arrived. Either from the nature of your data or because you use a https://en.wikipedia.org/wiki/Serial_Li ... t_ProtocolSLIP protocol you know what to expect.

You've basically presented 100+ lines of code and asked us to get it working. Nobody will do that. Unless you pay us.

If you're building any kind of communication systems you build layers.
The UART is the physical layer.
Build a data link layer on top which send and receives whole packets.
A protocol on top of that that knows what to do with the data received.
Depending on complexity you might also need session and application layers.

Communication when everything goes right is quite easy. It's how to handle the unexpected that introduces all the complexity.

NateOdem
Posts: 13
Joined: Sun May 08, 2022 5:18 pm

Re: help with E32 program (simple)

Post by NateOdem » Wed May 11, 2022 5:04 pm

If I put a long enough delay after sending, the RX receives just fine - one full command on each line received. I just need it to read quicker. I have added the .sendbreak() after, which from what I understand, sends a break longer than the receive byte time - letting the RX side know where the end of the transmission "packet" is. If that is how that command works, why is it not recognizing the end of the data transmission?

User avatar
francis
Posts: 28
Joined: Sat Aug 14, 2021 8:14 am

Re: help with E32 program (simple)

Post by francis » Wed May 11, 2022 5:17 pm

UART.sendbreak()
Send a break condition on the bus. This drives the bus low for a duration longer than required for a normal transmission of a character.

This sends an illegal character. An (8 bit no parity) uart line can never be low for longer than 9 clocks. The stop bit is always high.
I've only just read about sendbreak() I see nothing about how the receiver flags it got a break. Normally a uart silently discards characters when the stop bit is invalid.

My guess right now is its a feature in case it might be useful. In case hardware exists that reports it.

Why not just use a SLIP protocol so you have a completely portable transport mechanism
You could mark packet end by a long delay, but remember the sender process in a multi user system could be pre-empted for arbitrarily long. You need a timeout longer than the worst case pre emption.

And how long is the worst case pre emption. Difficult to say. Probably <30ms

NateOdem
Posts: 13
Joined: Sun May 08, 2022 5:18 pm

Re: help with E32 program (simple)

Post by NateOdem » Wed May 11, 2022 5:53 pm

I am under the impression that .sendbreak() combined with the .readline() on the RX side, would have the rx read a "line" (and stop at the break) and return to a new line and repeat - which should output something like:

(0, 6, 153, 1, 1, 1, 1, 1, 1, 1, 1, 255, 103, 1005, 394)
(0, 6, 153, 1, 1, 1, 1, 1, 1, 1, 1, 255, 103, 1005, 394)
(0, 6, 153, 1, 1, 1, 1, 1, 1, 1, 1, 255, 103, 1005, 394)
(0, 6, 155, 1, 1, 1, 1, 1, 1, 1, 1, 255, 103, 1005, 394)


which is what I am trying to get on the RX side.....

User avatar
francis
Posts: 28
Joined: Sat Aug 14, 2021 8:14 am

Re: help with E32 program (simple)

Post by francis » Wed May 11, 2022 7:33 pm

I was afraid you would say that.

readline() means get a line (of text) ending in a \n.
Often software process files line by line. And lines tend to be short so reading line by line is memory efficient.

But you're working with binary so stay the hell away from readline()
You drew my attention to the sendbreak() call. It basically means: do something illegal as a signal to the other side.

Assuming the other side notices this illegal condition and reports it.
But there seems to be no mechanism in the micropython uart for the receiver to notify you of this illegal condition.
As I said protocol is to just silently discard.

1005, and 394 don't fit in a byte so I'm afraid you're very confused about what a byte stream looks like.

Post Reply