It's been a while, had to bring up my new website...
But I have made a little progress. Bought a Saleae Logic to help out and then wrote some code.
I first tried the I2C library here http://dsscircuits.com/articles/arduino-i2c-master-library.html and found out that the Slave side of the API isn't there yet: "The new library does not support Slave functions as of yet." This particular application needs both the Master and Slave API, so I had to go with the Wire library. This will cause me some problems later.
To test Wire API, I wrote a single routine that "plays catch" between two Arduinos. Whichever one has the "Ball", lights it's LED.
- I compile once. Connect the serial port to one Arduino, download. Connect to the other Arduino, download. Get's tedious very quickly.
- The initial master is gotten from Pin 5. After that the master and slave swap roles.
- Note that I had to declare the Wire.onReceive(receiveEvent); even though I don't use the interrupt routine. That took a while to figure out.
- It is just as gratifying watching the LEDs light up on the two Arduino's as it was for the very first LED blinker program
- There is a lot of output to the screen so you can follow along as the ball goes back and forth. Note this output for one Arduino (the initial master)
A
B
C
M1: passing the ball
M2: wait for slave...
recv: 1
M3: got it...
M4: and it is an ack; Slave now has the ball.
S1: waiting for ball
recv: 1
S2: got it...
S3: and it is the ball
S4: told master we got the ball
M1: passing the ball
M2: wait for slave...
recv: 1
M3: got it...
M4: and it is an ack; Slave now has the ball.
<and so on>
Next step: try seeding the random number generator on both Arduino's to see if a simple AnalogRead(0) works.
John
// for I2C stuff: http://www.gammon.com.au/forum/?id=10896
// for i2c lib: http://dsscircuits.com/articles/arduino-i2c-master-library.html
#include "WProgram.h"
#include "Wire.h"
#define CONFIGPIN 5
#define THEBALL 0x88
#define GOTTHEBALL 0x66
static enum
{
master = 0,
slave = 1,
} state;
int myaddr = 1;
int destaddr = 2;
//===========================
void receiveEvent(int howMany)
{
Serial.print("recv: ");
Serial.println(howMany, DEC);
}
//===========================
void setup()
{
Serial.begin(9600);
Serial.println("A");
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
pinMode(CONFIGPIN, INPUT);
// the Config pin indicates who starts off as the master
int v = digitalRead(CONFIGPIN);
if (v == HIGH)
{
state = master;
myaddr = 1;
destaddr = 2;
// the LED indicates who has the ball (the master)
digitalWrite(13, HIGH);
}
else
{
state = slave;
myaddr = 2;
destaddr = 1;
// the LED indicates who has the ball
digitalWrite(13, LOW);
}
Serial.println("B");
//Start the wire session using our own address
Wire.begin(myaddr);
//Even though receiveEvent is empty, got to use it in the setup
Wire.onReceive(receiveEvent);
// empty the input buffer of any garbage
while (Wire.available() > 0)
{
Wire.receive();
}
Serial.println("C");
}
//===========================
void loop()
{
if (state == master)
{
// send the ball to the slave
Serial.println("M1: passing the ball");
Wire.beginTransmission(destaddr);
Wire.send(THEBALL);
Wire.endTransmission();
// wait for slave to acknowledge it has the ball
Serial.println("M2: wait for slave...");
int timeout = 0;
const int maxtimeout = 500;
while (timeout < maxtimeout && Wire.available() < 1)
{
delay(1);
timeout++;
}
if (timeout >= maxtimeout)
{
Serial.println("M3: timeout, trying the send again");
}
else
{
Serial.println("M3: got it...");
// check it is a good value (GOTTHEBALL)
byte c = Wire.receive();
if (c == GOTTHEBALL)
{
Serial.println("M4: and it is an ack; Slave now has the ball.");
}
else
{
Serial.print("M4: error unexpected byte: ");
Serial.println(c, HEX);
}
// convert to a slave
state = slave;
// don't have the ball anymore, so clear the LED
digitalWrite(13, LOW);
}
}
else // state == slave
{
// wait for the incoming ball
Serial.println("S1: waiting for ball");
int count = 0;
while (Wire.available() < 1)
{
delay(1);
count++;
if (count > 500)
{
count = 0;
Serial.println("S2: still waiting...");
}
}
Serial.println("S2: got it...");
// consume the byte that was read
byte c = Wire.receive();
if (c == THEBALL)
{
Serial.println("S3: and it is the ball");
}
else
{
Serial.print("Sx: error unexpected byte: ");
Serial.println(c, HEX);
}
// send response to master
Wire.beginTransmission(destaddr);
Wire.send(GOTTHEBALL);
Wire.endTransmission();
Serial.println("S4: told master we got the ball");
// convert to the master
state = master;
// we have the ball now, so indicate the we have it
digitalWrite(13, HIGH);
// wait for a while before passing the ball back...
delay(500);
}
}
//===========================
int main()
{
init();
setup();
for (;;)
{
loop();
}
return 0;
}