Adsense HTML/JavaScript

Tuesday, April 26, 2022

ESP32-S2 (arduino-esp32) display on ILI9341 SPI TFT with Touch, using TFT_eSPI Library.

TFT_eSPI is a Arduino and PlatformIO IDE compatible TFT library optimized for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips.

Connection:


ILI9488
-------
1  - VCC	VCC
2  - GND	GND
3  - CS		34
4  - RESET	38
5  - DC		39
6  - SDI(MOSI)	35
7  - SCK	36
8  - LED	VCC
9  - SDO (MISO)	37
10 - T_CLK	(SCK)
11 - T_CS	40
12 - T_DIN	(MOSI)
13 - T_DO	(MISO)
14 - T_IRQ	no connection
In arduino-esp32, the default pins of ESP32S2 Dev Module for SPI are:
Default SS:         34
Default MOSI:    35
Default MISO:    37
Default SCK:      36

In TFT_eSPI, the SPI bus for the touch controller is shared with the TFT and only an additional chip select line is needed.

Setup TFT_eSPI Library:

This video show how to setup TFT_eSPI library in Arduino IDE, tested on ESP32-S2-Saola-1, with 2.4inch SPI Module ILI9341 SKU:MSP2402 with Touch.


Refer to "Tips" section in the TFT_eSPI page:

If you load a new copy of TFT_eSPI then it will overwrite your setups if they are kept within the TFT_eSPI folder. One way around this is to create a new folder in your Arduino library folder called "TFT_eSPI_Setups". You then place your custom setup.h files in there. After an upgrade simply edit the User_Setup_Select.h file to point to your custom setup file.

You can take this one step further and have your own setup select file and then you only need to replace the Setup.h line reference in User_Setup_Select.h to.

mySetup70_ESP32_S2_ILI9341.h, my custom setup.h for ESP32-S2 using ILI9341.
// Setup for the ESP32 S2 with ILI9341 display
// Note SPI DMA with ESP32 S2 is not currently supported
#define USER_SETUP_ID 70
// See SetupX_Template.h for all options available
#define ILI9341_DRIVER
/*
                    // Typical board default pins
#define TFT_CS   10 //     10 or 34

#define TFT_MOSI 11 //     11 or 35
#define TFT_SCLK 12 //     12 or 36
#define TFT_MISO 13 //     13 or 37

#define TFT_DC   14
#define TFT_RST  15
*/
#define TFT_MISO 37
#define TFT_MOSI 35
#define TFT_SCLK 36
#define TFT_CS   34
#define TFT_DC   39
#define TFT_RST  38

//#define TOUCH_CS 16 // Optional for touch screen
#define TOUCH_CS 40


#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF

#define SMOOTH_FONT

// FSPI port will be used unless the following is defined
#define USE_HSPI_PORT

//#define SPI_FREQUENCY  27000000
#define SPI_FREQUENCY  40000000   // Maximum for ILI9341

#define SPI_READ_FREQUENCY  6000000 // 6 MHz is the maximum SPI read speed for the ST7789V

#define SPI_TOUCH_FREQUENCY 2500000


Updated User_Setup_Select.h.
// This header file contains a list of user setup files and defines which one the
// compiler uses when the IDE performs a Verify/Compile or Upload.
//
// Users can create configurations for different Espressif boards and TFT displays.
// This makes selecting between hardware setups easy by "uncommenting" one line.

// The advantage of this hardware configuration method is that the examples provided
// with the library should work with different setups immediately without any other
// changes being needed. It also improves the portability of users sketches to other
// hardware configurations and compatible libraries.
//
// Create a shortcut to this file on your desktop to permit quick access for editing.
// Re-compile and upload after making and saving any changes to this file.

// Customised User_Setup files are stored in the "User_Setups" folder.

#ifndef USER_SETUP_LOADED //  Lets PlatformIO users define settings in
                          //  platformio.ini, see notes in "Tools" folder.

// Only ONE line below should be uncommented.  Add extra lines and files as needed.

//#include <User_Setup.h>           // Default setup is root library folder
#include <../TFT_eSPI_Setups/mySetup70_ESP32_S2_ILI9341.h>

//...




Monday, April 11, 2022

XIAO BLE Sense (Arduino framework) IMU USB Mouse

Exercise to implement IMU USB Mouse on XIAO BLE Sense (Arduino framework), reading onboard LSM6DS3 Accelerometer.


XIAOBLE_inclinometer_mouse.ino

/*
 * Seeed XIAO BLE exercise
 * act as USBMouse,
 * read IMU LSM6DS3 and report mouse movement accordingly.
 */

#include "LSM6DS3.h"
#include "Wire.h"
#include "PluggableUSBHID.h"
#include "USBMouse.h"

USBMouse Mouse;

//Create a instance of class LSM6DS3
LSM6DS3 myIMU(I2C_MODE, 0x6A);    //I2C device address 0x6A

void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);
    //while (!Serial);
    //Call .begin() to configure the IMUs
    if (myIMU.begin() != 0) {
        Serial.println("Device error");
    } else {
        Serial.println("Device OK!");
    }
}

float vector_2_degrees(float x, float y){
    float angle = atan2 (y, x) * 180.0f/PI;;

    if (angle < 0){
      angle += 360;
    }

    return angle;
}

void loop() {
    //Accelerometer
    float x, y, z;
    x = myIMU.readFloatAccelX();
    y = myIMU.readFloatAccelY();
    z = myIMU.readFloatAccelZ();

    float angle_xz = vector_2_degrees(x, z);
    float angle_yz = vector_2_degrees(y, z);

    Serial.print("angle_xz:");
    Serial.print(angle_xz);
    Serial.print(",");
    Serial.print("angle_yz:");
    Serial.println(angle_yz);

    int Xmove = 0;
    int Ymove = 0;
    //LEFT/RIGHT
    if (angle_xz > 120)
        Xmove = +3;
    else if (angle_xz > 105)
        Xmove = +1;
    else if (angle_xz < 60)
        Xmove = -3;
    else if (angle_xz < 75)
        Xmove = +1;
        
    //UP/DOWN
    if (angle_yz > 120)
        Ymove = -3;
    else if (angle_yz > 105)
        Ymove = -1;
    else if (angle_yz < 60)
        Ymove = +3;
    else if (angle_yz < 75)
        Ymove = +3;

    if ((Xmove!=0)||(Ymove!=0)){
      Mouse.move(Xmove,Ymove);
    }
        
    delay(50);
}



related:
Raspberry Pi Pico/CircuitPython act as IMU USB Mouse, read LSM303 Accelerometer and report as mouse movement. (my another blogspot)

Monday, April 4, 2022

CircuitPython BLE UART between XIAO BLE Sense and ESP32-C3/S3

It's a exercise of CircuitPython to implement BLE UART between server and client. All boards are flashed with CircuitPython 7.2.4 firmware, with adafruit_ble 8.2.3.


The server side run on Seeed XIAO BLE Sense (nRF52840) + Expansion board. The code modified from Adafruit CircuitPython ble_uart_echo_test.py example, or here, setup BLE UART Server, but display on SSD1306 I2C OLED instead of echo back.

The client side run on Ai-Thinker NodeMCU ESP-C3-32S-Kit and Espressif ESP32-S3-DevKitC-1. The code modified from ble_uart_echo_client.py, or here. The user enter text in REPL to send to server side and display on SSD1306 I2C OLED.

un-solved issue:

If server side offline and the BLE link disconnected, then server side online again and re-connected, the client side will fail; tested on both ESP-C3-32S-Kit and ESP32-S3-DevKitC-1.


Exercise code:

cpyXIAOBLE_ble_uart_server_ssd1306.py, run on server side.
"""
Run CircuitPython 7.2.4 on
Seeed XIAO nRF52840 Sense with nRF52840 + Expansion Board.
Modified from ble_uart_echo_test.py.
Act as BLE server, wait connection and
display received line on ssd13106 OLED.

libs need:
- adafruit_ble folder
- adafruit_displayio_ssd1306.mpy
"""
import os
import sys
import board
import busio
import displayio
import adafruit_displayio_ssd1306

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_ble import __name__ as BLE_NAME
from adafruit_ble import __version__ as BLE_VERSION

displayio.release_displays()

# Create the I2C interface and display object of SSD1306_I2C.
i2c = busio.I2C(board.SCL, board.SDA)

ssd1306_i2c_addr = 60
display_width =128
display_height = 64
display_bus = displayio.I2CDisplay(
    i2c, device_address=ssd1306_i2c_addr)
display = adafruit_displayio_ssd1306.SSD1306(
    display_bus, width=display_width, height=display_height)

# with displayio initialized, and have nothing displayed.
# displayio act like a REPL terminal.
# anything print() will be displayed on displayio also.

print("=================================================")
info = sys.implementation[0] + ' ' + os.uname()[3] + '\n' + \
       'run on ' + os.uname()[4]
print(info)
print("=================================================")
print(BLE_NAME, ":", BLE_VERSION)
print("=================================================")
print(adafruit_displayio_ssd1306.__name__, adafruit_displayio_ssd1306.__version__)
print("SCL: ", board.SCL)
print("SDA: ", board.SDA)

print(display)
print("display.width x height: ",
      display.width, " x ", display.height)
#=================================

ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)

#=== scroll up to print screen ===
print()
print()
print()
print(" ---- hello ----")

while True:
    ble.start_advertising(advertisement)
    print("Waiting to connect")
    while not ble.connected:
        pass
    print("Connected")
    while ble.connected:
        s = uart.readline()
        if s:
            print(s.decode())
            uart.write(s)

print("~ bye ~")

cpyESP32x3_ble_uart_client_repl.py, run on client side.
"""
Run CircuitPython 7.2.4 on
AITHinker ESP32-C3S_Kit with ESP32-C3FN4/ESP32-S3-DevKitC-1-N8R8 with ESP32S3.
Modified from ble_uart_echo_client.py.
Act as BLE client, connect to server,
get user input from REPL and send to server.

libs need:
- adafruit_ble folder
"""
import os
import sys
import time

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_ble import __name__ as BLE_NAME
from adafruit_ble import __version__ as BLE_VERSION

print("=================================================")
info = sys.implementation[0] + ' ' + os.uname()[3] + '\n' + \
       'run on ' + os.uname()[4]
print(info)
print("=================================================")
print(BLE_NAME, ":", BLE_VERSION)
print("=================================================")

ble = BLERadio()
while True:
    while ble.connected and any(
        UARTService in connection for connection in ble.connections
    ):
        for connection in ble.connections:
            if UARTService not in connection:
                continue
            
            uart = connection[UARTService]
            
            # input() will block the code.
            # if connection lost while waiting user input,
            # ConnectionError will thrown in uart.write()
            userinput = input("\nEnter something: ")
            print(userinput)
            
            try:
                uart.write(userinput)
            except ConnectionError as exc:
                print("ConnectionError:", exc)
            
    print("disconnected, scanning")
    for advertisement in ble.start_scan(ProvideServicesAdvertisement, timeout=1):
        if UARTService not in advertisement.services:
            continue
        ble.connect(advertisement)
        print("connected")
        break
    ble.stop_scan()




It you cannot open two Thonny instance, read last post How to open dual Thonny instance.



Sunday, April 3, 2022

How to open dual Thonny instance

By default, Thonny Python IDE allow only one instance running; that means we cannot run two program/device at the same time.

To enable dual instance of Thonny, click on Thonny Menu Tools > Options...


Under General Tab, UN-CHECK the option "Allow only single Thonny instance" option, OK to accept, close and re-start Thonny to make it take effect.


After re-start, you can re-start another Thonny instance from system Menu. Such that you can run/monitor two program for two device at the same time.


Saturday, April 2, 2022

Upgrade esptool using pip3

To upgrade esptool, enter thte command in Terminal:
$ pip3 install esptool --upgrade

Upgrade esptool on Raspberry Pi

With esptool upgraded to ver 3.3, now ESP32-S3 (also ESP32-C3) can be flashed on Raspberry Pi.


CircuitPython flashed on ESP32-S3 using esptool 3.3 on Raspberry Pi

Related: