Serial use on Mega

I'm trying the get a Mega2560 to talk to an MP3 players using hardware serial and not having any luck. It works fine with SoftwareSerial, which I cannot use because it conflicts with another library, so I'm stuck for now.
Serial1, Serial2 or Serial3 seem not be setup correctly by the begin. I cannot find anyway to confirm that. I need 2 interrupt inputs from Hall sensors. Polling them is too inefficient. If SoftwareSerial can support pins 10/11 as change interrupts I would be happy.
Does anyone have an idea out this conflict?

@Bigoldsofty ,

Topic split from another topic. Please do not add your own questions to the end of other people's topics.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

We would probably if you post the code and some more information about your circuit...

There is no solid reason it would not work using Hardware Serial and work with SoftwareSerial...

I can't understand either why it works with SoftwareSerial but not with Hardware Serial unless the default format in hardware mode is not 8N1. An Open-Smart MP3 module is connected to pins 16 and 17 (Serial1). A stepper motor will be connected to 20-23 but not at this stage. A LocoNet interface uses pins 48,49 and an Adafruit TLC5947 uses 32-34. LEDs will be connected to A0-A13.
To switch between Hard/soft serial I just comment the appropriate line.

#include <LocoNet.h>
#include <EEPROM.h>
#include <Adafruit_TLC5947.h>
#include <Stepper.h>
#include <SoftwareSerial.h>
//#include <PinChangeInt.h>
#include <StringTokenizer.h>
#include <LayoutDefines.h>

// MP3
static int8_t Send_buf[6] = {0} ;
/*basic commands*/
#define CMD_PLAY                0x01
#define CMD_PAUSE               0x02
#define CMD_NEXT_SONG           0x03
#define CMD_PREV_SONG           0x04
#define CMD_VOLUME_UP           0x05
#define CMD_VOLUME_DOWN         0x06
#define CMD_FORWARD             0x0A    // >>
#define CMD_REWIND              0x0B    // <<
#define CMD_STOP                0x0E
#define CMD_STOP_INJECT         0x0F    //stop interruptting with a song, just stop the interlude

/*5 bytes commands*/
#define CMD_SEL_DEV             0x35
#define DEV_TF                  0x01
#define CMD_IC_MODE             0x35
#define CMD_SLEEP               0x03
#define CMD_WAKE_UP             0x02
#define CMD_RESET               0x05

/*6 bytes commands*/  
#define CMD_PLAY_W_INDEX        0x41
#define CMD_PLAY_FILE_NAME      0x42
#define CMD_INJECT_W_INDEX      0x43

/*Special commands*/
#define CMD_SET_VOLUME          0x31
#define CMD_PLAY_W_VOL          0x31

#define CMD_SET_PLAY_MODE       0x33
#define ALL_CYCLE               0x00
#define SINGLE_CYCLE            0x01

#define CMD_PLAY_COMBINE        0x45    //can play combination up to 15 songs
#define CMD_LOOP                0x33

#define   MP3_TX                17    // connect to RX of the module
#define   MP3_RX                16    // should connect to TX of the Serial MP3 Player module

#define   RING_FLD              1
#define   TOLL_FLD              2

//  Comms Tx1/Rx1 18,19 | Tx2/Rx2 16,17 | Tx3/Rx3 14,15 
//#define   myMP3                 Serial1
SoftwareSerial myMP3(MP3_RX, MP3_TX);

//
void setup() {
  Serial.begin(115200);

  pinMode(MP3_TX, OUTPUT);
  pinMode(MP3_RX, INPUT_PULLUP);
  digitalWrite(MP3_TX, HIGH);

  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  
  myMP3.begin(9600);
  delay(1000);
  setVolume(16);
  Serial.println("Hardware Serial for MP3 tester.");Serial.flush();
  playFileName(2, 1);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()) doSerialCommand();Serial.flush();
}

void playFileName(int8_t folder, int8_t fName) {
  mp3_6bytes(CMD_PLAY_FILE_NAME, folder, fName);
}

void setVolume(int8_t vol) {
  mp3_5bytes(CMD_SET_VOLUME, vol);
}

void playWithVolume(int16_t dat) {
  mp3_6bytes(CMD_PLAY_W_VOL, dat);
}

/*cycle play with an index*/
void cyclePlay(int16_t index) {
  mp3_6bytes(CMD_SET_PLAY_MODE,index);
}

void setCyleMode(int8_t AllSingle) {
  mp3_5bytes(CMD_SET_PLAY_MODE,AllSingle);
}

void playCombine(int8_t song[][2], int8_t number) {
  if(number > 15) return;//number of songs combined can not be more than 15
  uint8_t nbytes;//the number of bytes of the command with starting byte and ending byte
  nbytes = 2*number + 4;
  int8_t Send_buf[nbytes];
  Send_buf[0] = 0x7e; //starting byte
  Send_buf[1] = nbytes - 2; //the number of bytes of the command without starting byte and ending byte
  Send_buf[2] = CMD_PLAY_COMBINE; 
  for(uint8_t i=0; i < number; i++)//
  {
    Send_buf[i*2+3] = song[i][0];
    Send_buf[i*2+4] = song[i][1];
  }
  Send_buf[nbytes - 1] = 0xef;
  sendBytes(nbytes);
}

void sendCommand(int8_t command, int16_t dat = 0) {
  delay(20);
  if((command == CMD_PLAY_W_VOL)||(command == CMD_SET_PLAY_MODE)||(command == CMD_PLAY_COMBINE))
    return;
  else if(command < 0x10) 
  {
    mp3Basic(command);
  }
  else if(command < 0x40)
  { 
    mp3_5bytes(command, dat);
  }
  else if(command < 0x50)
  { 
    mp3_6bytes(command, dat);
  }
  else return; 
}

void mp3Basic(int8_t command) {
  Send_buf[0] = 0x7e; //starting byte
  Send_buf[1] = 0x02; //the number of bytes of the command without starting byte and ending byte
  Send_buf[2] = command; 
  Send_buf[3] = 0xef; //
  sendBytes(4);
}

void mp3_5bytes(int8_t command, uint8_t dat) {
  Send_buf[0] = 0x7e; //starting byte
  Send_buf[1] = 0x03; //the number of bytes of the command without starting byte and ending byte
  Send_buf[2] = command; 
  Send_buf[3] = dat; //
  Send_buf[4] = 0xef; //
  sendBytes(5);
}

void mp3_6bytes(int8_t command, int16_t dat) {
  Send_buf[0] = 0x7e; //starting byte
  Send_buf[1] = 0x04; //the number of bytes of the command without starting byte and ending byte
  Send_buf[2] = command; 
  Send_buf[3] = (int8_t)(dat >> 8); //datah
  Send_buf[4] = (int8_t)(dat);      //datal
  Send_buf[5] = 0xef;               //
  sendBytes(6);
}

void mp3_6bytes(int8_t command, int8_t dat1, int8_t dat2) {
  Send_buf[0] = 0x7e; //starting byte
  Send_buf[1] = 0x04; //the number of bytes of the command without starting byte and ending byte
  Send_buf[2] = command; 
  Send_buf[3] = dat1;
  Send_buf[4] = dat2;
  Send_buf[5] = 0xef; //
  sendBytes(6);
}

void sendBytes(uint8_t nbytes) {
  Serial.print("sendBytes ");Serial.println(nbytes);
  for(uint8_t i=0; i < nbytes; i++)
  {
    Serial.print(Send_buf[i], HEX);Serial.print(" ");
    myMP3.write(Send_buf[i]) ;
  }
  Serial.println();Serial.flush();
}

void doSerialCommand() {
  Serial.println("Entered doSerialCommand");Serial.flush();
  String inString = Serial.readStringUntil('\n');
  inString.toUpperCase();
  switch(inString[0]) {
    case 'B':
      Serial.println(inString);Serial.flush();
      playFileName(RING_FLD, atoi(inString.substring(1).c_str()));
      break;
    case 'F':
      Serial.println(inString);Serial.flush();
      playFileName(TOLL_FLD, atoi(inString.substring(1).c_str()));
      break;
  }
}

OOPS just realised I posted code defining Serial2 but starting Serial 1 which wouldn't work anyway.
If the definition is changed the problem still exists though.

I have included header files that are not really needed for the purpose of this test sketch apart from checking for conflicts is I try alternative Software serial libraries.
The reason I am making the change in my module, is that the original stepper motor control was blocking and made no difference to the soundtrack. The TLC5947 will control light changes that should not stop while the stepper motor works. I therefore need to break that up and time share its operation which is also why I would prefer to use interrupts for 'end of travel' sensing.

What pin on the MP3 is connected to pin16, and what pin on the MP3 is connected to pin 17? Are you cross connected with the rx>tx and tx>rx?

When using Serial2 I would delete these lines from setup, and let the instance control the pins.

//pinMode(MP3_TX, OUTPUT);
//pinMode(MP3_RX, INPUT_PULLUP);
//digitalWrite(MP3_TX, HIGH);

I had deleted those lines. Because things weren't working, I had them in for a while to see if that would make a difference, seeing I can't explain why something that should be working, wasn't. Yes, the RX and TX are cross connected. Tripple checked. I've made that mistake too many times in the past. I have even swapped to another Mega2560 in case I had a faulty one.

it is the default format.

May be you need to add a small delay after sending a command to ensure the MP3 got time to decode and execute what you requested.

Could you try something like this for your sendBytes() function (typed here, mind typos)

void sendBytes(uint8_t nbytes) {
  const unsigned long minTimeBetweenCommands = 100;
  static unsigned long lastCommandTime = -minTimeBetweenCommands;
  unsigned long now = millis();
  if (now - lastCommandTime < minTimeBetweenCommands) {
    // ensure minTimeBetweenCommands ms have elapsed since the last command
    delay(minTimeBetweenCommands - (now - lastCommandTime));
  }
  myMP3.write(Send_buf, nbytes) ; // send the command
  myMP3.flush();
  lastCommandTime = millis();
  Serial.print("sendBytes "); Serial.println(nbytes);
  for (uint8_t i = 0; i < nbytes; i++)  {
    Serial.print(Send_buf[i], HEX); Serial.print(" ");
  }
  Serial.println(); Serial.flush();
}

you'll get a blocking function that will wait up to 100ms in between two calls.

Also agree that you need to remove these lines when using Serial1

of course ensure things are connected in the right way.

Thanks for the help. The time delay helped.
There was also a hardware problem with an intermittent contact in the connector.

OK - glad you solved it!