ATtiny85 as I2C to serial bridge for YX5300 MP3 Player

I have started a big project and am trying to modularize it by using I2C devices as modules.

So far I have the following working on I2C:
20x4 LCD using PCF8574T
4x4 Keypad using PCF8574T

I have a few other devices that I want to port over to I2C:
RGB Led using ATtiny85, source is @ GitHub - G42makes/ATTiny-i2c-RGB: Via an ATTiny85, control the color and patters of an RGB LED,
Code looks good just waiting for the parts to arrive.

Now for the issue:

I could use a "SC16IS750 Breakout Board" but would prefer to create an "ATtiny85 I2C to serial/UART Bridge"

I have a few devices that communicate through Rx, Tx pins:
YX5300 MP3 player GitHub - cefaloide/ArduinoSerialMP3Player: Playing MP3 files on a Serial MP3 Player board from Catalex (YX5300 chip),
HC-12 433Mhz Wireless Serial Port GitHub - daar/HC-12: HC-12 library for Arduino

I have code that should work for I2C communication but am at a loss when it comes to sending a serial command through the I2C bus to be executed on remote arduino and passed on to remote device on Rx/Tx lines.

ATtiny85 I2C to serial/UART Bridge

This is a rather bad idea as the ATtiny85 doesn't have a UART interface. The only way to achieve that would be to use the SoftwareSerial emulation but that blocks interrupts for long periods of time (during complete byte transfers) so any I2C communication will fail during that time. Such a system would fail most of the time because of inherent race conditions (either interrupt will win and the other interface is blocked). You can work around that but then you have to move all driver code for your components to the Tiny and provide long wait periods for the tiny to do it's work. This will seriously slow down your system and provide a bad user experience.

I suggest to either use a Mega2560 (which has 4 hardware serial interfaces) as the main controller and connect the serial hardware directly to it or use an ATmega328 (or similar) as the I2C-to-UART converter and put all the intelligence for the serial interface to it. You then have to develop a new interface for the I2C side that abstracts the functionality to a scheme that adapts to I2C. I don't know how well that may work for the HC-12, you didn't specify what you wanted to use that one for.

Thank you pylon, for taking the time to guide me.

The data I plan on sending is minimal, with no more that 8 Bytes sent at any given time.
I had not thought about the I2C bus locking up due to congestion.
Good point thanks for bringing it up (pylon).

What if I were to send a single Byte command across the I2C bus and have the ATtiny85 decipher the "menu item" and execute the command itself?
Would that be a better way to accomplish the ability to modularize my project?

The reason I want to create I2C bus modules is for expansion.

Currently I am using an Arduino Nano it has an I2C LCD and 4x4 Keypad, I also have 2x TM1634 (7 seg display) using common clk pin and separate Digital In pins (3 pins total).

By adding devices to the I2C bus the master program would poll in the Setup() phase for I2C addresses, based on the available addresses, the functions of the devices at specific addresses would become available for the loop() phase.

Example:
I2C address x31 would be ATtiny85 with YX5300 connected to it; this would enable MP3 Playback of sound.
I2C address x42 would be ATtiny85 with push button connected to it; this would enable remote trigger.

Indeed both I2C and Serial require interrupts. That's a problem. Your other problem is likely going to be the available memory - especially the RAM. The default TinyWireS library uses 32-byte buffers for the I2C communication, if you're careful you can trim that down and give yourself a bit more breathing room elsewhere.

There are more modern ATtinies out there that have a Serial interface built in. Just a few come in DIP package, though (which is one of the main attractions of using the x5 series), most are in SSOP and QFN packages only.

Thanks wvmarie, for your input.

I was planning to use the ATtiny85 as a serial bridge.

After the input from pylon,
I think it would be wiser to use the ATtiny85 as a single function interface sitting on the I2C BUS.
The ATtiny85 are inexpensive and the I2C BUS should be able to handle less than a dozen devices fine.

By only sending a short transmission of data (1 Byte can hold 256 values), it would limit the congestion on the BUS. By using a menu like system it would offload any real processing from the master Arduino Nano to the ATtiny85 slaves.

Examples:
ATtiny85 controlling 4 relays => send byte value representing which relay and if it is toggled or not.
ATtiny85 controlling YX5300 => send byte value representing which mp3 to play.
ATtiny85 controlling 4 buttons => receive byte value representing which button(s) were pressed.

Looking back at OP I think the proper solution for this is to use a Mega.

Three hardware serial ports (for your two Serial devices + Serial monitor - no messing around with SoftwareSerial).

Plenty of pins - it just doesn't make sense to offload handing a relay to an ATtiny. Instead of all the overhead of maintaining the software of two devices and handling the communication, just control those pins directly. Or if you run out of pins, it makes much more sense to use a port expander rather than a microcontroller to get more pins.

Same for buttons. Instead of pulling an ATtiny over I2C to ask whether a switch was pressed, just read the switches directly.

The ATtiny85 are inexpensive and the I2C BUS should be able to handle less than a dozen devices fine.

It's not easy to design an I2C bus that will handle 1 device equally well as 12 devices on it. As the bus is passively pulled high the total bus capacitance is critical and that changes with every device added. You might have to adapt the pull-up depending on the bus capacitance.

By only sending a short transmission of data (1 Byte can hold 256 values), it would limit the congestion on the BUS.

A standard command of your MP3 player is 8 bytes long. Sending 8 bytes using SoftwareSerial blocks your Tiny for about 8ms (using 9600 baud). During this time frame the I2C bus may transmit about 100 bytes which your Tiny won't see as the necessary interrupt is blocked. So imagine how reliable your system will be.

Thanks again pylon and vwmarle for your input.

Unfortunately the design is restricted to using a Nano, although I agree the Mega would be the better choice, especially for designs sake.

The second problem with the design requirements are that the main device must be modifiable by simply adding modules.
The only automatic way I came up with was to scan the I2C Bus for predetermined addresses if they exist, than the functions of that device would become available as I had mentioned earlier.

As for the MP3 Player, I could send a single byte to the tiny and the tiny would translate that byte into an instruction that it would then execute independently of the Nano (like sending an address in an array)

I appreciate your feedback, and I will try and explain in greater detail, once I iron out a more formal plan as to what I plan to build.

Unfortunately the design is restricted to using a Nano, although I agree the Mega would be the better choice, especially for designs sake.

The second problem with the design requirements are that the main device must be modifiable by simply adding modules.

Please explain, where these restrictions are coming from. Is the usage of an ATtiny85 also predefined?

As for the MP3 Player, I could send a single byte to the tiny and the tiny would translate that byte into an instruction that it would then execute independently of the Nano (like sending an address in an array)

Yes, you wrote that already. That was the assumption for my comment. The problem is not the one byte you get from the Nano but that you send several bytes to the MP3 board using SoftwareSerial and during that transfer your Tiny will not realize that it might have got another byte on the I2C because the necessary interrupt was blocked for a to long time.

Pylon,

Thanks for clarifying that, for this particular project that is not really a problem as any communication with the "Tiny-YX5300 module" would not happen any quicker than 15 seconds from last transmission.

Thanks for clarifying that, for this particular project that is not really a problem as any communication with the "Tiny-YX5300 module" would not happen any quicker than 15 seconds from last transmission.

That means you ensure on your master (Nano) that before sending anything to the MP3 Tiny there is no traffic on the I2C for 15 seconds and there will be no traffic on the I2C for the same amount of time? I don't think that any such system makes any sense but if that's your specification go with your approach. But a reaction time of 15 seconds for a key stroke on the keypad is not what the average user expects.

I have the impression that you didn't understand the implications that your "design" poses on the timing behavior of the system. If you connect the MP3 player by the ATtiny with SoftwareSerial it won't work the way you expect it. Believe me.

I found the answer I was initially looking for here:
https://forum.arduino.cc/index.php?topic=441428.0