[ Foro de C ]

Reproductor melodías Arduino IDE

10-May-2023 19:44
Invitado (programador 81)
0 Respuestas

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.)