Bluetooth conflict with LittlevGL ili9341 driver

I have a simple Bluetooth scanning function that works fine.
Importing the ili9341 driver causes the Bluetooth def bt_irq function to exit after a couple of cycles.
No REPL errors.
Microcontroller still responsive.
Where does one start to track down the conflict.
Using a Lion D32 Pro v2

Hi,

In order to help we need more information, your original information you posted is not enough, at least not for me to try to help you.

I guess you are using the lv_port_esp32 project as base?

Do you have your code hosted somewhere so we can take a look at it?

Do you have the log of the console when you run idf.py monitor?

What version of the esp-idf are you using?

MicroPython v1.9.4-2158-g6b32fae73-dirty on 2020-02-29; ESP32 module (spiram) with ESP32
IDF 4.0
Never used idf.py monitor what information will this give that REPL is not?
esp is not freezing or crashing.

import utime, ubinascii, ubluetooth
import lvgl as lv
from micropython import const
from ili9341 import ili9341
# from xpt2046 import xpt2046

lv.init()
disp = ili9341(miso=19, mosi=23, clk=18, cs=14, dc=27, rst=33, backlight=32, backlight_on=2, rot=ili9341.LANDSCAPE, width=320, height=240)

_IRQ_SCAN_RESULT = const(1 << 4)
_IRQ_SCAN_COMPLETE = const(1 << 5)

bt=ubluetooth.BLE()
bt.active(True)

def ble(x):
  start = utime.time()
  x = (["0004", "0005"])
  print(x)
  def bt_irq(event, data):
    if event == _IRQ_SCAN_RESULT and data[4][2:11] == b'BLEsensor' :
      print("found a sensor")
      mf = (ubinascii.hexlify(data[4]).decode("utf-8"))
      sn = (ubinascii.hexlify(data[1]).decode("utf-8"))[-4:]
      if sn in x:
        x[x.index(sn)] = [data[3], int(mf[36:38], 16), (-(int(mf[38:44], 16) & 0x8000) | (int(mf[38:44], 16) & 0x7fff)) /10]
        print('got sn:', sn)

    elif event == _IRQ_SCAN_COMPLETE:
      print("scan completed in",utime.time() - start,'sec')
      print(x)

  bt.gap_scan(10_000, 40_000, 40_000)
  bt.irq(handler = bt_irq)
  print("scan start @", utime.time() - start, 'sec')

scr = lv.obj()

l_p1 = lv.label(scr)
l_p1.set_text('Temp-1: ')
l_p1.align(scr, lv.ALIGN.CENTER, -50, -20)

l_p2 = lv.label(scr)
l_p2.set_text('Temp-2: ')
l_p2.align(scr, lv.ALIGN.CENTER, -50, 20)

lv.scr_load(scr)
ble('x')

Some ideas of things you can check

  • Latest stable release of Micropython is v1.12. lv_micropython is aligned to that version.
    Are you aligned to that?
  • Please check what exactly triggers the problem: Only importing lvgl? importing lvesp32? importing ili9341?
  • Are you sure the action of importing a library causes the problem? Maybe it’s the loading of the display driver, disp = ili9341(...?
  • The display driver consumes RAM. Did you try to lowering it? You can configure it to use single buffer instead of double buffer (double_buffer=False). You can increase factor. By default it’s 4 meaning 1/4 of the screen is buffered. Try 8 or 16.
  • You are saying "bt_irq exit after a couple of cycles". Please try logging every “event” and “data” that is passed to it. Currently you only act upon _IRQ_SCAN_RESULT and _IRQ_SCAN_COMPLETE. Maybe it was called with some other event?

Perhaps there’s some issue with SPI? I know that people have had to change duplex settings to make the display and touchscreen work well together. Maybe there’s something similar happening with Bluetooth.

Hi,

I assumed you where using the esp32 with the idf framework.

What is lvesp32 for?


double_buffer=False… no change
increase factor… no change

>>> ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371      
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4932
load:0x40078000,len:11424
load:0x40080400,len:6076
entry 0x400806c8
W (1656) cpu_start: Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.
MicroPython v1.9.4-2158-g6b32fae73-dirty on 2020-02-29; ESP32 module (spiram) with ESP32
Type "help()" for more information.

sys.version:
 3.4.0

sys.implementation:
 (name='micropython', version=(1, 12, 0), mpy=10757)

micropython.mem_info:
stack: 704 out of 31744
GC: total: 4098240, used: 5344, free: 4092896
 No. of 1-blocks: 20, 2-blocks: 4, max blk sz: 264, max free sz: 255738
GC memory layout; from 3f817740:
00000: h=hhhBMLhDBhSh=hhh==============================================
00400: ================================================================
00800: ================================================================
00c00: ================================================================
01000: =========================hh==h========================B.......h=
01400: ===..h========h.................................Sh........Sh=...
01800: ......h=.........F..............................................
       (3995 lines all free)
e8800: ............
>
MicroPython v1.9.4-2158-g6b32fae73-dirty on 2020-02-29; ESP32 module (spiram) with ESP32
Type "help()" for more information.

output… event & data

MicroPython v1.9.4-2158-g6b32fae73-dirty on 2020-02-29; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>>
>>> ble('x')
['0004', '0005']
scan start @ 0 sec
>>> 16
(1, b'o\x8cy\x12\xe5\x04', True, -77, b'\x02\x01\x1a\x11\x07\x96\xc1\x9fU1\xc9!\xb8\xc3L\\\xb2\x0fs\xa4\x9a\t\t44098CEB')
16
(1, b'\x03\xf5\xae\x8d\x89b', False, -51, b"\x1e\xff\x06\x00\x01\t \x02\xbe\xc7\xe2\x1f\x83\xd5:\xaa\xbc\x99;\x8f'\xcb@Xp\xd6\x9aKj\x8f'")
16
(1, b'o\x8cy\x12\xe5\x04', True, -71, b'\x02\x01\x1a\x11\x07\x96\xc1\x9fU1\xc9!\xb8\xc3L\\\xb2\x0fs\xa4\x9a\t\t44098CEB')
16
(1, b'o\x8cy\x12\xe5\x04', True, -79, b'\x02\x01\x1a\x11\x07\x96\xc1\x9fU1\xc9!\xb8\xc3L\\\xb2\x0fs\xa4\x9a\t\t44098CEB')
16
(1, b'o\x8cy\x12\xe5\x04', True, -79, b'\x02\x01\x1a\x11\x07\x96\xc1\x9fU1\xc9!\xb8\xc3L\\\xb2\x0fs\xa4\x9a\t\t44098CEB')
16
(1, b'\x1b\xcb\xfd\xa0Y2', False, -75, b'\x1e\xff\x06\x00\x01\t \x02%?%\x1aL\xed\x9e\x86\x07\rt\xeb\x17+\x9e\xb8\xf4\x8c\x7f\x07\x1f\xf4?')
16
(1, b'x7sNc\xf1', True, -54, b'\x02\x01\x1a\x02\n\x0c\x0b\xffL\x00\x10\x06\x03\x1e\xc3\xe6\xe8\x1a')
16
(1, b'\x03\xf5\xae\x8d\x89b', False, -52, b"\x1e\xff\x06\x00\x01\t \x02\xbe\xc7\xe2\x1f\x83\xd5:\xaa\xbc\x99;\x8f'\xcb@Xp\xd6\x9aKj\x8f'")

----just stops hit enter and returns to repl prompt------

how to change to duplex settings… code sample please.

I’m not sure as I don’t work with ESP32. I just know from reading the issue list that duplex settings have been an issue.

Actually he is using esp32 with the idf framework.
Micropython is just a wrapper around it.

lvesp32 is a library responsible for calling lv_tick_inc and lv_task_handler periodically from Micropython context. For more information, have a look at lvgl porting guide.
lvesp32 is implicitly imported by ili9341 (if you haven’t imported it explicitly).

It’s interesting that importing lvesp32 is enough for ble drop.

Could you explain what exactly you mean by “ble drop”? Does the ble driver just stop calling your bt_irq? Or is there some other error happening?

lvesp32 by itself doesn’t do much. It creates a new RTOS timer (xTimerCreate) which calls lv_tick_inc and to lv_task_handler periodically (the later is called indirectly by scheduling it to Micropython).
I don’t see how any of these could be related to BLE, but apparently it somehow does.

If you want to further debug it, I suggest you try to change lvesp32 not to call lv_tick_inc and lv_task_handler (or only call one of them) and see in which cases the problem persists. The source file is lv_binding_micropython/driver/esp32/modlvesp32.c.
You will not be able to use lvgl if you change lvesp32 like this, but the goal here is just to see if ble still drops when lvesp32 is imported, or not.

I don’t see how BLE and SPI are related, so I doubt changing half/full duplex would matter.

I believe def bt_irq() is in its own thread and while scanning
there is a collision over some resource…
what I do not know.

On a fresh reboot you can run ble(‘x’) and
pass thru def bt_irq() varying between 5 to 100 times,
then freezes before the duration of 10 sec is meet.
bt.gap_scan(10_000, 30_000, 20_000)
duration=10 interval=.03 window=.02 seconds
ble(‘x’) refuses to run second time (needs reboot)

>>>
in BTmoduleRMG.py
ILI9341 initialization completed
Enable backlight
Double buffer
>
MicroPython v1.9.4-2158-g6b32fae73-dirty on 2020-02-29; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>>
>>> ble('x')
['0004', '0005']
scan start @ 0 sec
>>> 1
2
3
4
5
6
7
8
9
10
11
12
13
14       *just freeze before 10 sec... loops are not consistent *
         *press enter to get REPL prompt... run ble('x') again *
>>> ble('x')
['0004', '0005']
scan start @ 0 sec
>>>    *does not run at all*

On the last run log you sent, you load the display driver.
However, you said the problem happens even if not loading the display driver or creating any lvgl objects.
I’m talking about this line you sent above:

image
From this line it seems that it’s enough to import lvesp32 to experience the problem.
Let’s start by debugging this simple scenario without the display driver and lvgl objects, before jumping to the full scenario.

I still didn’t understand from your explanations what is a “ble drop”. Please run something like:

import lvgl as lv
lv.init()
import lvesp32
# Do your ble thing..
# Show us what happens, what is a "ble drop" vs. correct behavior.

Then please try my suggestions above. (changing lvesp32 module)
One more thing you can try is increasing the time in xTimerCreate.

image

I would appreciate if you would investigate/debug this as you are deeply familiar with this library. Below is the exact code that was used for above tests.

import utime, ubluetooth
import lvgl as lv
# import lvesp32
from micropython import const
# from ili9341 import ili9341
# from xpt2046 import xpt2046

# lv.init()
# disp = ili9341(miso=19, mosi=23, clk=18, cs=14, dc=27, rst=33, backlight=32, backlight_on=2, factor=4, rot=ili9341.LANDSCAPE, width=320, height=240)

_IRQ_SCAN_RESULT = const(1 << 4)
_IRQ_SCAN_COMPLETE = const(1 << 5)

bt=ubluetooth.BLE()
bt.active(True)

N = 1
def ble(x):
  start = utime.time()
  x = (["0004", "0005"])
  print(x)

  def bt_irq(event, data):
    global N
    print(N)
    N += 1
    if event == _IRQ_SCAN_RESULT and data[4][2:11] == b'AccuTherm' :
      print("found a sensor")

    elif event == _IRQ_SCAN_COMPLETE:
      print("scan completed in",utime.time() - start,'sec')
      print(x)

  bt.gap_scan(10_000, 30_000, 20_000)  # 10 x .03 x .02 
  bt.irq(handler = bt_irq)
  print("scan start @", utime.time() - start, 'sec')

# scr = lv.obj()
# l_p1 = lv.label(scr)
# l_p1.set_text('Temp-1: ')
# l_p1.align(scr, lv.ALIGN.CENTER, -50, -20)
# l_p2 = lv.label(scr)
# l_p2.set_text('Temp-2: ')
# l_p2.align(scr, lv.ALIGN.CENTER, -50, 20)
# lv.scr_load(scr)

ble('x')

Again I have no idea how to use that command.

If you are willing to make an effort and debug this, I can try helping you.
But currently I don’t have the time reproducing this on hardware and debugging this myself.

From this screenshot it seems that importing ili9341 and not importing lvesp32 causes the problem.
However, from your previous post I understood that it was enough to import lvesp32:
image
Could you check that? It’s important to exactly understand the scenario in order to debug it.

Please have a look at modlvesp32.c. That’s the C file where lvesp32 module is defined.
My suggestion was that you make some changes there, build the firmware and try your script again. Are you willing to make this effort?
btw this is only relevant if importing lvesp32 alone is enough to reproduce the problem. If this is not the case we would need to check something else.

I do not understand “c” !!!


This appears to have corrected the problem.
Thank You amirgon