mathiasvr / bluejay

:bird: Digital ESC firmware for controlling brushless motors in multirotors
GNU General Public License v3.0
487 stars 51 forks source link

Custom beep melodies #3

Closed Quick-Flash closed 3 years ago

Quick-Flash commented 3 years ago

while using the motor beeper functionality, i realized how fun it would be to have the motor beeper actually play music instead of just a single tone.

mathiasvr commented 3 years ago

There has been some interest in custom startup melodies so let's try to do this too. It might be some time before I get to this unless someone pitches in.

Quick-Flash commented 3 years ago

I sadly have 0 understanding of assembly code. I might take a look and see if I could figure out anything easy as a quick test.

mathiasvr commented 3 years ago

Yeah, it really hinders "BLHeli_S" contributions in general. If you or anyone else should dare to take a stab at it, I recommend only adding code after the bootloader check:

https://github.com/mathiasvr/bluejay/blob/06787cc146cee625661366de252e5e328d08986e/Bluejay.asm#L3571

The startup beeps are located before this, but if something goes wrong there it can become very difficult to flash the ESC.

saidinesh5 commented 3 years ago

@mathiasvr One good news is with bluejay stripping out older protocols freed up more space for this feature on these really really space constrained MCUs, I think we can implement this in ~200-500 bytes...

The bluejay firmware with a test tone (not working well yet.. ) weighs 14974 bytes The same little melody on BLHeli_M weighs 15349 bytes.

I haven't touched assembly programming much yet, but I think we should be able to implement this feature in about 200-300 bytes of flash for a 50 note melody.

Is there any way to (add support for) setting strings/byte arrays as EEP ROM variables from the configurator?

For eg.

;Eep_StartupTuneTempo:          DB  96
;Eep_StartupTuneMelody:         DB "--------------------------------------------------------------------------------------------------------------------------------"

And have a section in the code just loop through that array picking up tuples of (note length, note) or triples of (note length, note, octave) and playing it blindly?

Right now, the edit beep functions, make the calls to those functions, compile and flash the firmware cycle is a little too time consuming. Plus that also wastes more storage.

Also can you explain how you arrived at the Temp3, Temp4 variable values for various beep notes? I was planning on writing a little loop to cycle through Temp3, Temp4 variable values in subroutines to find out the values we need for various notes, but if we can find a little formula, that should speed things up more..

Would love to take a look at this next weekend

mathiasvr commented 3 years ago

@mathiasvr One good news is with bluejay stripping out older protocols freed up more space for this feature on these really really space constrained MCUs, I think we can implement this in ~200-500 bytes...

The bluejay firmware with a test tone (not working well yet.. ) weighs 14974 bytes The same little melody on BLHeli_M weighs 15349 bytes.

I think you may be referring to the size of the intel hex files? This is actually an ascii encoding of the binary. The program data currently takes up around ~5200 bytes so there should be plenty of space left on both BB1 8kb and BB2 16kb.

I haven't touched assembly programming much yet, but I think we should be able to implement this feature in about 200-300 bytes of flash for a 50 note melody.

Is there any way to (add support for) setting strings/byte arrays as EEP ROM variables from the configurator?

For eg.

;Eep_StartupTuneTempo:            DB  96
;Eep_StartupTuneMelody:           DB "--------------------------------------------------------------------------------------------------------------------------------"

And have a section in the code just loop through that array picking up tuples of (note length, note) or triples of (note length, note, octave) and playing it blindly?

I have not looked into extending the "EEPROM" space but I don't think this should be a big problem. We could also reserve an area of space to allow 'flashing' the melody.

Right now, the edit beep functions, make the calls to those functions, compile and flash the firmware cycle is a little too time consuming. Plus that also wastes more storage.

I'm not quite sure which functions you are referring to here?

Also can you explain how you arrived at the Temp3, Temp4 variable values for various beep notes? I was planning on writing a little loop to cycle through Temp3, Temp4 variable values in subroutines to find out the values we need for various notes, but if we can find a little formula, that should speed things up more..

Temp3 is the length of the beep period, so a higher value is lower frequency and vice versa. Temp4 is the number of pulses, so this needs to be adjusted to have the same beep duration for different frequencies. I currently use 3500 / Temp3 where 3500 is used to adjust beep duration for all frequencies.

Would love to take a look at this next weekend

Sound great! 😃

saidinesh5 commented 3 years ago

I was able to hardcode the current startup tune into:

Eep_Name:                   DB  "Bluejay (BETA)  "          ; Name tag (16 Bytes)
Eep_Pgm_Startup_Tune:       DB  66,53,5,1,45,77,5,1,66,53,5,1,38,92,200,1,45,77,25,140,25,140,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; EEPROM copy of startup tune

The idea is to make this writable via. Bluejay configurator and make the configurator do the heavy lifting of converting musical notes, duration into this array (Still looking up how to do that).

And then the loop will blindly play all those notes:


startup_beep_melody:
    mov Temp1,  #32h ; Startup tone has 100 items of (pulse length, number of pulses). So we need to loop this for 50 times
    mov DPTR,   #Eep_Pgm_Startup_Tune
startup_melody_loop:
    ; Read location at Eep_Pgm_Startup_Tune Temp1 to Temp3
    clr A
    movc    A,  @A+DPTR
    mov Temp3,  A
    inc DPTR
    ; Read location at Eep_Pgm_Startup_Tune Temp1 to Temp4
    clr A
    movc    A,  @A+DPTR
    mov Temp4,  A
    inc DPTR
        ; Todo: Find out a way to encode "empty notes"
    call beep
startup_melody_loop_next_note:
    djnz    Temp1, startup_melody_loop

Now, the Good news is that it plays the tune when powered up.

The bad news is that this bricked the ESC somehow. The thing it isn't even getting recognized by blheli suite/blheli configurator. I suspect the 0 duration pulses somehow tripped something somewhere. But isn't that what the bootloader on this thing is for?

Fortunately, i have 2 more ESCs to brick on this crazybee f4 board (with a burned out fet. But I'd like to fix the bricked ESC first if i can. Because, pretty sure i will make more mistakes while trying to finish this task, and would like to know how to recover. like short some pins and get the bootloader uart working etc.. Any easy tips on that? My current option is go out and buy an Arduino to make a BB21 programmer, but would like to avoid it if i can. The pins on this QFN20 package are too tiny and I don't have the skill/equipment to solder wires to that (yet). There are some unnamed larger pads next to these pins too ( http://www.happymodel.cn/wp-content/uploads/2019/05/Crazybee-F4-FR-Pro-v2.1-Connection-Diagram.pdf ), would I be able to force the bootloader into uart mode if i bridge some pins someway?

The pad next to pin 6 (C2 Debug Data) is connected to pin 6 I think. At least based on the multimeter continuity test.

mathiasvr commented 3 years ago

@saidinesh5 If you can share the code you are working on I can try to take a look so we can hopefully avoid future bricking.

I think the uart bootloader is not present on blheli_s escs so you have to use the C2 interface to unbrick it. It might be easier with an Arduino but I have used an esp8266 before, probably other MCUs could be used as well.

saidinesh5 commented 3 years ago

@mathiasvr Oh i totally forgot i have an ESP32.. Can you share your ESP firmware/code so i can flash mine too?

Also my code is really all that i shared in the above comment lol. https://github.com/mathiasvr/bluejay/pull/8 (DO NOT MERGE THIS YET)

mathiasvr commented 3 years ago

https://github.com/lhartmann/c2_prog_wifi is the best C2 for esp I’ve seen.

mathiasvr commented 3 years ago

I see your code runs before the bootloader check, which could be why you have problems. I recommend placing the code after the bootloader_done label during development. You can comment out the normal startup beeps if you like.

saidinesh5 commented 3 years ago

Thank you, looking into it. And yeah before the audio plays, we explicitly disable interrupts. I suspect that's what making this ESC look dead to the configurator

mathiasvr commented 3 years ago

Tracking the remaining beacon melody request here: #19.