Prva misao je bila „zašto bi“, a već sledeća  “što da ne“ probamo MicroPython na STM32F401RE. Ova ploča je jedna od osnovnih edukacionih alata na elektrotehničkim fakultetima širom sveta, a posebno u Indiji. Ovo joj je veoma velika preporuka.

O STM32F401RE smo već pisali ranije, a sada ćemo u svetlu moderne opsednutosti Python jezikom proći kroz ovu avanturu nazvanu “microPython tamo gde mu mesto i nije”.

Prvo oduševljenje je bilo da uopšte postoji microPython port za ovu platformu i on se može naći na ovoj lokaciji. Instalacija je više nego jednostavna, sve sto treba uraditi je preuzeti DFU/hex fajl i update-ovati firmeware ploče koristeći STSW-LINK004: STM32 ST-LINK utility (ili modernijim alatom pod imenom STM32CubeProgrammer). I to je sve. U par koraka NUCLEO-F401RE je postao MicroPython ploča.

STM32F401RE MicroPython kod

I tada kreću zanimljivosti koje su prava poslatica za one koji obožavaju osećaj da je nešto (što u principu treba da radi out-of-the-box) proradilo. Machine.h biblioteka će proraditi odmah, proradiće i Pin i I2C paketi, ali PWM neće.

STM32F401RE u radu

Dobro, povezali smo SSD1306 ekran i preuzeli odgovarajuću biblioteku, te je uz I2C komunikaciju zasijao za tren. Povezivanje SCL -> SCL/D15 i SDA -> SDA/D14 je odradio posao.

Joystick HW-504 na analognim ulaznim portovima VRx -> A0, VRy -> A1 se očitava kako treba i digitalni ulaz na SW -> D8 radi.

I sada dolazi RGB dioda (R -> D3/PWM, G -> D5/PWM i B -> D7), gde se sa PWM kontroliše sjaj. PWM funkcije ne rade, te je neophodno ručno podesiti tajmer:

p_red = Pin('PB3') # PB3-D3 has TIM2, CH2
tim = Timer(2, freq=4000)
ch = tim.channel(2, Timer.PWM, pin=p_red)
ch.pulse_width_percent(red)

Tajmer 2, na kanalu 2 za pin PB3… čemu onda MicroPython koji liči na C++.

Ideja je bila da se promenom položaja Joystick-a koji ide po HSV krugu, menjaju boje i to prikazuje bojom svetlosti na diodi. Da bi se to uradilo potreban je „import colorsys„, ali on nije implementiran. Nema veze, hteli smo da napišemo neku priručnu varijantu HSV-to-RGB rutine, i za to nam treba malo više matematike. Dakle „import numpy„… ali nema ni njega.

SSD1306 ekran

Rešavamo stvar svodeći se na najjednostavnije opcije, klik za plavu, levo-desno i gore-dole za crvenu i zelenu. Radi, i interesantno je.

Ovo je bilo zanimljivo putovanje u MicroPython, koje nam je pokazalo da je ovaj sistem odlično rešenje za poznavaoce Pythona i njihove prve korake ka STM32 ekosistemu. Da pojedine bitne funkcije nedostaju, nedostaju. Već drugi korak zbog toga mora bit ka Arduino IDE, STM IDE ili Mbed.com-u. Ovaj potonji je posebno interesantan u svojoj on-line verziji.

from machine import I2C, Pin, ADC
from utime import sleep_ms
from ssd1306 import SSD1306_I2C

from pyb import Pin, Timer

blue_on = False

def remap(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

def handle_interrupt(pin):
    global blue_on
    if (blue_on):
        blue_on = False
    else:
        blue_on = True
    global interrupt_pin
    interrupt_pin = pin
    sleep_ms(20)

xAxis = ADC(Pin('PA1'))
yAxis = ADC(Pin('PA0'))

SW = Pin('PA9', Pin.IN, Pin.PULL_UP)
SW.irq(trigger=Pin.IRQ_FALLING, handler=handle_interrupt)

red = 0
green = 0
blue = 0

p_red = Pin('PB3') # PB3-D3 has TIM2, CH2
tim = Timer(2, freq=4000)
ch = tim.channel(2, Timer.PWM, pin=p_red)
ch.pulse_width_percent(red)

p_green = Pin('PB4') # PB4-D5 has TIM3, CH1
tim = Timer(3, freq=4000)
ch = tim.channel(1, Timer.PWM, pin=p_green)
ch.pulse_width_percent(green)

p_blue = Pin('PA8') # PB10-D6 has TIM1, CH1
tim = Timer(1, freq=4000)
ch = tim.channel(1, Timer.PWM, pin=p_blue)
ch.pulse_width_percent(blue)


i2c = I2C(1)
oled = SSD1306_I2C(128, 64, i2c)

oled.show()
oled.fill(0)
oled.show()
oled.text("RED:   {}".format(red),10,10,1)
oled.text("GREEN: {}".format(green),10,30,1)
oled.text("BLUE:  {}".format(blue),10,50,1)
oled.show()



while True:
    xRef = round (remap (xAxis.read_u16(), 0, 65555, 0, 100))
    yRef = round (remap (yAxis.read_u16(), 0, 65555, 0, 100))
    oled.fill(0)
    oled.text("RED:   {}".format(str(xRef)),10,10,1)
    oled.text("GREEN: {}".format(str(yRef)),10,30,1)
    oled.text("BLUE: {}".format(str(blue)),10,50,1)
    oled.show()
    
    p_red = Pin('PB3') # PB3-D3 has TIM2, CH2
    tim = Timer(2, freq=4000)
    ch = tim.channel(2, Timer.PWM, pin=p_red)
    ch.pulse_width_percent(xRef)
    
    p_green = Pin('PB4') # PB4-D5 has TIM3, CH1
    tim = Timer(3, freq=4000)
    ch = tim.channel(1, Timer.PWM, pin=p_green)
    ch.pulse_width_percent(yRef)
    
    p_blue = Pin('PA8') # PB10-D6 has TIM1, CH1
    tim = Timer(1, freq=4000)
    ch = tim.channel(1, Timer.PWM, pin=p_blue)
    if (blue_on):
        blue = 255
    else:
        blue = 0
    ch.pulse_width_percent(blue)
    
    sleep_ms(100)
    

 

Follow me