| Menu | JAQForum Ver 19.10.27 |
Forum Index : Microcontroller and PC projects : read out carolling christmas bells
I used a “normal” RP2040. These are my settings: The settings are very clear... ;-) Should I increase the CPU speed? So the “111100000000” seems to be normal. Which program should I try next? Thank you very much for your help!!! Frank UPDATE: I have now increased the CPU speed to 252000 and run the same program as yesterday: ' "Port Recorder - 12 pin v03.bas" 'Reading the 12 outputs of a chiming bells ornament. 'It records the time (mS) when any solenoid is activated/released and which sole noids(s) Dim integer n, tmr, Port.now, Too.long=8000 'Length of pause that terminates the program (mS) For n=0 To 11 SetPin MM.Info(pinno "GP"+Str$(n)),DIN Next 'GoTo Remap Open "RecordBells.dat" For Output As #1 Print " Waiting to start" Print "Timer",, "Solenoid", "Interval mS" Timer = 0 Do : Loop Until Port(gp0,12) 'wait for the first pulse Timer = 100 n=0 Do While Timer-tmr < Too.long tmr = Timer Do While (Port(gp0,12) = Port.now) And (Timer-tmr < Too.long+50):Loop 'wait for a solenoid pulse to start/end Pause 25 '<================ Add this and adjust to get all 8 bits at the start of the test Port.now = Port(gp0,12) If (Timer-tmr) < (Too.long-5) Then Print #1, Timer; ",", Port.now Print Timer, Bin$(Port.now,12), Timer-tmr Else Print #1, Timer-Too.long+450; ",", 0 Print Timer-Too.long+450, Bin$(0,12), Timer-tmr EndIf If (Timer-tmr) > (Too.long-19) Then Exit Do Inc n Loop Close #1 Print "Finished - more than ";Too.long;"S since last pulse" Here is the result: RecordBells252000.zip Frank Edited 2025-11-07 23:35 by Frank N. Furter |
||||||
And here is a complete run-through: RecordBellsComplete.zip I recorded a little too much—the first piece was recorded again at the end. Frank |
||||||
|
||||||
Excellent news that it appears to be capturing the data correctly. It would appear the last addition:- Pause 25 '<================ Add this and adjust to get all 8 bits at the start is redundant. The start of the remapped files shows all 12 bells chiming in the correct order so the pause hasn't introduced any obvious errors. 125.416, 3264 260.116, 0 929.699, 1 964.845, 0 1164.546, 2 1199.698, 0 1399.418, 4 1434.585, 0 1634.232, 8 1669.443, 0 1869.089, 16 1904.247, 0 2103.904, 32 2139.098, 0 2338.689, 64 2373.882, 0 2573.526, 128 2628.993, 0 2808.334, 256 2843.517, 0 3043.104, 512 3078.272, 0 3277.901, 1024 3313.078, 0 3512.647, 2048 3547.805, 0 When you get to play the files back listen for any errors and if there are you could either reduce it to Pause 5 (or less) or remove it entirely. Alternatively you could re-record the files with the pause removed and compare the data. As it is 196kB (28.3 min) you may want to write a program to automate the comparison. Edit The longest break between songs is about 5.2 seconds so the recorder time-out (Too.long=8000) could be reduced from 8000mS to 5500, though I guess you don't need the recorder now. Currently playing RemappedALL.dat to make sure it doesn't fail when the data reaches 1.000363306e+06, 2048. Edit 2 All good, it kept on playing. Edit 3 When you build the xylophone version I imagine you will be using different solenoids that might require a different pulse duration. It should be possible to modify the player program to do that. Perhaps automotive relays could be adapted. Glue a flexible arm with a striker on the end to the armature. Edit 4 Player program with adjustable pulse duration (+/- XmS). You may not need it but here it is anyway. ' "Xylophone player v04.bas" Dim integer Bell.note Dim float Bell.time, interval, Pulse.change = -0 'Add to, or subtract from recorded solenoid pulse duration (mS) 'MakeFile 'Sub to create a test file For n=0 To 11 SetPin MM.Info(pinno "GP"+Str$(n)),DOUT Next '*******Add your recorded file name here.************* 'Open "RecordBellsFrank.dat" For Input As #1 'Open "BellTestSample.dat" For Input As #1 Open "RemappedALL.dat" For Input As #1 Print "Input time","Solenoid(s)",,"Output time", "interval" Timer = 0 Do Input #1, Bell.time, Bell.note 'get the data If Bell.note Then Inc Bell.time, -Pulse.change 'adjust pulse duration Do While Timer < Bell.time : Loop 'wait for next note or pulse Port(gp0,12) = Bell.note 'start / end solenoid pulse Print Bell.time, Bin$(Bell.note,12),, Timer, Bell.time-interval', interval = Bell.time Loop Until Eof(#1) Port(gp0,12) = 0 'ensure all solenoids are off at the end. End Sub MakeFile Local float SPD=35 'solenoid pulse duration (mS) Local integer n, Steps=40 'number of on/off transitions in the sequence Open "BellTestSample.dat" For Output As #1 For n=0 To Steps\2 Inc Bell.time, (Rnd * 1400 + 100) 'random intervals from 100 to 1500mS Bell.note = (1 << Fix(Rnd * 12)) Or (1 << Fix(Rnd * 12)) ' ring 2 random bells Print #1, Bell.time;","; Bell.note 'solenoid pulse start Print Bell.time, Bin$(Bell.note,12) Print #1, Bell.time+SPD;","; 0 'solenoid pulse end Print Bell.time+SPD, Bin$(0,12) Next Pause SPD Print #1, Bell.time+SPD;","; 0 'final solenoid pulse end Print Bell.time+SPD, Bin$(0,12) Close #1 End Sub Changing the solenoid pulse duration does not affect the interval between notes. Edited 2025-11-08 14:18 by phil99 |
||||||
Yesterday, I revised the .dat file and created a (poorly programmed) player. It sounds awful, the frequencies are off (I also shifted them up an octave). Nevertheless, you can still recognize the pieces! ![]() I don't think the exact milliseconds are that critical, so I rounded the values. I have attached the result. The path must be adjusted, of course. I saved it on the SD card under “Bells.” music.dat.zip Next, I will try to determine the frequencies of the bells. Frank P.S.: Zaehler means Counter Edited 2025-11-08 19:22 by Frank N. Furter |
||||||
Next, I'll adjust the frequencies according to the great link from Volhout (C5, D, E, F, F#, G, A, B, C6, D, E, F) - let's see how it sounds then... Unfortunately, I probably won't be able to use my beautiful xylophone... Frank |
||||||
Hi Frank, Nice project. It (Music.dat) sounds terrible, but it's recognizable as "Rudolph the Red-Nosed Reindeer" (AFAIK). Regards Michael |
||||||
Yes, you're right! I'm curious to see if it sounds better when I adjust the frequencies. Frank |
||||||
I listened to this: https://www.sheetmusicdirect.com/de-DE/se/ID_No/525881/Product.aspx? This is how I imagine it could sound. I also extracted the notes from a MIDI file... Maybe that will help. Finally, I created a WAV file (with Pico) as a basis for experiments, since I don't have any bells or a glockenspiel. gong2.zip The fundamental frequency is 1046.5 Hz (C6). This can then be used to feed the new "PLAY ARRAY" command ... |
||||||
NPHighview is absolutely right! A simple C major is not enough. Yesterday, I tried the following frequencies: C5 523.3 D5 587.3 E5 659.3 F5 698.5 F#5 740 G5 784 A5 880 B5 987.8 C6 1046.5 D6 1147.61 E6 1318.5 F6 1397 Michael, your frequency is there too! A big THANK YOU to Volhout - I got the frequencies from your GitHub link. It sounds very much better, but it's still not quite right! Something seems to be wrong, especially with the higher notes... ![]() I absolutely have to determine the frequencies of the bells somehow. Could a small speaker function as a microphone on an oscilloscope? Frank |
||||||
Hi Frank (Assuming I understand the problem) I think one of those is wrong. Try D6 = 1174.66 Each semitone up should increase by a factor 2^(1/12)...since Bach. Regards Phil |
||||||
Hi Phil. Damn! That was a typo! I had used a frequency of 1174.61 for D6... Thank you very much for your comment anyway! Frank |
||||||
That's correct, but to be more precise: In the currently common "equal temperament" tuning, an octave (factor of 2) is divided into 12 equal steps: Factor per semitone = 2^(1/12) ≈ 1.05946 This results in these semitones: C – C# – D – D# – E – F – F# – G – G# – A – A# – B -> Each step sounds equally "far" apart, regardless of the key. This means that, for example, for Play Array you only need one frequency to play an octave. For example, by changing the factor. It seems important to me to adjust the volume simultaneously. An example from my test program: Dim float ii=1 Dim integer mvol=28 Do Print ii,ii*Freq1a/Pi2 Play volume mvol,mvol Play array packed%(),packed%(),Play_Freq*ii Do :Loop Until MM.Info(sound)="OFF" ii = ii * 2^(1/12) Inc mvol,4 Loop Until ii >2.68 Do :Loop While Inkey$="" Glocke01.zip Regarding the determination of the frequencies (my idea on the subject): As already mentioned at the beginning of this thread, I would have sampled the bell tones - e.g., with a smartphone - and converted them to mp3. Then I would have had an audio editor program analyze them (FFT analysis). This is quite easy with bell tones, as they have a typical waveform. Regards Michael |
||||||
Hi Michael, If I manage to create an MP3 file of the bells tomorrow, would you help me analyze it? I tried it yesterday with a microphone and my oscilloscope. The result could be correct for the higher bells. However, the lower the bells become, the more difficult it was to read anything from the curves. Frank |
||||||
Have you looked for a frequency analyzer for your smart phone. There are plenty to choose from for Android. Most will give frequency and note. You might have to try a few to get one that reads short duration notes reliably. Jim |
||||||
@TassyJim: My first problem with this is that I don't have a smartphone or an account with this data hog... Frank |
||||||
Yes, of course. Do you already have the MP3? How do you plan to upload it? Should Pico do the analysis? I'd like to take a look at the MP3 first. Kind regards Michael |
||||||
Frank, This is how I would approach it. There are only 12 bells, so there are 12 different frequencies (tones) and thus notes. The bells will not be "calibrated" (it is a toy), but should come close to 12 different frequecies in this table. ![]() Sound 1 bell (short short ULN2003 output to GND). on any musical instrument, find the note it resembles. -or- in the pico: OPTION AUDIO gpx,gpy with a 220 ohm series resistor from gpx, and after that a 100nF to ground, connect to a headset/speaker/amplifier. PLAY TONE 1175,1175 (to test for a D note in octave 6).Find the note is resembles by trying different frequencies. Repeat this for every bell, and you have the translation table (both frequency, and note). With a bit of effort you are done in 30 minutes. You can also write a program that scans through all the frequencies in above overview so you can use up and down keys to the next value. That works even faster. But you need to write a program. These bells are small, so I expect the frequencies to be in octave 5,6,7. Don't worry about the lower octaves. Volhout Edited 2025-11-12 22:29 by Volhout |
||||||
@Volout: Thank you very much for your table. That's my plan "B"! ![]() @twofingers: Michael, I have recorded 3 WAV files and attached them. REC000.WAV.zip Thanks so much to both of you! Frank |
||||||
![]() Time in seconds and frequency in Hz. I would draw gridlines for frequency to make reading the frequency easier. Thats a start Edited 2025-11-13 07:15 by TassyJim |
||||||
| The Back Shed's forum code is written, and hosted, in Australia. |