My music code will upload but doesn't run (Adafruit ESP32 Feather)

I have a project that I’m working on that runs two speakers at once to play a tune and has an rgb led change color with the pitch. All of that works fine and I have a short piece that it can play. So essentially the music is coded in arrays. One array controls the beats/rhythm. The other two are given pitch values to run off of. Everything works well. But, when I try to use a longer piece nothing happens.

The attached file is the one with the longer music that won’t run. The only difference between it and the code that works is the size of the three arrays (rhythm1, melody1, melody2).

The code that is currently running uses only the first 15 or so lines of those arrays.

I don’t believe the program is using up too much memory or RAM but I’m not really sure what the issue is. I’m pretty new to this and would really appreciate any help.

This is what displays in the console window:

Sketch uses 210036 bytes (16%) of program storage space. Maximum is 1310720 bytes.
Global variables use 15396 bytes (4%) of dynamic memory, leaving 312284 bytes for local variables. Maximum is 327680 bytes.
esptool.py v2.6
Serial port COM5
Connecting…
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 80:7d:3a:bc:bb:14
Uploading stub…
Running stub…
Stub running…
Changing baud rate to 921600
Changed.
Configuring flash size…
Auto-detected Flash size: 4MB
Compressed 8192 bytes to 47…

Writing at 0x0000e000… (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 21845.2 kbit/s)…
Hash of data verified.
Compressed 15328 bytes to 9994…

Writing at 0x00001000… (100 %)
Wrote 15328 bytes (9994 compressed) at 0x00001000 in 0.1 seconds (effective 922.0 kbit/s)…
Hash of data verified.
Compressed 210144 bytes to 107542…

Writing at 0x00010000… (14 %)
Writing at 0x00014000… (28 %)
Writing at 0x00018000… (42 %)
Writing at 0x0001c000… (57 %)
Writing at 0x00020000… (71 %)
Writing at 0x00024000… (85 %)
Writing at 0x00028000… (100 %)
Wrote 210144 bytes (107542 compressed) at 0x00010000 in 1.7 seconds (effective 980.8 kbit/s)…
Hash of data verified.
Compressed 3072 bytes to 144…

Writing at 0x00008000… (100 %)
Wrote 3072 bytes (144 compressed) at 0x00008000 in 0.0 seconds (effective 3072.0 kbit/s)…
Hash of data verified.

Leaving…
Hard resetting via RTS pin…

8Bit_Vivaldi_fullfirstmovt.ino (22.2 KB)

Just my 2 cents... This forum is for Arduino products, so i doubt that you'll receive much help for ESP32, and since it's an Adafruit product, you should probably consider posting on their forums. :slight_smile:

I don't think there's anything specific to AdaFruit in the code. The board is being used as an "Arduino". You might just as well as the question here, on the AdaFruit forum or on the Arduino ESP8266/32 forum.

Just skimmed through your code and have an idea what the problem might be. All the code is setup() and loop() is empty. There is no use of delay() (only delayMicroseconds()) or yield() so I wonder if one of the watchdogs (hardware or software) is preventing the longer tune from completing. My theory is based on my own use of esp8266 boards, but I've never used an esp32, so not 100% sure they are similar in this respect. If the watchdog is preventing the longer tune running, you should see error messages on the serial monitor.

Other comments on the code: is there not a built-in tone() function you can use rather than coding your own loops to produce the note? The standard Arduino tone() function on Uno can only play one note at a time because it relies on a hardware timer. But on esp, it may be done in software, making several simultaneous notes possible.

Secondly, there's a "gotcha" in writing formulae in C that you should be aware of. If you write, for example

float x = 1 / 2;

Then x does not come out as 0.5 as you might expect from familiarity with other languages such as BASIC. In C you get (in this example) zero, because when you divide an integer by another integer (1 and 2 are both integers), C performs integer division. To force C to do real/float division, you need to write

float x = 1.0 / 2;

This works because of either number is a float, C performs float division. "1.0" is obviously intended to be a float, not an integer.

There is a tone function on esp32. It’s called ledcWriteNote().

Found your problem:

  for (byte k = 0; k < melodylength; k++)

This only works for melody lengths up to 255. Your melody is 1012 notes and ‘k’ can never be higher than 255. Change it to a larger size.

It’s interesting to note that the compiler did NOT give me this warning:

/Users/john/Documents/Arduino/sketch_oct12a/sketch_oct12a.ino: In function 'void setup()':
/Users/john/Documents/Arduino/sketch_oct12a/sketch_oct12a.ino:432:22: warning: comparison is always true due to limited range of data type [-Wtype-limits]
   for (byte k = 0; k < melodylength; k++)
                    ~~^~~~~~~~~~~~~~

until I changed

  int melodylength = (sizeof(melody1) / sizeof(melody1[0]));

to

  const int melodylength = (sizeof(melody1) / sizeof(melody1[0]));

Good spot, John. I looked for a problem like that, involving a byte/uint_8t/char, it was my first thought, but I didn't spot it!

warning: comparison is always true

But why? A byte variable can contain a number like 100 and an int can contain a smaller number like 50. So what does the compiler mean by that, and why would making it a const make any difference?

PaulRB:
But why? A byte variable can contain a number like 100 and an int can contain a smaller number like 50. So what does the compiler mean by that, and why would making it a const make any difference?

Yes, an 'int' can contain a value that is smaller than a 'byte', but when melodylength is declared 'const int' the compiler knows it will always be 1012 which is always greater than any value you can put in a byte. I'm just surprised that the compiler didn't notice that 'melodylength' was initialized to 1012 and never changed. It would have been better if the compiler had marked the value as a compile-time constant and give the warning.

Thank you so much all the help everyone. John, your correction worked. Seems like a silly mistake on my part in hindsight. Again, thanks all!

Got it, thanks John.