I have made a first version of data transfer. It uses 4 pins.
The Master (transmits data)
// Toggle with Handshake Communication.
// ------------------------------------
//
// This communication is written for the VGAx code.
// It transfers a byte from a Master Arduino to a Slave Arduino.
// The Slave Arduino is running the VGAx code.
// The Slave code does not use delays, no interrupts,
// and interrupts are not disabled.
//
// Signals are active HIGH, and default LOW.
// LSB first, bit 0 is the first bit to be send.
//
// Four signal wires plus GND:
// dat = data (from Master)
// dtr = data ready (from Master)
// ack = acknowledge (from Slave)
// stx = first bit (from Master)
// GND (connect also both GND of the Arduino boards)
//
// Transfer rate is about 1400 bytes per second for two Arduino Uno boards.
//
// This is the first version, the code might not be fully fail safe at the moment.
//
const int pinDat = A1;
const int pinDtr = A2;
const int pinAck = A3;
const int pinStx = A4;
void setup()
{
Serial.begin(9600);
Serial.println(F("Master"));
pinMode( pinDat, OUTPUT);
pinMode( pinDtr, OUTPUT);
pinMode( pinAck, INPUT);
pinMode( pinStx, OUTPUT);
}
void loop()
{
const char text[] = "Hello World\r\n";
for( int i=0; i<strlen(text); i++)
{
int n = ToggleSend( text[i]);
if( n == 0)
Serial.println(F("ToggleSend failed"));
}
}
// ToggleSend
// ----------
// Send a single byte.
// This function waits for the Slave with a timeout,
// and returns after the byte has been send.
// The return value is the number of bytes that are send.
// At this moment only one byte is send.
//
int ToggleSend( const byte data)
{
unsigned long toggleMillis;
int error = 0;
int n = 0; // number of bytes that are send
digitalWrite( pinStx, HIGH); // indicate start (HIGH for first bit)
for( int i=0; i<8 && error == 0; i++)
{
digitalWrite( pinDat, bitRead( data, i) == 1 ? HIGH : LOW);
digitalWrite( pinDtr, HIGH); // everything is ready, make it high
// wait for ack to be HIGH
toggleMillis = millis();
while( digitalRead( pinAck) == LOW)
{
if( millis() - toggleMillis >= 1000UL)
{
error = -1;
Serial.println(F("timeout waiting for ack high"));
break;
}
}
digitalWrite( pinStx, LOW); // stx low for other bits
digitalWrite( pinDtr, LOW); // everything is ready, make it low.
if( error == 0)
{
// wait for ACK to go low.
toggleMillis = millis();
while( digitalRead( pinAck) == HIGH)
{
if( millis() - toggleMillis >= 1000UL)
{
error = -2;
Serial.println(F("timeout waiting for ack low"));
break;
}
}
}
}
// If an error occured, the byte is probably not send.
if( error != 0)
n = 0;
else
n = 1;
return( n);
}
The Slave (receives data)
// Toggle with Handshake Communication.
// ------------------------------------
//
// This communication is written for the VGAx code.
// It transfers a byte from a Master Arduino to a Slave Arduino.
// The Slave Arduino is running the VGAx code.
// The Slave code does not use delays, no interrupts,
// and interrupts are not disabled.
//
// Signals are active HIGH, and default LOW.
// LSB first, bit 0 is the first bit to be send.
//
// Four signal wires plus GND:
// dat = data (from Master)
// dtr = data ready (from Master)
// ack = acknowledge (from Slave)
// stx = first bit (from Master)
// GND (connect also both GND of the Arduino boards)
//
// Transfer rate is about 1400 bytes per second for two Arduino Uno boards.
//
// This is the first version, the code might not be fully fail safe at the moment.
//
const int pinDat = A1;
const int pinDtr = A2;
const int pinAck = A3;
const int pinStx = A4;
void setup()
{
Serial.begin(9600);
Serial.println(F("Slave"));
pinMode( pinDat, INPUT);
pinMode( pinDtr, INPUT);
pinMode( pinAck, OUTPUT);
pinMode( pinStx, INPUT);
}
void loop()
{
byte data;
if( ToggleCheck(&data) >= 1) // read incoming bits and check if a byte is received
{
Serial.write( data);
}
// Do other things here in the loop().
// Other code will slow down the transfer rate.
}
// ToggleCheck
// ----------
// Receive a single byte.
// This function should be called in the loop() function every time,
// since it receives bits while being called repeatedly.
// This function is non-blocking, and without waiting.
// The return value is the number of bytes that are received.
// At this moment just one byte is received.
//
int ToggleCheck(byte *pdata)
{
static byte toggle_Data; // variable in which the bits are stored to make a byte.
static byte toggle_Index; // index of bits
static boolean toggle_Ready = true; // ready to read a bit
int n = 0;
int toggleDtr = digitalRead( pinDtr); // read dtr signal first
int toggleStx = digitalRead( pinStx);
int toggleDat = digitalRead( pinDat);
if( toggle_Ready && toggleDtr == HIGH)
{
if( toggleStx == HIGH)
{
toggle_Index = 0;
toggle_Data = 0;
}
if( toggleDat == HIGH)
bitSet( toggle_Data, toggle_Index);
digitalWrite( pinAck, HIGH);
toggle_Ready = false;
toggle_Index++;
if( toggle_Index >= 8)
{
toggle_Index = 0;
// All 8 bits of the data byte have been received.
// Write to *pdata only if the complete and valid data was received.
*pdata = toggle_Data;
n = 1;
}
}
else if (!toggle_Ready && toggleDtr == LOW)
{
digitalWrite( pinAck, LOW);
toggle_Ready = true;
}
return( n);
}
The Slave code is to test the communication. For use with VGAx, the Serial functions have to be removed.