piano trouble

Questions and discussion about running MicroPython on a micro:bit board.
Target audience: MicroPython users with a micro:bit.
Post Reply
DPaul
Posts: 10
Joined: Tue Mar 05, 2019 3:47 pm

piano trouble

Post by DPaul » Thu Dec 05, 2019 8:20 am

Hi,

I am testing a one - note piano with a pushbutton on the microbit.
The digital reading is "1" in normal state, and "0" when the button is pressed. (signal goes to GND)
The the note is produced. So far so good.
My question:
The note keeps on sounding even after i release the button .
I expected that with the circuit open again, the reading would return to "1".
I am unsure if i should digital_write(1) myself or is something else wrong ?

Code: Select all

from microbit import *
import music
pinTest = pin1
while True:
    sleep(2000)
    x = pinTest.read_digital()
    display.show(x)
    if x == 0:
        music.play('a')
    sleep(1000)
    pinTest.write_digital(1)  #  <<< WHY ?
    display.show('?')
[\code]

Thanks,
Paul

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: piano trouble

Post by OutoftheBOTS_ » Thu Dec 05, 2019 9:11 am

I see that when the pin = 0 then it plays the music but I can't anywhere in your code you turn the music off.

Code: Select all

    if x == 0:
        music.play('a')
    else:
    	#code goes here to turn music off

DPaul
Posts: 10
Joined: Tue Mar 05, 2019 3:47 pm

Re: piano trouble

Post by DPaul » Thu Dec 05, 2019 9:42 am

Thanks,

I now tested multiple music.stop() configurations, and it may certainly have somethingto do with it.

But i also have a 7 push-button version, where music.stop() does not work so well.
It almost seems that when you press one of the buttons, some current is randomly triggering one or 2
others, playing their notes.

Is it a de-bouncing problem? I inserted all sorts of sleep(...) but to no avail.
That is why is started the one-note program, thinking if it works with one, it ... but no :-(

DPaul

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: piano trouble

Post by jimmo » Fri Dec 06, 2019 3:26 am

Hi,

You shouldn't need music.stop, as music.play just plays the specified sequency then stops automatically. (You can use loop=True if you want it to keep playing).

Can you describe the circuit how the buttons are connected? I suspect you might need pull-up resistors? Also you definitely shouldn't need to write_digital to the pin. That could potentially cause issues if the button is currently pressed and it will short the output to ground.

The circuit you need is that the pin should only be read from (i.e. only use read_digital, which keeps it in input mode), and connected with a resistor to the 3V pin. Then the button also connects it to ground.

Also, the sleeps are likely to cause problems down the track. Try and avoid using sleep() at all wherever possible in your micro:bit programs. see viewtopic.php?f=17&t=7150&p=40706 for more info.

DPaul
Posts: 10
Joined: Tue Mar 05, 2019 3:47 pm

Re: piano trouble

Post by DPaul » Fri Dec 06, 2019 7:41 am

Thanks Jimmo,

a) Agreed, Music.stop() should not be necessary. lengths of notes are driven via parameters.
b) Write_digital(1) not necessary: i thought not, that is the reason i asked. (i'll take it away)

c) pullup/pulldown resistor:
The push buttons are connected to:
One leg to : pinX (1,2,8,13,14,15,16) and also ->10k resistor -> 3.3 volts
Other leg to: GND

On pin0 and GND , i have the speaker. Music defaults to pin0, it seems.

I visited many sites to come up with this setup. But strangely i cannot find any micropython script
that handles more than 2 buttons (not A and B) for a diy piano. Like it's too difficult ? :(

The simple idea is that when you push a button, it plays the associated note. Next, we play a tune. That's the project :o

Dpaul

lujo
Posts: 24
Joined: Sat May 11, 2019 2:30 pm

Re: piano trouble

Post by lujo » Fri Dec 06, 2019 8:25 am

Hi,

Here is a minimal script that handles an extra 12 buttons. Google 3x4 keypad schematics.
This is one way to scan a keypad. Adapt for piano keys.

Code: Select all

from microbit import *

cols = pin0, pin1, pin2
rows = pin8, pin12, pin14, pin16

keys = (
  ('*', '0', '#'),
  ('7', '8', '9'),
  ('4', '5', '6'),
  ('1', '2', '3'),
)

for pin in rows + cols:
    pin.write_digital(0)

while True:
    for r, row in enumerate(rows):
        row.write_digital(1)
        for c, col in enumerate(cols):
            if col.read_digital():
                key = keys[r][c]
                display.show(key, delay=100, clear=True)
        row.write_digital(0)
lujo

DPaul
Posts: 10
Joined: Tue Mar 05, 2019 3:47 pm

Re: piano trouble

Post by DPaul » Fri Dec 06, 2019 8:57 am

Thanks lujo,

Will try this immediately.
I see a big difference right away, might be the solution ... :D

Paul

DPaul
Posts: 10
Joined: Tue Mar 05, 2019 3:47 pm

Re: piano trouble

Post by DPaul » Fri Dec 06, 2019 9:35 am

Hi,

I have taken into acount all the remarks, and changed 2 things. As far as i can tell, it works ! :o
1) i got inspired by the cols and rows to turn the program around, writing digital zero instead of 1
2) i changed the hardware config, now the leg with the 10k resistor goes to GND, the other to VCC, when the circuit closes.
This is the program:

Code: Select all

from microbit import *
import music

noteC = pin1
noteD = pin2
noteE = pin8
noteF = pin13
noteG = pin14
noteA = pin15
noteB = pin16

notes = [noteC, noteD, noteE, noteF, noteG, noteA, noteB]

for pin in notes:
    pin.write_digital(0)

while True:
    if noteC.read_digital() == 1:
        music.play('c')
        noteC.write_digital(0)
    if noteD.read_digital() == 1:
        music.play('d')
        noteD.write_digital(0)
    if noteE.read_digital() == 1:
        music.play('e')
        noteE.write_digital(0)
    if noteF.read_digital() == 1:
        music.play('f')
        noteF.write_digital(0)
    if noteG.read_digital() == 1:
        music.play('g')
        noteG.write_digital(0)
    if noteA.read_digital() == 1:
        music.play('a')
        noteA.write_digital(0)
    if noteB.read_digital() == 1:
        music.play('b')
        noteB.write_digital(0)
    sleep(20)

Paul

Post Reply