I was having a play with the ATtiny85 device to impersonate a microdrive sound posted a while back by Stephen Usher. No real reason, I just found it interesting and wanted to hear what it sounded like. Unfortunately, no sound! Turns out my only 8 ohm speaker, salvaged from something some time back, was deader than a dead thing. That's now in the electrical pile for recycling.
Even with PWM on the outputs, I suspected that there would be too much voltage to feed the signal into a small amp's line-in, which I think needs 1V peak to peak, so I connected the two channels on my "Espotek Labrador" toy oscilloscope to the output pins, plus ground, and was able to see the waveforms on the two PWM pins PB1 and PB4.
I then had a play with the source code to see what could be done to reduce the amount of flash used. again, just for fun but maybe to allow for a bigger/better(?) waveform. Anyway, coming from a ZX81 background, making things as small as possible, while still being readable is a bit of a hobby! (I haven't gone to assembly yet!)
The original, when compiled in Arduino IDE 1.8.13 resulted in 3,248 Flash bytes and 11 Static RAM bytes.
The attached Arduino sketch (see below) saved 314 Flash bytes and 9 Static bytes, plus, looking at the waveform on the scope,
looks a lot smoother -- which might be a good thing, maybe not! As I mentioned, I've not been able to hear the original or the attached version. It could be complete garbage for all I know.
Basically, what I did was:
- Removed the "avr/sleep.h" header. Sleeping isn't used.
- Removed the call to "set_sleep_mode()". Sleeping isn't used.
- Removed "adc_disable" macro as it wasn't used either.
- Added "stdint.h" header to allow non-Arduino IDE compilations.
- Added "avr/interrupt.h" header to allow non-Arduino IDE compilations.
This took things down to 3,240 Flash + 11 Static bytes.
- Changed "pinMode()" calls to setting the DDRB register directly.
This took things down to 3,136 Flash + 11 Static bytes.
- Removed global variable "P" and made it static in the ISR.
- Removed global variable "mdvsnd_wav_len", as it is hard coding!
- Added "sizeof(mdvsnd_wav)" in the ISR to check for the end of audio data. The compiler will work out the value required and plug it into the code at compile time.
- Converted "setup()" and "loop()" to "main()", no Arduino dependencies now.
- Added call to "sei()" to enable interrupts for non-Arduino IDE compilations.
This took everything down to 2,934 Flash + 2 Static bytes, a saving of 314 Flash and 9 Static bytes.
So that was my distraction for this morning! Keeping me away from doing the things I really should be doing!
This code, when renamed to "vdriveSound_2.cpp", from "vdriveSound_2.ino" compiles quite happily under PlatformIO.
One question for anyone in the know, I'm no good with graphics or audio stuff, for some reason I can't get my head around it. This code baffles me:
Code: Select all
OCR1A = sample;
OCR1B = sample ^ 255;
It's in the ISR and I know
what it does, I just don't know
why it does it. Can anyone give me a clue please? Thanks.
Take care & stay safe.
The attachment is an Arduino sketch but for PlatformIO users like me, the "ino" file can be copied out, renamed to "cpp" and used in a PlatformIO project as-is. You can create a new project with:
Code: Select all
mkdir vDriveSound
cd vDriveSound
pio init -b attiny85
# Edit "platformio.ini" and remove the "framework=arduino" line.
# Add in your programmer, mine is "upload_protocol=usbtiny"
Then compile with "pio run" and upload with "pio run -t upload".
Easy!
Cheers,
Norm.