2024. május 29., szerda

Gyorskeresés

Raspberry pi pico projekt #1

Írta: | Kulcsszavak: pi pico . DIY

[ ÚJ BEJEGYZÉS ]

Körülbelül fél évvel ezelőtt akadtam rá erre a kis mikrovezérlőre. Nem sok időm volt foglalkozni vele, de több projektet is elkezdtem (néhány olyanokból fakadt, hogy meg lettem kérve, csináljak ezt-meg-azt :D ).

A legelső az egy éjjeli, nem túl erős fény a mellékhelyiségbe.
Probléma: az alap világítótest túl fényesnek bizonyult ahhoz, hogy ha kell, éjjel annak a segítségével lássunk. Feleségem kérte tőlem. Nekem meg jó ürügy volt arra, hogy legyen a éjszakára felkapcsolható, "okos", mozgásérzékelővel ellátott világítás. A legegyszerűbb egy sima kapcsolóval ellátott gyengébben világító lámpatest vagy LED szalag lett volna. No, de akkor hogyan gyakoroljam a mikrovezérlő programozását? (Mert azt ugye meg kell venni, és használni kell! ;] )

Világos! Kell valami esemény általi vezérlés pluszban! Eszembe jutott, hogy a gyerek néha panaszkodik, hogy nem éri fel a kapcsolót. Milyen egyszerű is lenne, ha éjjelre igazából egy mozgásérzékelő kapcsolná fel? És akkor még csak tapizni sem kell mindenfele, amikor az ember félálomban használni szeretné a mosdót.

Hozzávalókat feljegyeztem, gondolatban elkészült az is, hogyan oldjam meg a tápot. Ez a valóságban nem teljesen úgy sikerült, ahogy kigondoltam, a képen látszani is fog.

Tehát kell
- egy pi pico mikrovezérlő,
- egy PIR szenzor,
- LED szalag (nem találtam abban a boltban olyat, ami 5V-on ad meleg fehér fényt, így RGB-set rendeltem)
- BC413 tranzisztor (vagy bármilyen hasonló NPN tranzisztor, erről majd később, hogy miért kellett)
- 3db [>70 Ohm] ellenállás
- tüskesor (plusz tüskéket használtam, hogy ne legyen minden vezeték forrasztva a későbbi javíthatóság, cserélhetőség miatt)
- jó minőségű vezetékek
- forrasztásmentes LED összekötő (van rajta két darab összecsukható műanyag "összekötő", amibe bele lehet csúsztatni a szalag végét a levágásnál, ezt kettévágtam és leblankoltam a vezetékeket)
- doboz
- kábelcsatorna
- 5v dc táp USB A kimenettel
- USB A -> mikroUSB vezeték

Kevés időt tudtam így is szánni a projektre, kb 2 hónapba telt, mire tesztelésből, forrasztásig jutottam.
A pico 5V feszültségét használja a LED szalag. Ennél a fajta LED szalagnál 4 darab végződés van: B, R, G és 5V.
Az első hetekben azt néztem meg, hogy hogyan tudom vezérelni a LED szalagot. Kezdetben Micropython-t használtam, sikerült is hamar színeket kevernem, PWM-mel a fényerősséget is tudtam állítani. A színeket a nullás, 1-es és 7-en tüskékhez rögzítettem, egy-egy ellenállásal (a tutorialokban azt írják, biztonsági okokból javasolt ellenállásokat használni). A vsys-hez pedig az 5V-t csatlakoztattam.
Ezzel a kóddal kezdtem el játszani vele:

from machine import Pin, PWM
from time import sleep

redPWM = PWM(Pin(1))
greenPWM = PWM(Pin(7))
bluePWM = PWM(Pin(0))

bluePWM.freq(1000)
greenPWM.freq(1000)
redPWM.freq(1000)

def setLEDPercentage(percVal, ledPWM):
fullPWM = 65535
maxVal = int(fullPWM*(100-percVal)/100)
ledPWM.duty_u16(maxVal)
sleep(0.1)

def initLEDPWM(pinNum):
ledPWM = PWM(Pin(pinNum))
ledPWM.freq(1000)
return ledPWM
def turnGreenPercentage(percVal):
greenPWM = initLEDPWM(7)
setLEDPercentage(percVal, greenPWM)

def turnRedPercentage(percVal):
redPWM = initLEDPWM(1)
setLEDPercentage(percVal, redPWM)

def turnBluePercentage(percVal):
bluePWM = initLEDPWM(0)
setLEDPercentage(percVal, bluePWM)

Kiderült, hogy néha akkor is világít a LED, amikor nullára van állítva. Akár úgy is, ha csak digital IO-ként adom meg, és ki-bekapcsolom. Ekkor megnéztem mi van itthon, mivel tudnám ténylegesen kikapcsolni. Találtam egy régi NYÁK-on két darab BC413 tranzisztort, amikkel úgy emlékeztem pont el lehet érni azt, hogy ha a középső lábra kimenő jelet adunk, akkor a két szélső zárja az áramkört, azaz tud folyni az áram. A próba NYÁKhoz raktam, átvezetékeztem, hogy azon menjen át az 5V tápfeszültség, a középső lábát egy másik IO-hoz kapcsoltam. Sima digital output-ként adtam meg, és így már tudtam rendesen fel- és lekapcsolni a fényt.

Aztán a következő turpisság derült ki: fordítva nő, vagy csökken a fényerő, mint, ahogyan a PWM értéket megadnánk! Semmi baj, akkor megfordítjuk. A 0 százalék a 100, a 100 a nulla.

A fejemben összeállt a kép, hogyan kell összehuzalozni az egészet.

Következett a számomra nehezebb rész: kitalálni, mibe rakjam, hogy szereljem fel, honnan kapja a tápfeszültséget.
Maradt kb. fél méternyi RGB LED szalag egy másik - már korábban elkezdett - projektből. Az ajtó keret tetejére pont ráillett, szóval annak az elhelyezésével nem volt gond.
A wc ajtó mellett olyan 2,5 méter magasságban volt egy összekötő doboz. Benne fázis, nulla, föld. A tégla itt vékonyabb, szóval egy sima 8-as fúrószárral (kb 10cm hossz) át tudtam vinni. Itt volt a wc villanykapcsoló is átkötve. Azért, hogy magát a vezérlő eszközt és a tápegységet is áramtalanítani lehessen könnyen a későbbi változtatásokhoz, egy csillárkapcsolót raktam a sima kapcsoló helyére és azzal lehet kapcsolni mindkét fényforráshoz a bemenő ~230V-ot. Volt még itthon bőven 2,5-ös fekte, meg kék MCU vezeték, nosza. Ha már a konnektorokat meg a kapcsolókat én kötöttem be, ez nem volt olyan nagy trükk.

A tápegység egy régi, sima fél amperes USB-s töltő volt, szétszedtem. A NYÁK lapján érdekes módon jelölve volt, hogy a ~230V bemenetnél melyik az 'L' és az 'N'... Ezt elvileg bárhogy be lehetne dugni! Csak furcsa volt nekem. Na mindegy, ha már jelölték, akkor az N-hez forrasztottam a kéket, az L-hez a feketét.

Aztán összeforrasztottam egy forrszemes lapon a dolgokat, vezetékeket, összedugdostam és készítettem egy másfajta, összetettebb programot, immáron circuitpython-ban. (Plusz poén, hogy véletlenül nem egy sima pico-t raktam bele, hanem egy pico w-t, amin van egy wifi+bt chip is.)

A legutóbbi kód:

import board
import digitalio
import pwmio
import asyncio as uasyncio
import os, time, sys, ipaddress, ssl, wifi, socketpool
import adafruit_requests

greenLED_PIN = board.GP11
redLED_PIN = board.GP15
blueLED_PIN = board.GP2
PIR_PIN = board.GP0 # Pin number connected to PIR sensor output wire.
TRA_PIN = board.GP16

# Setup digital input for PIR sensor:
pir = digitalio.DigitalInOut(PIR_PIN)
pir.direction = digitalio.Direction.INPUT

# setup for transistor to turn on/off the 5v output for the LED strip
tra0 = digitalio.DigitalInOut(TRA_PIN)
tra0.direction = digitalio.Direction.OUTPUT

# Setup pwm output for LEDs:
green = pwmio.PWMOut(greenLED_PIN, frequency=1000)
red = pwmio.PWMOut(redLED_PIN, frequency=1000)
blue = pwmio.PWMOut(blueLED_PIN, frequency=1000)

maxPWM = 65535
lightsOn = 200000

def setPercent(val):
c = 1 - val/100
return int(c * maxPWM)

green.duty_cycle = setPercent(0)
blue.duty_cycle = setPercent(0)
red.duty_cycle = setPercent(0)
tra0.value = False

async def dimmUpUntil(ledPWM, val):
percentVal = 1
currentVal = setPercent(percentVal)
while percentVal < val:
#print("increasing led value " + str(currentVal))
ledPWM.duty_cycle = currentVal
percentVal = percentVal*(1+1-int(percentVal*0.01))
currentVal = setPercent(percentVal)
await uasyncio.sleep_ms(50)
currentVal = setPercent(val)
ledPWM.duty_cycle = currentVal

async def dimmDownSlowly(ledPWM, fromVal):
percentVal = fromVal
currentVal = setPercent(percentVal)
while percentVal > 2:
#print("decreasing led value " + str(currentVal))
if pir.value:
return
ledPWM.duty_cycle = currentVal
percentVal = percentVal-2
currentVal = setPercent(percentVal)
await uasyncio.sleep_ms(300)
ledPWM.duty_cycle = setPercent(0)

def connect():
print("Connecting to WiFi")
wifiAP = str(os.getenv('WIFI_SSID'))
print(wifiAP)
wifiPass = str(os.getenv('WIFI_PASSWORD'))
print(wifiPass)

try:
# Connect to the WIFI, use settings.toml to configure SSID and Password
wifi.radio.connect(wifiAP, wifiPass)
print("Connected to WiFi")
except Exception as e:
# Handle connection error
# For this example we will simply print a message and exit the program
print("Failed to connect, adorting.")
print("Error:\n", str(e))
sys.exit()

# Prints your MAC (Media Access Control) address
print("MAC addr:", [hex(i) for i in wifi.radio.mac_address])

# Prints your IP address
print("IP address is", wifi.radio.ipv4_address)
pool = socketpool.SocketPool(wifi.radio)
return adafruit_requests.Session(pool, ssl.create_default_context())

# Main loop that will run forever:
async def main():
requests = connect()
old_value = pir.value
while True:
pir_value = pir.value
if pir_value:
tra0.value = True
# PIR is detecting movement! Turn on LED.
turnOnBlue = uasyncio.create_task(dimmUpUntil(blue, 65))
turnOnRed = uasyncio.create_task(dimmUpUntil(red, 100))
turnOnGreen = uasyncio.create_task(dimmUpUntil(green, 95))
# Check if this is the first time movement was
# detected and print a message!
if not old_value:
try:
resp = requests.get("http://192.168.0.170/cgi-bin/assign.py?wc=activated")
print(str(resp))
resp.close()
except Exception as e:
print("Error:\n", str(e))
print('Motion detected')
print(pir_value)
await uasyncio.gather(turnOnBlue, turnOnRed, turnOnGreen)
await uasyncio.sleep_ms(lightsOn)
#pir_value = pir.value
old_value = pir_value
else:
# Again check if this is the first time movement
# stopped and print a message.
if old_value:
old_value = False
print('Motion ended!')
try:
resp = requests.get("http://192.168.0.170/cgi-bin/assign.py?wc=deactivated")
print(resp)
resp.close()
except Exception as e:
print("Error:\n", str(e))

# PIR is not detecting movement. Turn off LED.
turnOffRed = uasyncio.create_task(dimmDownSlowly(red, 100))
turnOffGreen = uasyncio.create_task(dimmDownSlowly(green, 95))
turnOffBlue = uasyncio.create_task(dimmDownSlowly(blue, 65))
await uasyncio.gather(turnOffRed, turnOffGreen, turnOffBlue)
pir_value = pir.value
if pir_value:
continue
tra0.value = False
print('led has been turned down')

uasyncio.run(main())

És itt most álljunk meg. Nem így nézett ki eredetileg. Nem tartalmazott request-et, és wifi csatlakozást. Tudom is, hogy nem jó a kód, mert ha nem tud csatlakozni, nem lép tovább.
Át kell még írnom, hogy csak egy task legyen a csatlakozás és ne szakítsa meg a fő programot, amennyiben nem sikerül csatlakoznia.

update

Hátra van még:
- kód átalakítása, hogy ne akadjon meg, ha nem tud csatlakozni
- szenzor és vezérlő rögzítése (nehéz ilyen kis csavarokat találnom)
- táp usb kábel átvezetés, hogy be lehessen csukni a dobozt a fedlappal, illetve a szenzor vezetékek lefedése a kábelcsatorna tetejével

bónusz: LED szalag kontakt megjavítása, hogy ne kelljen oda az a klipsz :DDD

Hozzászólások

(#1) saja


saja
tag

Jöhetnek a szörnyülködések.

Micsoda gányolás! Még egy klipsz is kell, hogy legyen biztos kontakt annál a forrasztásmentes LED szalag csatlakozónál! :DDD

[ Szerkesztve ]

keep calm and code erlang

(#2) alcsa válasza saja (#1) üzenetére


alcsa
senior tag

Te jo eg, a szenzort a kondenzatorok szoritjak a kabelcsatornahoz??? :Y :DDD

További hozzászólások megtekintése...
Copyright © 2000-2024 PROHARDVER Informatikai Kft.