I want to create an arduino I2C slave that acts similarly the the SRF08, the SRF08 uses registers which can me accessed using a write from the master. see code below: How can I get this done?
- SRF08 code-------------------
#include <TwoWire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(19200); // start serial communication at 19200bps
}
int reading = 0;
void loop()
{
// step 1: instruct sensor to read echoes
Wire.beginTransmission(112); // transmit to device #112 (0x70)
// the address specified in the datasheet is 224 (0xE0)
// but i2c adressing uses the high 7 bits so it's 112
Wire.send(0x00); // sets register pointer to the command register (0x00)
Wire.send(0x51); // command sensor to measure in cm (0x51)
// use 0x52 for ping microseconds
Wire.endTransmission(); // stop transmitting
// step 2: wait for readings to happen
delay(70); // datasheet suggests at least 65 milliseconds
// step 3: instruct sensor to return a particular echo reading
Wire.beginTransmission(112); // transmit to device #112
Wire.send(0x02); // sets register pointer to echo #1 register (0x02)
Wire.endTransmission(); // stop transmitting
// step 4: request reading from sensor
Wire.requestFrom(112, 2); // request 2 bytes from slave device #112
// step 5: receive reading from sensor
if(2 <= Wire.available()) // if two bytes were received
{
reading = Wire.receive(); // receive high byte (overwrites previous reading)
reading = reading << 8; // shift high byte to be high 8 bits
reading |= Wire.receive(); // receive low byte as lower 8 bits
Serial.println(reading); // print the reading
}
delay(250); // wait 250ms
}
There's nothing "magic" about the register pointer: it's simply the first data byte in the packet. So just write your I2C slave code so it examines the first received byte and treats it as an "opcode" for deciding how to interpret the rest of the packet.
Some languages expect a register when accessing I2C like Lejos
getData:
public int getData(int register, byte[] buf, int len)
Executes an I2C read transaction and waits for the result.
Parameters:
register - I2C register, e.g 0x41
buf - Buffer to return data
len - Length of the return data
Returns:
status == 0 success, != 0 failure
sendData:
public int sendData(int register, byte[] buf, int len)
Executes an I2C write transaction.
Parameters:
register - I2C register, e.g 0x42
buf - Buffer containing data to send
len - Length of data to send
Returns:
status zero=success, non-zero=failure
so instead of using "registers" could I have a case construct which selects different operations or data stored in varibales based on a variable which stores the first byte. eg algorithm
wait for first byte from master [register?]
store first byte in a variable called option
use a case construct that selects based on the value in 'option'
execute case
Yes. There are lots of protocols that use this type of approach for communication. Basically, you want your arduino to sit and listen on its data line for some kind of trigger (the SRF08 uses registers, other protocols use sync bits, etc.) This is usually a unique byte that tells your device to get ready to do something. Once that's triggered, you know the next message you receive is going to be a command. Then you can use a case statement or something to compare the command you read with the list of commands your arduino is able to execute. If it matches something, execute the command and return your data, otherwise you can ignore the command and/or throw back some kind of error code. At this point you go back to listening for your trigger. Your psuedocode correctly prototyped this sequence.
The SRF08 uses different registers to access different categories of functionality (commands, configuration, etc). It just provides a way to organize the command set, and makes sure you're never going to mess up the configuration if all of your requests are for the command register.
No, the address is separate from the register. The address specifies which device on the bus you want to talk to, and then the register is used to request information/change device settings, depending on which one you use. The list of registers for the srf08 are here: SRF08 Ultra sonic range finder