9.0 TOTAL SCORE

banana pi bpi-leaf-s3

Development kits
0 Out of 5

Based on 0 Users

Build quality 9
Implemented technology 9
Ease-of-use 9
Price/performance ratio 9
PROS
  • Feather-like set of IO
  • Good compatibility with third-party HALs
CONS
  • No significant disadvantages here!
Bottomline

An inexpensive development system based on ESP32S3 SiC intended for the development of IoT applications.

What's your opinion on this product?
0 (0)

Sinovoip’s Banana Pi family has gotten another interesting member alongside of BPi-PicoW-S3. In our hands today is an MCU development board with the newest Espressif ESP32-S3 SoC – a dual-core Xtensa LX7-based chip clocked at 240MHz. The board’s called BPI-Leaf-S3 and shares the form factor of Espressif’s own ESP32-S3-DevKitC-1 system, with which it shares the pinout. This does make it a drop-in replacement for the latter in projects. There’s 512kB RAM and 2MB pseudo-SRAM, alongside 8MB of external Serial NOR Flash.

BPi-Leaf-S3 pinout

ESP32-S3 SoC, like all ESP32 chipsets, has integrated radios – namely the 2.4 GHz, 802.11 b/g/n Wi-Fi and Bluetooth 5 (supporting the Low Energy Physical Layer – with long range and fast 2 Mbps data transfer). Out of the 45 GPIO pins available on the SoC, the board breaks out 36 (among which pins with specialised SPI, I2S, I2C, PWM, RMT, ADC, UART, SD/MMC host and TWAITM functions are available).

BPi-Leaf-S3 box

The board also features RST and BOOT keys as well as one Neopixel RGB LED on pin 48. What sets the Leaf apart is the USB Type-C connector, a 3.7V Li-ion battery port (with a charging circuit – akin to those Adafruit’s Feather boards have) and a separate four-pin I2C (GND, 3V3, SDA, SCL) connector for attaching hardware to the main SoC serial bus.

BPi-Leaf-S3 top viewBPi-Leaf-S3 bottom view

Like all ESP32-based boards, the Leaf can be programmed using Espressif’s own Eclipse-based IDE. This gives low-level control over every aspect of the hardware and is ideal for developing demanding applications. For users coming from STEM backgrounds, accustomed to Adafruit CircuitPython, the board ships with the interpreter pre-installed. The board also supports code written in Processing using the Arduino IDE – which is bound to please the more experienced members in the maker community accustomed to C, and vanilla MicroPython support is also available with a custom boot loader available for download at Banana Pi’s GitHub.

BPi-Leaf-S3 project

For purposes of demonstrating basic capabilities of the system, we wrote a little demo project in MicroPython for driving a simple 8-segment LED display. We connected it to pins 1 through 8 of the board and wrote a driver program which is capable of sequentially parsing strings and integers and showing them on the segmented display. It’s an elegant bit of code primarily aimed at showcasing the level of code abstraction possible with such a development kit.

BPi-Leaf-S3 movie

Overall, we opine that the BPi-Leaf-S3 is a trustworthy and powerful system which comes at a very affordable price, well supported by various IDEs. It’s based on the popular ESP32 platform – which gives it a wealth of community support, as well.

from machine import Pin, PWM
import time
import sys


#Pin list for digits
pinList = [[1,2,3,4,6,7],[4,6],[1,3,4,5,7],[1,4,5,6,7],[2,4,5,6],[1,2,5,6,7],[1,2,3,5,6,7],[1,4,6],[1,2,3,4,5,6,7],[1,2,4,5,6,7]]

#############
#Driver code#
#############

#Pin setup
for i in range (1,9):
    globals()[f"PWM_LED{i}"] = PWM(Pin(i)) #Global dictionary used for dynamic global variable generation
    globals()[f"PWM_LED{i}"].freq(1000)
    globals()[f"PWM_LED{i}"].duty(0)

#Clear routine
def clearDisplay():
    for i in range (1,9):
        globals()[f"PWM_LED{i}"].duty(0)
    
#Digit display - use when dimming effects or custom timings required
def displayDigit(n, dot, dutyCycle):
    if n in range (0,10) and dot in range (0,2): #Check if arguments in range to prevent variable naming errors
        clearDisplay() #Clear display in case something was displayed before
        for i in pinList[n]:
            globals()[f"PWM_LED{i}"].duty(dutyCycle)
        if dot == 1: #Dot as argument
            PWM_LED8.duty(dutyCycle)
    elif str(n) == '-': #Stringify n for data integrity
        clearDisplay()
        PWM_LED5.duty(dutyCycle)
    else: #If not, safely handle error
         raise Exception("displayDigit error (could be caused by arguments out of bounds or program termination).")
    
#Number display as a wrapper for displayDigit command
def displayNumber(n, dot, dutyCycle, ms, pre_ms=50): #Optional pre_ms argument for predelay settings, automatically set to 50
    try: #Try if int; exception catches for logic if string
        numList = [int(x) for x in str(n)] #Turns an integer into a list of its digits, e.g. 429 -> [4,2,9]
    except ValueError: #If argument is string, do whatever it needs to make above command accept this input
        numList = []
        for x in n:
            try:
                numList.append(int(x))
            except ValueError:
                numList.append(x)
            
    for i in numList: #Iterate through list and pass i as argument into the displayDigit command
        try: #No argument check in wrapper command as subcommand performs these, try method required to pass exception along
            clearDisplay()
            time.sleep_ms(pre_ms)
            displayDigit(i, dot, dutyCycle)
            time.sleep_ms(ms)
        except:
            raise Exception("displayNumber error (could be caused by arguments out of bounds or program termination).")
        
###########
#Main code#
###########


while True:
    displayNumber("17-12-1973",0,1023,750)

 


Aleksandar D.
Follow me