Pages: [1]   Go Down
Author Topic: Issue with TinyWireM only recieving one byte  (Read 1228 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,

Got a big issue trying to transfer data between a ATmega328p using Arduino core/wire and a ATtiny44 (and same issue on ATtiny85) using the tiny core/TinyWire.

The issue is in TinyWireM I request 3 bytes from the 328, I successfully receive the request, and respond with 3 bytes, however TinyWireM only receives the first byte. I ran into the issue when working on a project, but created stripped down code, and still have the issue.

On the master I have:

Code:
#include <Wire.h>

void setup()

{
  Wire.begin(0x9);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
  Serial.begin(9600);
}

void loop() {
}

void receiveEvent(int sizeIn) {

  Serial.println("receive");
 
  byte a = Wire.read();
  byte b = Wire.read();
  byte c = Wire.read();
 
  Serial.println(a,DEC);
  Serial.println(b,DEC);
  Serial.println(c,DEC);
 
}   

void requestEvent() {

  Serial.println("request");

  byte outa = 0x10;
  byte outb = 0x20;
  byte outc = 0x30;
     
  Serial.println(outa);
  Serial.println(outb);
  Serial.println(outc);
     
  Wire.write(outc);
  Wire.write(outb);
  Wire.write(outa);

}


On the slave I have:

Code:
#include <TinyWireM.h>

#define THIS_ADDRESS 0x8
#define OTHER_ADDRESS 0x9

void setup() {
 
  int wireRet = 0;
  TinyWireM.begin();
  //Serial.begin(9600);
  delay(1000);
 
  wireRet = TinyWireM.requestFrom(OTHER_ADDRESS, 3);
  if (wireRet) {
    Serial.println("RcveError: ");
    Serial.println(wireRet,DEC);
  }

  //while(TinyWireM.available()){

  //Serial.println(TinyWireM.available(),DEC);

  //while(TinyWireM.available() < 3){}

  byte a = TinyWireM.receive();
  byte b = TinyWireM.receive();
  byte c = TinyWireM.receive();

  //Serial.println(a,DEC);
  //Serial.println(b,DEC);
  //Serial.println(c,DEC);
 
  TinyWireM.beginTransmission(OTHER_ADDRESS);
  TinyWireM.send(a);
  TinyWireM.send(b);
  TinyWireM.send(c);
  TinyWireM.endTransmission();
 
}

void loop() {
 
}


available() reports 3 bytes are waiting (but maybe only because I requested 3), then first byte is read successfully, but the other two return 255 in decimal

I've had it printing the results by serial on the ATtiny, and sending them back via i2c etc, but the results are the same.

Here is the serial output from the ATmega328:
Code:
request
16
32
48
receive
16
255
255

Can anybody help as to why this isn't working?

BONUS QUESTION: I'm having to do it this way (328 will flag an interrupt pin on an array of ATtiny's, who will then request data from the 328 as to what it needs to do (recalibrate etc). The ATtiny's will also send messages to the 328, so its acting as both master and slave) because I cant get TinyWireM and TinyWireS working together to act as both a slave and master, otherwise the 328 could just send commands to the ATtiny's, and the ATtiny's send data back as needed.

It would be great if anyone was able to help get both TinyWireM and TinyWireS working together?

Regards
Logged

Denver
Offline Offline
God Member
*****
Karma: 20
Posts: 778
Inactive - PM
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Without getting my head into your code, I can say this . . .
 - be sure you are using pullups on the I2C lines
 - TinyWireM and TinyWireS did work together (for me) - at least on the ATtiny85
 - I can give you that code I have that does this if it will help

John
Logged

"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi John,

Yes, 4.7k pullups, transfering data does work, apart from these two issues.

Just tried again using TinyWireM and TinyWireS, and it dosent seem to work. Calling TinyWireM.begin, if I then call TinyWireS.begin(addr) the master cant send, but if I comment TinyWireS.being out, it can (tried reverse order too)

If I can have a look at that code, might help.

Regards
Logged

Denver
Offline Offline
God Member
*****
Karma: 20
Posts: 778
Inactive - PM
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well sorry, it's not as I remembered it. It's two ATtiny85 slaves talking to a ATmega master.
The only ATtiny master code I have are the examples included in the library. There are examples in the slave lib too. I notice your "slave code" uses the master lib - that seems strange.
Hopefully someone can give you a hand with this.
John
« Last Edit: May 05, 2012, 03:27:57 pm by bHogan » Logged

"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi John,

No worries - thanks though.

Quote
I notice your "slave code" uses the master lib - that seems strange.

Basically a multi-master system. Its more important for the "slaves" to be able to push events to the master as they happen, than it is for the master to be able to talk to/poll the "slaves". The arduino wire lib is able to be both a master/slave - so it can talk to other i2c devices on the bus and receive messages from the "slaves". Just cant seem to get it working with TinyWire.

I can successfully send multiple bytes between a beginTransmission/endTransmission, its only the requestFrom that is stuck receiving a single byte.

Fingers crossed someone might have a solution.

Regards
Logged

Denver
Offline Offline
God Member
*****
Karma: 20
Posts: 778
Inactive - PM
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Its more important for the "slaves" to be able to push events to the master as they happen
FWI, the way I did that was for the slave to trigger a pin change interrupt on the master when it had something. (There might be some help in the code for this crazy idea I had.)

Quote
Fingers crossed someone might have a solution.
There are a lot of sharp guys here on I2C.
Good luck, John
Logged

"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

FWI, the way I did that was for the slave to trigger a pin change interrupt on the master when it had something. (There might be some help in the code for this crazy idea I had.)

Indeed. Thats basically what I planned to do, but in reverse. If the master wanted to contact the slaves, it would fire off a interrupt, then the slaves would ask what the master wanted. The slaves would be frequently sending data to the master, but it would be rare (and manually triggered) for the master needed to contact the slaves.

Thanks - will take a look at that code.
Logged

Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys

I am working on a project that sounds similar to what you're facing.  I have multiple Attinys (mixture of 85s and 2313s) all talking with a mixture of Atmegas (328p, 1280, etc).
One thing I found with the Attinys, if you are wanting both master and slave capabilities is you have to do one at a time, switching between them.  You start them all as slaves, then if they need to send data, shutdown the slave, go to master, send whatever, then go back to slave.

Something like this:
Code:
void setup() {
    TinyWireS.begin(attinyAddress);
}

void loop() {
    if (TinyWireS.available) {
        byte command = TinyWireS.read();
        switch (command) {
            case WHATEVER: {
                // reset the I2C pins
                pinMode(0, INPUT);
                pinMode(2, INPUT);
                TinyWireM.begin();
                TinyWireM.beginTransmission(AtmegaAddress);
                TinyWireM.write(stuff);
                TinyWireM.endTransmisison();
                // reset the I2C pins
                pinMode(0, INPUT);
                pinMode(2, INPUT);
                TinyWireS.begin(attinyAddress);
            }
        }
    }
}

This is just a snippit of code that I have been using successfully.

Hope that helps somebody.
Logged

Pages: [1]   Go Up
Jump to: