Teknik 1 · område 1 · pass 4 · utmaning
Ljus-theremin
En theremin är ett instrument man spelar utan att röra det. Er version: ljussensorn styr buzzerns tonhöjd. Handen upp och ner över sensorn ändrar tonen. Knappen tystar.
1. Uppgiften
Ljuset in. Tonen ut. Knappen tystar. Allt du behöver sitter redan på breadboarden sedan förmiddagen: knappen på GP14, ljussensorn på GP26, buzzern på GP16.
Det nya är en enda rad: den som gör om sensorns tal till en frekvens.
2. Omräkningen
Sensorn ger ett tal mellan 0 och 65535. Buzzern vill ha en frekvens, säg mellan 200 och 2000 Hz. Det lägsta talet ska bli den lägsta tonen, det högsta talet den högsta, och allt däremellan ska hamna däremellan.
frekvens = 200 + varde * 1800 // 65535
Räkna själv innan du skriver in den:
- Vad blir
frekvensomvardeär 0? - Vad blir den om
vardeär 65535? - Varför står det 1800 och inte 2000?
// är heltalsdivision – resultatet blir ett heltal, och det är vad
freq() vill ha. Men varde // 65535 blir nästan alltid 0
(vad är 30000 delat med 65535, utan decimaler?). Därför multipliceras det
först, sedan delas det.
3. Startskelettet
Ny fil theremin.py. Det här är början – loopen är tom, och den skriver
ni själva.
from machine import ADC, Pin, PWM
from time import sleep
ljus = ADC(26)
knapp = Pin(14, Pin.IN, Pin.PULL_UP)
ton = PWM(Pin(16))
while True:
# 1. läs sensorn till en variabel
# 2. räkna om till frekvens
# 3. om knappen är nedtryckt: tyst
# annars: sätt frekvensen och slå på ljudet
sleep(0.02)
Kommentarerna (raderna med #) är planen. Skriv en rad kod under varje.
Allt du behöver har du använt i förmiddags: read_u16(),
knapp.value(), freq(), duty_u16(), if
och else.
4. Nivåerna
Ska — nivå E
Bör — nivå C
Utmaning — nivå A
Kryssen sparas i din webbläsare.
5. Felsökning
6 rader
| Symptom | Trolig orsak | Åtgärd |
|---|---|---|
| Alltid samma ton | varde // 65535 blir 0 – delat innan multiplicerat | Multiplicera först: varde * 1800 // 65535 |
Röd text: TypeError på freq() | Ett decimaltal skickas in – / i stället för // | Använd //, eller int(...) runt uttrycket |
| Tonen hackar | sleep för lång | 0.02 räcker. Frekvensen byts varje varv i loopen |
| Knappen tystar inte | if knapp.value() == 1 | Nedtryckt är 0. Samma regel som i förmiddags |
| Tyst för alltid efter första trycket | duty_u16(0) sätts men aldrig tillbaka | duty_u16(30000) i else-grenen, varje varv |
| Ingen ton alls | Aktiv piezo i stället för passiv | Byt till modulen utan vit lapp |