8-bit sound sampling with arduino

Good morning everyone.

A friend of mine and I have a little problem. We are trying to connect an Arduino Mega 2560 with an electric dartboard and play different 8 bit audio samples depending on which field is hit.

We have already connected the Arduino to the dart boards 8x8 matrix and were able to get the output we wanted.

Then we seperately tried to program the audio samples. For this we used this guide: Arduino audio sampling tutorial (part 1) - YouTube

and it works (we have changed the code for our purposes).

Our problem now is, that as soon as we implement a 3rd audio sample, the program starts to behave weird (even though "only" 30% of the program memory is used).´

The sounds are constantly played without us pressing the button and the sounds are also played in a strange order (something like 1 - 3 - 2 - 3 - 3 - 1 - 3 - 2 - 3 - 3 - 1...) with some distortion noises.

Source Code:

short buttonPin = 53;
short i = 0;  //Counter for the length of the Sounds
int y = 0;  //Switch case for different sounds
short z = 0;  //Variable for Button (1 or 0)


void setup() 
{
  pinMode(buttonPin, INPUT);
  DDRC = 255;
}

void loop() 

  if(digitalRead(buttonPin) == HIGH && y == 0){
    z = 1;
  } //If button is pressed sound 1 (hall) will be played because the while loop will be true
  
  while(z == 1 && y == 0){
      PORTC = pgm_read_byte(&(hall[i++]));
      if(i >= sizeof(hall)){
        i = 0;
        y = 1;
        z = 0;
      }
      delayMicroseconds(62);
  } //Loop for the sound 1 (hall) to be played

  if(digitalRead(buttonPin) == HIGH && y == 1){
    z = 1;
  } //If button is pressed sound 2 (craftUH) will be played because the while loop will be true
  
  while(z == 1 && y == 1){
      PORTC = pgm_read_byte(&(craftUH[i++]));
      if(i >= sizeof(craftUH)){
        i = 0;
        y = 2;
        z = 0;
      }
      delayMicroseconds(62);
  } //Loop for the sound 2 (craftUH) to be played

  if(digitalRead(buttonPin) == HIGH && y == 2){
    z = 1;
  } //If button is pressed sound 3 (err) will be played because the while loop will be true
  
  while(z == 1 && y == 2){
      PORTC = pgm_read_byte(&(err[i++]));
      if(i >= sizeof(err)){
        i = 0;
        y = 0;
        z = 0;
      }
      delayMicroseconds(62);
  } //Loop for the sound 3 (err) to be played
}

The sounds (hall, craftUH and err are declared above the whole program like this:

const unsigned char hall[28561] PROGMEM =
{
  //some hex code
}

but its 5k lines of hex code, so i dont wanna upload that here)

The funny thing is, that if we simply change "err" in the last while loop to either "hall" or "craftUH" the program will only use 23% of Program memory because the const unsigned char err wont be uploaded since its not called in the program. After this everything works fine. The sounds are being played in the order we wanted (1 - 2 - 3 - 1 - 2 - 3 - 1 - 2 -....)
Also it doesnt matter which sound we replace with another as long as we only use 2 different sounds it works in any order.

We try these different cases with one button in order to be able to play different sounds if different parts of the dart board are hit later on. We will then merge our two codes but we are not at this point of the project yet.

If you miss something please just ask for it and i will try my best to give you those information.

I can also upload picture of the curcuit we use later today.

Thank you in advance for your time and your help!

Greetings from Germany

Shokker

The Mega has 128k of Flash, but I think you can only address 64k at a time in that architecture
(vague memory of this from long ago) - I think its something like pointers are 16 bit in the C compiler.

There's probably a workaround for this.

I also noticed this in setup:

  pinMode(buttonPin, INPUT);

Are you using an external pulldown resistor for buttonPin?

Normally you'd be using INPUT_PULLUP and connect the button to ground, saving a resistor and
inverting the logic.

Hi MarkT,

MarkT:
The Mega has 128k of Flash, but I think you can only address 64k at a time in that architecture
(vague memory of this from long ago) - I think its something like pointers are 16 bit in the C compiler.

the compiler actually says this:

Der Sketch verwendet 76112 Bytes (29%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 15 Bytes (0%) des dynamischen Speichers, 8177 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.

In English:

The Sketch uses 76112 bytes (29%) of program memory. The maximum is 253952 bytes.
Global variables use 15 bytes (0%) of dynamic memory, 8177 bytes for local variables remain. The maximum is 8192 bytes.

So in fact, if you talk about 64k BIT at a time, you probably mean the dynamic memory? (8192 bytes = 65.536 bit)
But I actually store the hex sounds, which need a lot of mem, in the program memory (PROGMEM).

MarkT:
I also noticed this in setup:

  pinMode(buttonPin, INPUT);

Are you using an external pulldown resistor for buttonPin?

Normally you'd be using INPUT_PULLUP and connect the button to ground, saving a resistor and
inverting the logic.

I followed this setup for the button:


Here are actual pictures of my setup:

Note: left button just closes the power curcuit for the sound if pressed (the program used to play as a loop in the beginning). Right button: white cable=5v, blue cable=pin 53, yellow cable=mass.


Note: It's a R to R resistor ladder. Left resistor is mass, followed by 8 pins connected to PORTC (Pin 30-37) The signal then goes through the blue cable through the transistor to the speaker.

We will probably try your suggestion with INPUT_PULLUP later today. I didn't know that until now, but I will read something about this.

shokker:
The sounds are constantly played without us pressing the button and the sounds are also played in a strange order (something like 1 - 3 - 2 - 3 - 3 - 1 - 3 - 2 - 3 - 3 - 1...) with some distortion noises.

This error occured everytime you closed the curcuit with the left button I wrote about in my answer above.

But I have to correct myself since the above described has been solved kind of. In the beginning I wrote digitalRead(53) everywhere in my code. After looking at the "Button" sketch from Arduino I declared buttonPin.

After I did that the sound isn't constantly played anymore when you press the left button. Also it now plays three different sounds every time you press the right button (or just hold it down). Sound 2 sounds fine. Sound 3 sounds fine aswell. But after sound 1 finishes there is a high pitch noise and sound 3 plays aswell (they are merged together somehow).

The Mega used to have 128KB, but modern ones have 256KB.

The limit seems to be 32767 entries per array (0x7FFF), and no more than 65536 bytes are addressable,
which I think is because the compiler uses 16 bit pointers. Certainly couldn't get anything to work above
those limits, though I've a rather ancient install here.

Nothing to do with bits or SRAM, I mean bytes and I mean Flash.

This thread seems pertinent: https://forum.arduino.cc/index.php?topic=485507.0

Yet I didn't understand a lot from the topic you shared there, but that is due to my lack of knowledge. I will probably have to read about some things mentioned in the post there first.

But I will try to cut the audio samples a little more and try to not exceed 65k bytes. If playing all three sounds then works we know what the problem is and I will have to find a workaround.

Thank you for your answers so far, I will let you know if it then works or not.