I'm trying to get my Maple Native to act as master on I2C with an atMega328 as slave. I've successfully gotten I2C working with the bmp085 after some trouble (http://forums.leaflabs.com/topic.php?id=925#post-7931) using software implementation with the Wire.h library, but have yet to get my atMega to respond. The same atMega with the same code works fine as slave with an Arduino Uno as master. Here's the code on the slave:
#include <Wire.h>
int slaveAddress = 0x7f;
int ledPin = 13;
int inData;
void setup() {
Wire.begin(slaveAddress);
Wire.onReceive(receive);
Wire.onRequest(request);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
}
void loop() {
///////////////////////////////////////////////////////////////
// I2C is taken care of in event handlers defined in setup() //
///////////////////////////////////////////////////////////////
for (int i=0; i<inData; i++) { // flash so many times
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
delay(1000);
}
void receive(int num) { // num comes from the number of bytes being received, defined by master
static char inString[16];
static int i;
for (i=0; i<num; i++) {
inString[i] = Wire.read(); // read in a byte
}
inString[i] = ''; // complete the string
inData = atoi(inString); // convert string to integer
}
void request() {
char writeString[16]; // for formating a string to send over I2C
sprintf(writeString, "You rang?\n%d", inData);
Wire.write(writeString);
}
And the master:
#include "Wire.h"
#define ATMEGA_ADDR 0x7f
unsigned long now;
int i = 0;
char inString[16]; // string for storing incoming data
void setup() {
Serial1.begin(115200);
Wire.begin(0,1); // initialize bitbanged (software) i2c protocol
Serial1.println("I2C Bus 1 Initialized");
now = millis();
pinMode(22,OUTPUT);
}
void loop() {
if (Serial1.available() > 0) { // probe the serial monitor for data (not I2C)
char inByte = Serial1.read();
if (inByte == '0' || inByte == '1' || inByte == '2' || inByte == '3' ||
inByte == '4' || inByte == '5' || inByte == '6' || inByte == '7' ||
inByte == '8' || inByte == '9') { // check serial monitor for a digit
inString[i] = inByte; // add the digit to the string
i++; // get ready to read next byte
} else if (inByte == 'S' || inByte == 's') { // check for flash flag
inString[i] = ''; // add null character to end of string
i = 0; // reset for new data
Serial1.print("sending data: ");
Serial1.println(inString);
//////////////////////////////////
// I2C transmission starts here //
//////////////////////////////////
Wire.beginTransmission(0x7f); // initiate I2C transmission
Wire.send(inString); // queue the string to be transmitted over I2C
int r = Wire.endTransmission(); // send string and close transmission
Serial1.println(r);
} else if (inByte == 'R' || inByte == 'r') {
Wire.requestFrom(0x7f, 16); // request 16 bytes from slave
while (Wire.available() > 0) {
char received = Wire.receive();
///////////////////////////
// I2C transmission ends //
///////////////////////////
Serial1.print(received); // read a byte and print over serial
i = 0; // reset to avoid confusion
}
Serial1.print('\n'); // new line
}
}
// blink led to make sure program is running
if (millis() - now > 1000) {
toggleLED();
now = millis();
}
}
The idea here is that from a serial monitor connected to the slave you will type a number followed by "s" (for "send") and the number will be sent to the slave over I2C and a confirmation message will be sent over the serial monitor:
Sending data: <num>
where <num> is the number sent. The slave will then flash an LED that many times, repeated, until a new number is sent. You can also type an "r" (for "ring" or "read") and the master will request data from the slave, whereupon the slave will reply:
You rang?
<num>
where <num> is the last number it received. The message is echoed on the serial monitor.
Again, the code is proved, everything works as expected with the Arduino as master. The only difference in the code between the Arduino master and the Maple master is Wire.begin() vs. Wire.begin(0,1) and Serial vs. Serial1. When running on the Maple, Wire.endTransmission() will return a 2 (I think that's for ENACKADDR).
If anybody has any ideas, your help would be appreciated.