Introduction
[NOTE: I use Arduino Mega2560]
Firstly I was inspired by this project
- https://youtu.be/XisSdQF2vdo?si=4C7gyI7epXFw5VMh
- GitHub - P0keDev/Midi2Arduino: A simple project used to convert MIDI files directly into code playable on Arduino piezo buzzers.
He used 5 buzzers to play firefly. And Yeah it is so cool.
So I want to DIY this project but improved further by making individual buzzers volumable. (loudness control inside arduino code) . And play 6 buzzers at the same time.
For volume control. I use MCP41010 digital potentiometer and 2N3906 transistor.
MCP41010 to make current adjustable. and 2N3906 to make buzzer louder (bc MCP41010 will take most of the voltage/watt).
The equation to make buzzer's loudness stay at certain percentage required effort of calculation (bc Iā1/R and IC=hFE*IB etc.,)
I use this ways bc I also want the sound to have damping. (approach to zero amplitude overtime).
(And no toneAC only works with one buzzer so I don't use it)
Here comes the problems part : 6 buzzers
Problems
So I experiment whether I can use 6 buzzers or not by using this code.
#include <SPI.h>
#include "Tone.h"
void setup() {
Serial.begin(9600);
// put your setup code here, to run once:
pinMode(13,OUTPUT);
pinMode(12,OUTPUT);
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(8,OUTPUT);
Tone toner[6];
for(int i=0;i<6;++i){
toner[i].begin(13-i);
toner[i].play(map(i,0,6-1,NOTE_A5,NOTE_DS8));
}
SPI.begin();
pinMode(22,OUTPUT);
pinMode(24,OUTPUT);
pinMode(26,OUTPUT);
pinMode(28,OUTPUT);
pinMode(30,OUTPUT);
pinMode(32,OUTPUT);
pinMode(2,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), test_int, FALLING);
}
void test_int(){
Serial.println("pressed");
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println(millis());
delay(1000);
}
Suprisingly. I can.
The sounds of 6th buzzer is a bit shaky but that's duable.
The big problem is millis() and delay() inside loop() function.
Here are the weird behaviours.
0-2s since the program start
Serial.println(millis());
will display "1"
delay(1000);
This line do nothing. It won't even delay
For 2 seconds the loop() run continuously.
However millis() will return 1 continuously too.
2s-inf since the program start
Serial.println(millis());
will display "1"
delay(1000);
stuck there,freeze and never going anywhere
therefore loop() is not looping
I also tested with other code and found out while-loop work well. The millis() itself doesn't.
If I only use 5 buzzers (by modifying the for-loop and its content). The millis()/micros()/delay() will works just fine.
Like delay() and millis() are essential to space duration between note too.
The push button that connect to pin 2 works fine.. Meaning attachInterrupt works fine.
Questions
- What is the reason behind this? Why using more than 5 buzzers stop timer counter?
- What is the solution to make delay work again?
- What is the work around?
- Do I have to use NE555 timer combine with attachInterrupt() as a workaround? If I really want to use 6 buzzers