rambo / TinyWire

My modifications to TinyWire Arduino libs
284 stars 121 forks source link

send() function outside onRequest() event #3

Closed klawyMarcin closed 11 years ago

klawyMarcin commented 11 years ago

When I'm trying to send something via send() to Master device directly from the main loop it doesn't work(slave just stops working. I know it has something to do with a buffer). Moreover onReceive event also doesn't work :/

I'm using Attiny45@8MHz (int. osc.) as a slave and Arduino Uno as master.

And a little bit of code for slave:

include "TinyWireS.h"

void setup() { TinyWireS.begin(0x26); TinyWireS.onReceive(tester); } void loop() { }

void tester (byte zzz){ PORTB ^= _BV(4);
}

And for master:

include

void setup() { Wire.begin(); }

void loop() { Wire.beginTransmission(0x26); Wire.write(B11111111); Wire.endTransmission(); }

Any Idea what Am I doing wrong? :/

rambo commented 11 years ago

You need to empty the buffer on receive

void receiveEvent(uint8_t howMany)

so call read howMany times.

while(howMany--) { TinyWireS.receive(); }

also remember to call TinyWireS_stop_check(); on the slave mainloop.

As for sending data to master, while in theory you could queue data to the buffer anywhere you will somehow need to make sure you will only attempt to send as much data as the master is trying to read (or buffer will fill and the send will block untill space is freed). Thus I only recommend calling send from requestEvent

klawyMarcin commented 11 years ago

Ok thanks :D Finally receivig works like a charm! Now i have to work with sending (I need to send Integer, but in "onRequest" can't be more than one byte per one onRequest...)

klawyMarcin commented 11 years ago

Is there a way to flush send buffer?

rambo commented 11 years ago

No way to flush at the moment, to send integer send the upper and lower halfs as bytes, the master must know it's going to read two bytes and combine into int. you will need to track on the requestevent at which point you are.

I recommend keeping an array of "registers" like in the example and on the master side to read the int first write 0 (the address to start reading from) and then on every read increment the register address. This is very common convention in I2C devices.

If you want to send for example data from the ADC then in mainloop every once in a while write the int to the register (first read to int, then split to two bytes to the register) and the master can then read at it's leisure.