Voor een surprise projectje ben ik bezig om via een buzzer een theme song van Minecraft af te spelen.
Ik heb de sketch van een voorbeeld project. Dit werkt verder prima. Ik heb de code aangepast zodat het afspelen van het deuntje in de main loop zit en ik deze kan aanzetten met een druk op de knop. Veel spannender moet het niet worden. Echter wil ik nog 1 uitgang hoog maken wanneer het programma in de for loop zit van het afspelen van de theme song. Hiermee wil ik nog een ledstripje aansturen. Ik dacht dit simpel te doen door een digital.write toe te voegen, en dan deze pin hoog te maken. En deze weer laag te maken als die uit de for loop is.
Maar wanneer ik dit doe, dan klopt het "deuntje" niet meer. Hij lijkt dat niet meer de goede volgorde van de array te volgen. Echter zie ik niet terug waarom dit fout gaat. Op dit moment heb ik de extra stukjes code voor de aansturing van Pin3 als comment neergezet. Dan gaat het goed. Maar als ik zelfs al alleen in de void setup deze regel neerzet pinMode(3, OUTPUT); // sets the digital pin 3 as output, dan gaat het al fout.
Iemand enig idee? Wellicht zie ik iets simpels over het hoofd, maar ik zie niet wat.
// NB: ALL NOTES DEFINED WITH STANDARD ENGLISH NAMES, EXCEPT FROM "A"
//THAT IS CALLED WITH THE ITALIAN NAME "LA" BECAUSE A0,A1...ARE THE ANALOG PINS ON ARDUINO.
// (Ab IS CALLED Ab AND NOT LAb)
#define C0 16.35
#define Db0 17.32
#define D0 18.35
#define Eb0 19.45
#define E0 20.60
#define F0 21.83
#define Gb0 23.12
#define G0 24.50
#define Ab0 25.96
#define LA0 27.50
#define Bb0 29.14
#define B0 30.87
#define C1 32.70
#define Db1 34.65
#define D1 36.71
#define Eb1 38.89
#define E1 41.20
#define F1 43.65
#define Gb1 46.25
#define G1 49.00
#define Ab1 51.91
#define LA1 55.00
#define Bb1 58.27
#define B1 61.74
#define C2 65.41
#define Db2 69.30
#define D2 73.42
#define Eb2 77.78
#define E2 82.41
#define F2 87.31
#define Gb2 92.50
#define G2 98.00
#define Ab2 103.83
#define LA2 110.00
#define Bb2 116.54
#define B2 123.47
#define C3 130.81
#define Db3 138.59
#define D3 146.83
#define Eb3 155.56
#define E3 164.81
#define F3 174.61
#define Gb3 185.00
#define G3 196.00
#define Ab3 207.65
#define LA3 220.00
#define Bb3 233.08
#define B3 246.94
#define C4 261.63
#define Db4 277.18
#define D4 293.66
#define Eb4 311.13
#define E4 329.63
#define F4 349.23
#define Gb4 369.99
#define G4 392.00
#define Ab4 415.30
#define LA4 440.00
#define Bb4 466.16
#define B4 493.88
#define C5 523.25
#define Db5 554.37
#define D5 587.33
#define Eb5 622.25
#define E5 659.26
#define F5 698.46
#define Gb5 739.99
#define G5 783.99
#define Ab5 830.61
#define LA5 880.00
#define Bb5 932.33
#define B5 987.77
#define C6 1046.50
#define Db6 1108.73
#define D6 1174.66
#define Eb6 1244.51
#define E6 1318.51
#define F6 1396.91
#define Gb6 1479.98
#define G6 1567.98
#define Ab6 1661.22
#define LA6 1760.00
#define Bb6 1864.66
#define B6 1975.53
#define C7 2093.00
#define Db7 2217.46
#define D7 2349.32
#define Eb7 2489.02
#define E7 2637.02
#define F7 2793.83
#define Gb7 2959.96
#define G7 3135.96
#define Ab7 3322.44
#define LA7 3520.01
#define Bb7 3729.31
#define B7 3951.07
#define C8 4186.01
#define Db8 4434.92
#define D8 4698.64
#define Eb8 4978.03
const int buttonPin = 2; // the number of the pushbutton pin
int buttonState = 0; // variable for reading the pushbutton status
int melody[] = {C3, G3, C4, D4, E4, G3, C3, G3, C4, D4, E4, G3, LA2, G3, C4, D4, E4, G3, LA2, G3, C4, D4, E4, G3, F2, G3, C4, D4, E4, G3, F2, G3, C4, D4, E4, G3, G2, G3, C4, D4, E4, G3, G2, G3, C4, D4, E4, G3};
void setup() {
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
// initialize the pin3 as an output:
// pinMode(3, OUTPUT); // sets the digital pin 3 as output
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
for (int thisNote = 0; thisNote < 48; thisNote++) {
//digitalWrite(3, HIGH); // turn the LED on (HIGH is the voltage level)
int noteDuration = 1000/4;
tone(8, melody[thisNote],noteDuration);
delay(noteDuration);
}
//digitalWrite(3, LOW); // turn the LED off (LOW is the voltage level)
}
}
Op een Arduino Leonardo onder 2.2.1 kan ik het probleem niet reproduceren, de code lijkt normaal te werken.
Ik heb een filmpje toegevoegd wat het probleem weergeeft.
Als eerste heb ik de code zonder declareren van de output pin. Dan gaat het goed.
Vervolgens declareer ik enkel pin 3 in de void setup. Dan gaat het al fout.
En als laatste haal ik de commentaar lijntje weg in de for loop. Dan zie je dat de uitgang wel hoog gemaakt wordt in de for loop, maar de themesong is nog steeds onjuist.
Pin3 en 11 zijn PWM pinnen. Als je de mogelijkheid hebt, gebruik dan een andere pin voor je led.
Zie hier:
https://www.arduino.cc/reference/en/language/functions/advanced-io/ton…
De melodie is hetzelfde, alleen de frequentie lijkt verschoven te zijn.
Mogelijk heeft u een bug of ongedocumenteerd feature gevonden, maar de snelste oplossing lijkt me een andere pin voor audio of lamp te proberen.
Een andere mogelijkheid is niet de Arduino pinMode en digitalWrite functies te gebruiken voor het aansturen van de pin, maar de register bits met de hand te zetten. Dat is goed te doen.
Op 14 december 2023 13:11:23 schreef Zonnepaneeltje:
Pin3 en 11 zijn PWM pinnen. Als je de mogelijkheid hebt, gebruik dan een andere pin voor je led.
Zie hier:
https://www.arduino.cc/reference/en/language/functions/advanced-io/ton…
Gewijzigd naar pin 4, maar helaas blijft het hetzelfde..
Edit: Gewijzigd naar pin 7, nu lijkt het 3x goed te gaan. Daarna gaat het weer fout..
Schiet mij maar lek!
[Bericht gewijzigd door Ricotjuh op (13%)]
maartenbakker
Golden Member
www.elba-elektro.nl | "The mind is a funny thing. Sometimes it needs a good whack on the side of the head to jar things loose."
IK verwacht een beetje dat het in de pinmode routine zit, die zet misschien ergens een register dat dit als effect heeft. Dan zou je het inderdaad kunnen vermijden door zelf naar de registers te schrijven. Probeer dat eens.
[Bericht gewijzigd door maartenbakker op (17%)]
buckfast_beekeeper
Van Lambiek wordt goede geuze gemaakt.
int noteDuration = 1000/4;Wijzigt niet gedurende de ganse for loop. Zet die gewoon buiten je loop. Of zelfs gewoon als een constante declareren.
Je kan de led uitgang ook hoog maken net voor het starten van de loop en uitzetten na het einde. Een uitgang die niet tot dezelfde 8 uitgangen behoort als de melody uitgang zou moeten lukken.
Heb er nu dit van gemaakt en lijkt het wel te werken.
Alleen is dit dan een "soort van bug" in de software tijdens het gebruik van pinMode en de Tone() commando?
Want in al mijn andere arduino programma's maak ik normaliter gebruik van pinMode
void setup() {
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
// initialize the pin3 as an output:
//pinMode(7, OUTPUT); // sets the digital pin 3 as output
DDRD = DDRD | B10000000;
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
for (int thisNote = 0; thisNote < 48; thisNote++) {
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
tone(8, melody[thisNote],noteDuration);
delay(noteDuration);
}
digitalWrite(7, LOW); // turn the LED off (LOW is the voltage level)
}
}
[Bericht gewijzigd door Ricotjuh op (13%)]
Je zet nu 48 keer de LED aan en weer uit. Kun je dat niet beter buiten de for loop doen, heeft zelfde effect en lost misschien het probleem op (geen extra CPU cycles binnen de for loop door digitalWrite() )
/edit, P3 dus niet gebruiken... (thnx, fcapri). Aan/uit zetten buiten de loop wel doen (LED_BUILTIN = de LED op het arduino bordje).
pinMode(LED_BUILTIN, OUTPUT)
if (buttonState == HIGH) {
digitalWrite(LED_BUILTIN, HIGH);
for (int thisNote = 0; thisNote < 48; thisNote++) {
int noteDuration = 1000/4;
tone(8, melody[thisNote],noteDuration);
delay(noteDuration);
}
digitalWrite(LED_BUILTIN, LOW);
}
je moet eens goed de tone() nalezen. als je die gebruikt, zijn er een aantal pwm uitgangen die je NIET meer mag gebruiken.
3 is er eentje van 
Use of the tone() function will interfere with PWM output on pins 3 and 11 (on boards other than the Mega).
https://www.arduino.cc/reference/en/language/functions/advanced-io/ton…
blijf gewoon weg van alle PWM pinnen, misbruik eventueel een analoge pin om uw leds te laten branden.
Je zet nu 48 keer de LED aan en weer uit. Kun je dat niet beter buiten de for loop doen
Maar dat doet hij ook. Alleen staan de haakjes op een rare plaats dus je ziet het niet. Dat is precies de reden dat ik die stijl niet gebruik
.
Op 14 december 2023 16:16:58 schreef Schimanski:
Je zet nu 48 keer de LED aan en weer uit. Kun je dat niet beter buiten de for loop doen, heeft zelfde effect en lost misschien het probleem op (geen extra CPU cycles binnen de for loop door digitalWrite() )/edit, P3 dus niet gebruiken... (thnx, fcapri). Aan/uit zetten buiten de loop wel doen (LED_BUILTIN = de LED op het arduino bordje).
pinMode(LED_BUILTIN, OUTPUT) if (buttonState == HIGH) { digitalWrite(LED_BUILTIN, HIGH); for (int thisNote = 0; thisNote < 48; thisNote++) { int noteDuration = 1000/4; tone(8, melody[thisNote],noteDuration); delay(noteDuration); } digitalWrite(LED_BUILTIN, LOW); }
Voor de werking maakt dat niets uit volgens mij. Ik heb net getest om de digitalWrite voor het for command te zetten, maar dit lijkt niets te verschillen. Voor de zekerheid ook op pin7 gemeten met de scoop, maar ik zie daar geen pulsen voorbij komen. Enkel een puls na het indrukken van de start button.
Daarnaast even getest met de builtin led, maar dan gaat ie weer de fout in zoals in de video is aangegeven.
Dus op dit moment lijkt het enkel "goed" te werken als ik de uitgang zo: DDRD = DDRD | B10000000; definieer
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Op 14 december 2023 16:22:00 schreef fcapri:
je moet eens goed de tone() nalezen. als je die gebruikt, zijn er een aantal pwm uitgangen die je NIET meer mag gebruiken.
3 is er eentje van
Je kunt de hardware PWM functie van die pin niet meer gebruiken, zeer waarschijnlijk omdat ze dezelfde timer gebruiken om de interrupt te maken. Ik vind het stom dat ze vervolgens in die interrupt naar een pin gaan schrijven, ze hadden ook pin 3 kunnen togglen op de compare match.
Je kunt die pin dus prima gebruiken voor iets anders.
Op 14 december 2023 17:12:37 schreef deKees:
[...]Maar dat doet hij ook. Alleen staan de haakjes op een rare plaats dus je ziet het niet. Dat is precies de reden dat ik die stijl niet gebruik
.
Ik zie het nu, hij zet elke itteratie de LED opnieuw aan, en na afloop van de for-loop weer uit.