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