MP3 Jukebox (Integer Conversion Issue)

I am a student taking a Micro controller program and we are currently doing Arduino related projects. What my partner and I are trying to do is make a Coin Operated Jukebox that runs on Arduino. We are at a standstill right now. Currently what we have set up is a Master Arduino that is running a 3x4 Keypad, a 16x2 LCD Display and a Coin Acceptor. We have this setup communicating across Analog pins 4 and 5 to a slave Arduino which is running the MP3 FilePlayer same program that has been modified.

The trouble we are having is that the master Arduino that is receiving the Keypad presses is reading them as integers but over the connection to the slave Arduino and once the MP3 program receives it, somewhere along the way it seems to get translated to ASCII. What we want is for the keypad presses to communicate to the slave Arduino but stay as the integer value being inputed.

The parts that we are using are:
MP3 Shield: https://www.digikey.ca/en/products/detail/sparkfun-electronics/DEV-12660/5824154
LCD Display: https://www.digikey.ca/en/products/detail/adafruit-industries-llc/714/5761219
Keypad: https://www.digikey.com/product-detail/en/adafruit-industries-llc/1824/1528-2161-ND/7244947
Coin Acceptor: https://www.digikey.com/product-detail/en/sparkfun-electronics/COM-11719/COM-11719-ND/7319655

Attached are the Codes that we are using.

Any help would be greatly appreciated, thank you.

Jan24_MP3_Player_Slave_Code.ino (14.4 KB)

Jan23_Keypad_Coin_Acceptor_LCD_Master.ino (4.03 KB)

your slave receive function is not correct

void receiveEvent(int howMany)
{
  while (1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int customKey = Wire.read();    // receive byte as an integer
  Serial.println(customKey);         // print the integer
}

You read all the data the master sent and print it out. Then, after the buffer is empty, you try to read customKey.

Also, I2C transmission just sends bytes. When you write() your code in the master sketch, you are really only sending 1 byte, not 2 (the size of int). You need to write the MSB (most significant byte) of your code and then write the LSB of your code.

On the receiving end, you need to read both and combine them together to recreate your code.

Sorry, we were unable to work on this over the weekend and just got back to it. We've only been working with Arduino for about 2 months now and are kind of new to this. How would we edit the slave code to receive what we want it to.
Also, how would we edit the master code with the MSB and LSB and make the MSB come first and the LSB come afterwards? Is there any tutorials that I could watch or anywhere that I could read about this?
How would I go about combining the 2 codes on the receiving end, I'm a bit confused on how I would go about doing that.
Thanks for your help.

1. From your Master, you are sending the contents of code buffer where there are 4 charcaters.

2. In the following receiver codes, you should receive all those 4 charcaters.

char myCode[5] = "";
void receiveEvent(int howMany)
{
  for (int i=0; i<howMany; i++)
  {
    myCode[i] = Wire.read();//while (1 < Wire.available()) // loop through all but the last
  }
  myCode[5] = '\0';  //insert null character 
  //--convert the content of myCode[] array into integer
  int customKey = atoi(myCode);
  flag = true;   //use this flag status in loop() function to execute Serial.print(customKey) job
  //after printing job, reset the myCode[] array with this code: memset(myCode, 0, 5);
}

I tried editing the receiver like you said but now it doesn't seem to be transferring anything, is there anything that I have to change with the Master code?
Also, I've never worked with flags, how would I implement that into my loop, I'm a bit confused about that.
Thank you.

void loop()
{
   if(flag == true)
   {
       Serial.println(customKey);   //should show: 1234 (for example)
       flag = false;
       memset(myCode, 0, 5);   //array reset
   }
}

I tried that edit if (flag == true) but it still doesn’t seem to want to display the entered code. I’ll attach the edited code along with the master code if you want to have a look at it and see if there’s anything that I missed.
Thank you.

Jan27_Combo_LCD_Master.ino (4.18 KB)

MP3_Player_Slave_Code_New_Jan27_Rev5.ino (14.5 KB)

I have already down loaded your both sketches which you have copied from somewhere and beyond my abilities to understand. Simply, answer to my following questions:
1. What Arduino are you using for Master an for for Slave.

2. Give an example of a 4-digit code in decimal (for example: 1234) that you want to collect from the Master Keypad and then send it to Slave using I2C Bus.

inside your receiveEvent function, you create a new variable called customKey but as soon as that function ends, that variable goes away.

void receiveEvent(int howMany)
{
  for (int i = 0; i < howMany; i++)
  {
    myCode[i] = Wire.read();
  }
  myCode[5] = '\0';
  int customKey = atoi(myCode); //Convert array to an integer
}

It has nothing to do with the customKey variable you declare inside loop(). You need to have one global variable called customKey (char or int?) and assign to that.

Both of the Arduinos that we are using are Arduino Uno R3's.
An example of a decimal number that we would use would be a 4 digit number that has leading zeros.
Ex: 0001, 0010, 0002
Thank you.

Follow directives of Post#8 and check if it works; else, I will give codes for transferring/receiving the Keypad inputted number 0002 over I2C Bus.

I have tried what you both have recommended and this is where I am. I have make the customKey variable a global variable and that didn't seem to change anything.
Right now when we enter a code into the Master Arduino, the Slave Arduino doesn't seem to receive any data.
We have run an I2C scanner on both Arduinos' and on the Master Arduino it detects both the LCD display and the Slave Arduino. When I run it on the Slave Arduino, it only detects the display and not the Master Arduino.
Thank you.

Master Code to send 4-digit Keycode command (tested)

#include <Wire.h>
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 3;
char Keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {5, 6, 7, 8};  //R1R2R3R4
byte colPins[COLS] = {10, 3, 4};    //C1C2C3
Keypad customKeypad = Keypad( makeKeymap(Keys), rowPins, colPins, ROWS, COLS );
char myData[5];
int i = 0;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
}

void loop()
{
  char customKey = customKeypad.getKey();
  if (customKey != 0)
  {
    myData[i] = customKey;
    Serial.print(myData[i]);
    i++;
    if (i == 4)  //4 press has been detected
    {
      Serial.println();
      myData[i] = '\0';   //null charcater
      Serial.println(myData);   //shows: 0002
      //-------------------------------------
      Wire.beginTransmission(4);
      Wire.write(myData);  //sends ASCII represented number as separate 4-byte
      Wire.endTransmission();
      //-------------------------------------
      i = 0;
    }
  }
}

Slave Codes to receive 4-digit Keycode from Master and show on Serial Monitor (tested).

#include<Wire.h>
volatile bool flag = false;
char myData[5];

void setup()
{
  Serial.begin(9600);
  Wire.begin(4);
  Wire.onReceive(receiveEvent);
}

void loop()
{
  if(flag == true)
  {
    int keyCode = atoi(myData);
    Serial.println(myData);  //shows: 0002
    Serial.println(keyCode);   //shows:2 without leading 0s
    flag = false;
  }
}

void receiveEvent(int howMany)
{
  for(int i=0; i<howMany; i++)
  {
    myData[i] = Wire.read();
  }
  myData[4] = '\0';
  flag = true;
}

Master Serial Monitor Screenshot:
sm12x.png

Slave Serial Monitor Screenshot:
sm12y.png

sm12x.png

sm12y.png

Thank you so much, that has solved the problem, now we just have to have the MP3 shield accept the keypad entry as the code but we will look into that and figure that out ourselves.
Again, thank you so much.

You are welcome.