Hi,
I am intending to use an Arduino to simulate different sensors communicating with a master via I2C. When the master asks a sensor my arduino should response to it as if it was the requested sensor. To be able to that, I need my arduino to have different I2C addresses (an address per simulated sensor). Is that possible or at least can I manage this with a soft ?
Thank you.
The I2C is some hardware and some software (the Wire library).
It is not possible to let the hardware respond to different addresses.
There is something else: the Arduino is not able to behave like all sensors. I don't know what the problem was, but I remember reading about it.
Ok maybe I'll try to use an Arduino per sensor but this is not really an optimized solution..
Thank you anyway
After some research I've got an idea to make the arduino simulate different sensors but I'm not sure.
Is it possible in the setup function of the slave (which will be the writer) to insert an "if" condition to the wire.begin(address) and so I give a different address to my arduino. For example :
void setup()
{
if (condition) wire.begin(2);
else wire.begin(4);
Wire.onRequest(requestEvent);
}
The problem for now is that the setup fonction is called once, so can I call it periodically?
And does it make sense ?
More info for the Wire library, Arduino Playground - WireLibraryDetailedReference
Using a condition to set the slave address is valid.
Calling Wire.begin repeatedly with a different slave address might work. I am not sure about that, but I don't know a reason why it should not work.
There is no Wire.end function, which would be useful.
Great then I'll try this out and I'll give you feedback..
ilaam:
And does it make sense ?
Unfortunately, no.
Setup() is designed to only be called once - it is the function used to perform one-off initialisation of the sketch. If you want to make several calls to Wire.begin() during setup, you would need to write setup() so that a single call to setup() made all the calls to begin() that you want.
If you wanted to call wire.begin() after initialisation has completed, during the normal operation of your sketch, you should put those calls in loop() or code called from loop(). However, I'm not optimistic that calling begin() multiple times with different addresses will make wire listen to all the addresses - I suspect that at best it will only stop listening to the old address and start listening to the new address instead. If I understood your original request correctly, this is not what you want.
I was assuming that ilaam gave up on the idea to be different sensors at the same time.
Calling repeatedly Wire.begin after a button selects which sensor to simulate for example.
I'm pretty sure that the Arduino can not simulate all sensors. It might not work after all.
I get it So I won't be able to change the address in the setup() as it is called once.
I'll try to do it in the loop and I'm not optimistic neither because I suppose that the setup function is made for initializing the address and the event handlers so any changes in the loop() may not be considered.
I didn't gave up on the idea of simulating many sensors as this is my goal. I need to simulate many slave sensors using a shipset that communicates via I2C. Only arduino functions as an I2C slave.
maybe you should break this down into a flow chart ?
what is sounds like to me is that you have two micros. one is the master and the other is a slave(a lot of sensors)
on the I2c bus, you send our a request to poll I2c address 0, ( a simulated temperature sensor )
the arduino slave needs to recognize that it needs to be sensor #0 and to output a signal that would simulate a temperature sensor.
then, the master wants to talk to sensor #3 a simulated pressure sensor
so the call on the I2C buss to sensor #3 is made, the slave sees the call to sensor #3 and then outputs a value that would simulate what the pressure sensor would send.
sounds like a StateMachine might work.
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
or http://www.gammon.com.au/forum/?id=12316
step one)
you need to determine what sensor is called.
step two)
run the statemachine for that sensor.
step 3)
output the values that sensor would have.
in this part, you might be able to connect to a real sensor, capture the data and then just replay it
you could use an analog input with a thermistor or light sensor or some such as a variable to alter the output so that the simulated output was not always the same.
Which sensors do you want to emulate ?
Most sensors are cheaper than an Arduino board
Peter_n : I have to simulate many sensors including temperature, pressure, etc but I cannot use real sensors as the network is a bit complex so it is more ergonomic to use just one arduino that does it all.
dave-in-nj : That's exactly what I wan't to do ! The machine state seems very suitable for my problem thank you.
For now, I tried to change the Arduino address during runtime and it worked I just changed it using wire.begin() in the loop() function and tried to synchronise these modifications with the masters' demand so each time it asks an address the arduino has the same address in the same time.
Thank you all
Could you maybe get software I2C slave code and tweak it to respond to multiple addresses?
Hi! I'm trying to do the same thing, need to emulate many sensors with one board and It should be able to respond as any of them. So far the only solution I've came with is to use a software I2C implementation. Is there any software i2c library that allows arduino to behave like slave?, haven't found any yet
I don't know any software I2C library for a slave.
And if there was, it will not be the same as the real sensor, because the timing will be slower.
Luckely the Arduino Wire library (on the Master) allows pulse stretching, so perhaps with some fancy programming it is possible (in theory).
A couple of thoughts as to how to achieve this:
- Look at something like the Bus Pirate. I believe it can simulate an I2C device, so it might be able to simulate more than one. You'll need to write some software in something like processing, and it may still be too slow, but its designed to monitor and interface with I2C (Among other things).
- Write your own code. You could still use the arduino (or the ATMega328/ATmega32u4) to write it, but you'll need to probably write your own drivers. Either you'll just need to change it to be able to monitor multiple channels (might not work), or ignore the Wire library and instead bit-bang your own I2C responses out. The protocol is not /that/ complicated with only a single master.
- Use 5 different Arduino boards, each set up as a different device? Not much different than the various parts really, but its a possibility to stop-gap until you get the full device connected.
I notice that you say "network". This implies something more complicated than I expect. The benefit to I2C is it only requires 2 lines for data transmission of up to 127 devices, so its not as much a network as a bus, with everything tied into it. Also, I2C doesn't work very well past 15 ft (probably out of spec at 15 ft as well, but we have it working at 100kHz).
Is there any software i2c library that allows arduino to behave like slave?, haven't found any yet
I found this : http://www.atmel.com/Images/doc8478.pdf
a library that emulates the hardware TWI module on arduino which checks the address sent by the master.
the software is here : http://www.atmel.com/Images/doc8478.pdf
you need to adapt it (the driver) to your board : change the pins numbers etc.
You also need to compile it with IAR workbench IDE then modify it to change your board behavior according to the slave address.
After that I don't know if you need to use Wire library to communicates because the library is for low level I2C. So maybe you'll need after to adapt your Wire library to the Soft TWI one.
It doesn't seem very simple and let us know if you make it.
Good luck.
Is there any software i2c library that allows arduino to behave like slave?, haven't found any yet
I've found this http://www.atmel.com/Images/doc8478.pdf
It is a software emulation of the hardware TWI module on Arduino which checks the slave address during communication.
You can find the software in the AVR site.
However, you'll need to adapt the driver ot your board : change the pin numbers etc and also change the behavior of your board according to the slave address.
You can compile it only with IAR workbench IDE and maybe you'll have to adapt your wire library too. I think they should be used together (Wire and soft TWI libraries). This is not very simple and not sure if it's gonna work.
Good luck and let us know if you make it.