Single Ouput Drive Multiple Inputs. Fan-out limit?

HI,

For my Senior Design Project, I designed a custom protocol that would allow me to have multiple devices using one serial bus.

Currently it only works one way. All the slaves can send but not receive data.
The way it works is it uses extra two pins. One is used by the slaves to send a signal to the master that they are currently sending. Another pin is used, which is read by all the slaves to see if the bus is busy.
I have a diode that is reverse connected on both the tx line and the sPin line of the slaves.

Here is a snapshot of the signals. A high on the red indicates that the master is sending the busy signal to all the slaves. A low on the yellow signal indicates that a slaves is sending data.

Currently, it works with 6 slaves.
However I am worried that I may be limited by the fan-out of the output pin I am using.

So my question is hoe many input can I reliably drive with one single output on the master.
If I am limited how can I increase the fanout?
Can I use I transistor of some kind or a buffer that takes one input then drives multiple outputs?

For the Master I am using an Arduino Mega (ATMEGA1280)
For the Slaves I am using regular Arduinos (ATMEGA328)

Here is the code for both master and slave modules.

Master:

//Master Module
//Dino Tinitigan
//implement checksum

char dir;
byte incoming;
byte checksum;
byte checksum2;
int busyPin = 24;
int rPin = 25;
int ID;
int flag = 0;
int test;
int spd;

void setup()
{
  Serial.begin(38400); //use for debugging
  Serial1.begin(38400); //use for embedded
  Serial2.begin(38400); //use for motor
  Serial3.begin(38400); //use for modules
  pinMode(busyPin, OUTPUT);
  pinMode(rPin, INPUT);
  digitalWrite(busyPin, HIGH); //set pin HIGH to lock bus and prevent others from sending
  Serial.println("Start");
}

//-----------------------------------------------------------------------------------------------------//
void loop()
{
  
  checksum = 0; //set checksum to 0
  checksum2 = 255;
  flag = 0;
  /**
  //test loop
  while(Serial3.available() > 0)
  {
    incoming = Serial3.read();
    Serial.print(incoming, BYTE);
  }
  **/
  test = digitalRead(rPin);
  while(test == HIGH) //check if somebody is sending
  {
    //unlock bus and wait for input
    digitalWrite(busyPin, LOW); 
    test = digitalRead(rPin);
  }
  //somebody is trying to send
  digitalWrite(busyPin, HIGH); //set pin HIGH to lock bus and prevent others from sending
  
  //----------------------------process serial data--------------------------------
  if(Serial3.available() > 0)
  {
    incoming = Serial3.read(); //read a byte
    //keep reading a byte until header is found or until buffer is empty
    while((incoming != 255) && (Serial3.available())) 
    {
      incoming = Serial3.read(); //read a byte
      Serial.println("header error");
    }
  
    if(incoming==255)//if header found process data
    {
      Serial.println("***");
      readID(); //check the ID of the packet
    }
    Serial3.flush(); //flush serial buffer
  }
  //----------------------------process serial data--------------------------------
  
  digitalWrite(busyPin, LOW); //set pin LOW to free bus
}
//-----------------------------------------------------------------------------------------------------//

//-----------------------------------------------------------------------------------------------------//
void readID() //read ID and call coresponding function
{
  ID = 0;
  delay(5);
  if(Serial3.available() > 0)
  {
    ID = Serial3.read();
    Serial.print("ID: ");
    Serial.println(ID);
  }
  
  //switch statement for varoius IDs
  switch(ID)
  {
    case 1:
    {
      controlModule(); //control module identified
      break;
    }
    case 3:
    {
      CASModule();
      break;
    }
    default:
    {
      testCom();
    }
  }
}
//-----------------------------------------------------------------------------------------------------//



//-----------------------------------------------------------------------------------------------------//
//--------Receives directional control data----------------//
void controlModule()
{
  if(Serial3.available() > 0)
  {
    dir = Serial3.read();
    //spd = Serial3.read();
    checksum = ID + dir; //+ spd; //checksum calculation
    if(Serial3.available() > 0) //read checksum byte
    {
      checksum2 = Serial3.read(); //checksum calculation
      if(checksum == checksum2)
      {
        //valid data
        //Serial.print("Direction is: ");
        Serial.println(dir);
        //Serial.print("Speed is: ");
        //Serial.println(spd);
      }
      else
      {
        Serial.println("checksum error");
      }
    }
  }
}
//---------------------------------------------------------//

//---------------------------------------------------------//
//-------Receives proximity sensor readings----------------//
void CASModule()
{
  if(Serial3.available() > 0)
  {
    flag = Serial3.read();
    checksum = checksum + flag; //checksum calculation
    if(Serial3.available() > 0) //read checksum byte
    {
      checksum2 = Serial3.read(); //checksum calculation
      if(checksum == checksum2)
      {
        //valid data
        Serial.println("Too Close!!!");
        //delay(500);
      }
      else
      {
        Serial.println("checksum error");
        //delay(500);
      }
    }
  }
}
//---------------------------------------------------------//

//---------------------------------------------------------//
void ECGModule()
{
}
//---------------------------------------------------------//


//---------------------------------------------------------//
void navModule()
{
}
//---------------------------------------------------------//

//---------------------------------------------------------//
//-----------------------------------------------------------------------------------------------------//

//-----------------------------------------------------------------------------------------------------//
void emergencyStop()
{
}
//---------------------------------------------------------//

//---------------------------------------------------------//
void moveMotor()
{
}
//---------------------------------------------------------//

//---------------------------------------------------------//
void testCom()
{
  delay(5);
 Serial.print("test: ");
 Serial.println(ID);
}
//---------------------------------------------------------//
//-----------------------------------------------------------------------------------------------------//

Slaves

//Slave Module
//Dino Tinitigan

int ID = 123;
int x;
int bPin = 10;
int sPin = 11;

void setup()
{
   Serial.begin(38400);
   pinMode(bPin, INPUT);
   pinMode(sPin, OUTPUT);
   digitalWrite(sPin, HIGH);
   delay(500);
}

void loop()
{
  int test = digitalRead(bPin);
  while(test)//busy waiting
  {
    x = random(50);
    delay(x);
    test = digitalRead(bPin);
  }
  //---------------------------transmit------------------------------
  digitalWrite(sPin, LOW); //pull LOW to signify sending
  Serial.write(255);
  Serial.write(ID);
  delay(5);  
  digitalWrite(sPin, HIGH); //pull HIGH to signify done sending
  delay(500); //delay to give others a chance to use Bus 
}

Thanks,
bigdinotech

Sounds awfully like SPI =)

Anyways, in regards to your question:

A single pin on the microcontroller can drive (reliably) about 20mA. The impedance of an input pin is somewhere in the 20Kohm range, if I remember correctly.

V = IR, so I = V/R. Thus, a single input pin will draw about 5.0v/20,000ohm = 0.00025 amps

Under that calculation, you can drive 20mA/0.25mA = 80 input pins per output pin, disregarding wire resistance and other factors. I doubt it will be a limiting factor in your application.

"If I am limited how can I increase the fanout?
Can I use I transistor of some kind or a buffer that takes one input then drives multiple outputs?"

You can always use an octal driver chip like 74F244 (pick your logic family, I just happen to have a lot of old F logic parts around).
Arduino drives 8 pins, the 8 drivers then drive multiple slaves.