[ Foro de C ]
Tengo aquí un código en C que almacena unas melodías para luego hacerlas sonar en un zumbador. El problema que tengo es que el modo de reproducción me funciona ya que ni se mantiene ni suena la melodía. Alguien sabría decirme como arreglarlo.
// SimulIDE Compilar=Arduino Board=Mega
/* ------------------------------------------------------ */
/* melody_player.ino - Melodyplayer */
/* ------------------------------------------------------ */
#include "pitches.h"
#include <Wire.h>
/* Define constants. ------------------------------------ */
/* Melodies. */
#define MELODIES 2
#define MELODY_NAME_LEN 15
#define MELODY_NOTES 10
/* Modes. */
#define MODE_SELECT 0
#define MODE_PLAY 1
/* Rotary encoder. */
#define ROTARY_EVENT_NONE 0
#define ROTARY_EVENT_SWITCH 1
#define ROTARY_EVENT_RIGHT 2
#define ROTARY_EVENT_LEFT 3
/* LCD. */
#define LCD_I2C_ADDR 0x3E
#define LCD_MODE_COMMAND 0x00
#define LCD_MODE_DATA 0x40
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINC 0x01
#define LCD_ENTRYSHIFTDEC 0x00
/* Typedefs. -------------------------------------------- */
typedef struct {
int frequency; /* Hz */
int duration; /* ms */
} note;
typedef struct {
char name[MELODY_NAME_LEN + 1];
note notes[MELODY_NOTES];
} melody;
/* Constants. ------------------------------------------- */
const melody melodies[MELODIES] = {
{
"Melodia A",
{ {NOTE_C4, 250}, {NOTE_G3, 125}, {NOTE_G3, 125}, {NOTE_A3, 250}, {NOTE_G3, 250}, {0, 250}, {NOTE_B3, 250}, {NOTE_C4, 250}, {0, 250}, {-1, 0} }
},
{
"Melodia B",
{ {NOTE_C3, 125}, {NOTE_C3, 125}, {NOTE_D3, 250}, {NOTE_C3, 250}, {NOTE_F3, 250}, {NOTE_E3, 500}, {0, 250}, {-1, 0}, {-1, 0}, {-1, 0} }
}
};
const int PIN_CLK = 2;
const int PIN_DT = 3;
const int PIN_BOTON = 4;
const int PIN_BUZZER = 8;
/* Global variables. ------------------------------------- */
int mode = MODE_SELECT;
int CLK_ANTERIOR = LOW;
int DT_ANTERIOR = LOW;
int BOTON_ANTERIOR = HIGH;
int prev_pos = 0;
/* Rotary encoder functions. ----------------------------- */
void rotarySetup()
{
pinMode(PIN_CLK, INPUT);
pinMode(PIN_DT, INPUT);
pinMode(PIN_BOTON, INPUT_PULLUP);
}
int rotaryReadEvent()
{
int CLK_ACTUAL = digitalRead(PIN_CLK);
int DT_ACTUAL = digitalRead(PIN_DT);
int BOTON_ACTUAL= digitalRead(PIN_BOTON);
if (BOTON_ACTUAL != BOTON_ANTERIOR) {
BOTON_ANTERIOR = BOTON_ACTUAL;
return ROTARY_EVENT_SWITCH;
} else if (CLK_ACTUAL != CLK_ANTERIOR) {
CLK_ANTERIOR = CLK_ACTUAL;
if (DT_ACTUAL != CLK_ACTUAL) {
prev_pos--;
return ROTARY_EVENT_LEFT;
} else {
prev_pos++;
return ROTARY_EVENT_RIGHT;
}
}
return ROTARY_EVENT_NONE;
}
/* LCD functions. ----------------------------------------- */
void lcdSend (unsigned char value, unsigned char mode) {
Wire.beginTransmission(LCD_I2C_ADDR);
Wire.write(mode);
Wire.write(value);
Wire.endTransmission();
delayMicroseconds(50);
}
void lcdSetup() {
Wire.begin();
lcdSend(LCD_FUNCTIONSET|LCD_8BITMODE|LCD_2LINE|LCD_5x8DOTS, LCD_MODE_COMMAND);
lcdSend(LCD_DISPLAYCONTROL|LCD_DISPLAYON|LCD_CURSOROFF|LCD_BLINKOFF, LCD_MODE_COMMAND);
lcdSend(LCD_CLEARDISPLAY, LCD_MODE_COMMAND);
delayMicroseconds(2000);
lcdSend(LCD_ENTRYMODESET|LCD_ENTRYLEFT|LCD_ENTRYSHIFTDEC, LCD_MODE_COMMAND);
}
void lcdClear(){
lcdSend(LCD_CLEARDISPLAY, LCD_MODE_COMMAND);
delayMicroseconds(2000);
}
void lcdSetCursor(int x,int y){
unsigned char value = 0;
if (y>0){
value = 0x40;
}
value += x;
lcdSend(LCD_SETDDRAMADDR | value, LCD_MODE_COMMAND);
}
void lcdPrint(const char *str) {
while (*str != 0) {
lcdSend(*str, LCD_MODE_DATA);
str++;
}
}
/* Play functions. --------------------------------------- */
int current_melody = 0;
int current_note = 0;
int current_duration = 0;
int current_speed = 100;
bool playing = false;
void play_start()
{
playing = true;
current_note = 0;
current_duration = 0;
tone(PIN_BUZZER, melodies[current_melody].notes[current_note].frequency);
}
void play_task()
{
if (playing && current_duration >= melodies[current_melody].notes[current_note].duration / current_speed) {
noTone(PIN_BUZZER);
current_note++;
current_duration = 0;
if (melodies[current_melody].notes[current_note].frequency == -1) {
playing = false;
return;
}
tone(PIN_BUZZER,melodies[current_melody].notes[current_note].frequency);
}
current_duration++;
}
void play_stop()
{
playing = false;
noTone(PIN_BUZZER);
}
void play_decrease_speed()
{
current_speed--;
if (current_speed < 50) {
current_speed = 50;
}
}
void play_increase_speed()
{
current_speed++;
if (current_speed > 150) {
current_speed = 150;
}
}
void play_show()
{
lcdClear();
lcdSetCursor(0, 0);
lcdPrint(melodies[current_melody].name);
lcdSetCursor(0, 1);
lcdPrint("Notas:");
lcdSetCursor(6, 1);
lcdPrint(String(MELODY_NOTES - 1).c_str()); // Convertir a const char*
lcdSetCursor(10, 1);
lcdPrint(String(current_speed).c_str()); // Convertir a const char*
lcdPrint("%");
}
/* Melody functions. --------------------------------------- */
void melody_previous()
{
current_melody--;
if (current_melody < 0) {
current_melody = MELODIES - 1;
}
if (playing) {
play_start();
} else {
melody_show();
}
}
void melody_show()
{
lcdClear();
lcdSetCursor(0, 0);
lcdPrint("Pista:");
lcdSetCursor(8, 0);
lcdPrint(String(current_melody + 1).c_str());
lcdSetCursor(0, 1);
lcdPrint(melodies[current_melody].name);
}
void melody_next()
{
current_melody++;
if (current_melody >= MELODIES) {
current_melody = 0;
}
if (playing) {
play_start();
} else {
melody_show();
}
}
/* Mode control functions. --------------------------------------- */
void mode_select()
{
int event = rotaryReadEvent();
switch(event) {
case ROTARY_EVENT_SWITCH:
play_start();
play_show();
mode = MODE_PLAY;
break;
case ROTARY_EVENT_LEFT:
melody_previous();
melody_show();
break;
case ROTARY_EVENT_RIGHT:
melody_next();
melody_show();
break;
}
}
void mode_play()
{
int event = rotaryReadEvent();
switch(event) {
case ROTARY_EVENT_SWITCH:
play_stop();
melody_show();
mode = MODE_SELECT;
break;
case ROTARY_EVENT_LEFT:
play_decrease_speed();
play_show();
break;
case ROTARY_EVENT_RIGHT:
play_increase_speed();
play_show();
break;
}
play_task();
}
/* Arduino main functions. -------------------------------- */
void setup(){
pinMode(PIN_BOTON, INPUT_PULLUP); //4 //encoderPinA
pinMode(PIN_DT, INPUT_PULLUP); //3 //encoderPinB
pinMode(PIN_CLK, INPUT_PULLUP); //2
pinMode(PIN_BUZZER, OUTPUT);
lcdSetup();
rotarySetup();
melody_show();
Serial.begin(115200);
}
void loop()
{
switch (mode) {
case MODE_SELECT:
play_task();
mode_select();
break;
case MODE_PLAY:
play_task();
mode_play();
break;
}
}
/* --------------------------------------------------------- */
(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)