|
#include "Arduino.h" |
|
#include <Wire.h> |
|
// The code is inspired by the example given at http://dsscircuits.com/articles/arduino-i2c-slave-guide |
|
|
|
|
|
/* |
|
* Set right motor speed |
|
* i2cset -y 1 0x29 0x04 501 w |
|
* Set left motor speed |
|
* i2cset -y 1 0x29 0x03 501 w |
|
* Get left sensor |
|
* i2cget -y 1 0x29 0 w |
|
* $0x0400 |
|
* Get right sensor |
|
* i2cget -y 1 0x29 2 w |
|
* $0x012d |
|
* */ |
|
|
|
/********************************************************************/ |
|
|
|
#define SLAVE_ADDRESS 0x29 //slave address,any number from 0x01 to 0x7F |
|
#define REG_MAP_SIZE 5 |
|
#define MAX_SENT_BYTES 3 |
|
#define IDENTIFICATION 0x0D |
|
|
|
#define LEFT_SENSOR_ADDRESS 0 |
|
#define RIGHT_SENSOR_ADDRESS 2 |
|
#define LEFT_MOTOR_ADDRESS 3 |
|
#define RIGHT_MOTOR_ADDRESS 4 |
|
void storeData(); |
|
|
|
/********* Global Variables ***********/ |
|
byte registerMap[REG_MAP_SIZE]; |
|
byte registerMapTemp[REG_MAP_SIZE]; |
|
byte receivedCommands[MAX_SENT_BYTES]; |
|
byte newDataAvailable = 0; |
|
|
|
//on arduino uno this is 2 bytes |
|
int leftMotorSpeed = 1; |
|
int rightMotorSpeed = 2; |
|
int rightSensor = 301; |
|
int leftSensor = 1024; |
|
|
|
void setup() { |
|
Serial.begin(9600); |
|
Wire.begin(SLAVE_ADDRESS); |
|
Wire.onRequest(requestEvent); |
|
Wire.onReceive(receiveEvent); |
|
registerMap[13] = IDENTIFICATION; // ID register |
|
} |
|
|
|
void loop() { |
|
storeData(); |
|
newDataAvailable = 1; |
|
} |
|
|
|
void storeInt(byte startIndex, int* ptr) { |
|
byte arrayIndex = startIndex; |
|
byte * bytePointer = (byte*) ptr; //latitude is 4 bytes |
|
for (int i = 0; i < 2; i++) { |
|
registerMapTemp[arrayIndex] = bytePointer[i]; //increment pointer to store each byte |
|
arrayIndex++; |
|
} |
|
} |
|
|
|
void reStoreInt(byte address, int* ptr) { |
|
|
|
int tmp = receivedCommands[1]; |
|
tmp += (receivedCommands[1 + 1] << 8); |
|
*ptr = tmp; |
|
char buffer[200]; |
|
sprintf(buffer, "Setting address %d = %d", address, *ptr); |
|
Serial.println(buffer); |
|
} |
|
|
|
void storeData() { |
|
|
|
storeInt(0, &leftSensor); |
|
storeInt(2, &rightSensor); |
|
} |
|
|
|
void requestEvent() { |
|
if (newDataAvailable) { |
|
for (int c = 0; c < (REG_MAP_SIZE - 1); c++) { |
|
registerMap[c] = registerMapTemp[c]; |
|
} |
|
} |
|
|
|
newDataAvailable = 0; |
|
|
|
//Set the buffer to send all 14 bytes |
|
Wire.write(registerMap + receivedCommands[0], REG_MAP_SIZE); |
|
} |
|
|
|
void receiveEvent(int bytesReceived) { |
|
for (int a = 0; a < bytesReceived; a++) { |
|
if (a < MAX_SENT_BYTES) { |
|
receivedCommands[a] = Wire.read(); |
|
} else { |
|
Wire.read(); // if we receive more data then allowed just throw it away |
|
} |
|
} |
|
|
|
if (bytesReceived == 1 && (receivedCommands[0] < REG_MAP_SIZE)) { |
|
return; |
|
} |
|
|
|
if (bytesReceived == 1 && (receivedCommands[0] >= REG_MAP_SIZE)) { |
|
receivedCommands[0] = 0x00; |
|
return; |
|
} |
|
|
|
switch (receivedCommands[0]) { |
|
case RIGHT_MOTOR_ADDRESS: |
|
reStoreInt(receivedCommands[0], &leftMotorSpeed); |
|
return; |
|
case LEFT_MOTOR_ADDRESS: |
|
reStoreInt(receivedCommands[0], &rightMotorSpeed); |
|
return; |
|
default: |
|
return; // ignore the commands and return |
|
} |
|
|
|
} |