Author Topic: I2C digispark slave of arduino  (Read 20902 times)

effedebe

  • Newbie
  • *
  • Posts: 8
I2C digispark slave of arduino
« on: November 02, 2013, 09:00:28 am »
Hi,
I would like to use a digispark to make sound of my robot.
I would like if it is possible, to drive my digispark about my arduino uno by I2c.

- Is it possible to use I2C inbetween Uno & digispark ?

I'm looking for the adress of digispark.
- Anyone know how to find it ?

I've found this closed topic about this subject:
http://digistump.com/board/index.php/topic,743.msg2623.html#msg2623
I want to know more.

thx


« Last Edit: November 02, 2013, 09:02:19 am by effedebe »

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: I2C digispark slave of arduino
« Reply #1 on: November 02, 2013, 01:50:40 pm »
Thats all, you need to know.
https://github.com/qistoph/TinyWire
TinyWireS is the slave-library.  Read the docu-file!

It works just as described in the thread you have linked!

effedebe

  • Newbie
  • *
  • Posts: 8
Re: I2C digispark slave of arduino
« Reply #2 on: November 04, 2013, 02:33:27 am »
It's perfect. That's work !

Thank you a lot !

effedebe

  • Newbie
  • *
  • Posts: 8
Re: I2C digispark slave of arduino
« Reply #3 on: November 04, 2013, 09:45:26 am »
but not exaclty ..

My victory was: the master have found adress of slave :)

I send some values that return after (from master to slave & slave to master)
I sent 1, and slave return to master 255.

Is this because my pullup resistors are to 4.7 k ?

Some times somes projects use 3.3 k , 2.2 k. Why it is differents ?

Inbetween an arduino (master) and a digispark (slave) is it same resisors that inbebteen two arduinos uno ?
Is that correct to uses 4.7 k resistors when they are a digistark + arduino uno ?

Master code (arduino UNO):
Code: [Select]
#include "Wire.h"
byte reading = 0;

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

void loop()
{
    Wire.beginTransmission(0x26);
    Wire.write(1);
    Wire.endTransmission();
   
    Wire.requestFrom(0x26,1);       
    while(Wire.available())
    {
      reading = Wire.read();
      Serial.println(reading); // this return 255 value ??
    }
}


Slave code Digispark:
Code: [Select]
#include "TinyWireS.h"
#define I2C_SLAVE_ADDR  0x26
#define LED_pin 5

void blink()
{
      digitalWrite(LED_pin,HIGH);
      delay (250); 
      digitalWrite(LED_pin,LOW);
      delay (250); 
}

void setup()
{
pinMode(LED_pin,OUTPUT);
TinyWireS.begin(I2C_SLAVE_ADDR);
}

void loop()
{
byte received = 0;

if (TinyWireS.available()) // got I2C input!
{           
received = TinyWireS.receive();     // get the byte from master

if (received == 1)
                {
                    blink();
                    TinyWireS.send(1);
                }
}
}




thx
« Last Edit: November 10, 2013, 09:27:17 pm by effedebe »

DeuxVis

  • Full Member
  • ***
  • Posts: 107
Re: I2C digispark slave of arduino
« Reply #4 on: November 05, 2013, 04:57:28 am »
Can't reply to your question, but I  see you are using fritzing, I made a digispark part for this software : http://digistump.com/board/index.php/topic,615.msg2868.html

I should will submit it for integration into fritzing.

effedebe

  • Newbie
  • *
  • Posts: 8
Re: I2C digispark slave of arduino
« Reply #5 on: November 07, 2013, 05:10:26 am »
thx that seems to be better like that;)
(changed to the first image ;) )
« Last Edit: November 10, 2013, 09:28:00 pm by effedebe »

MichaelMeissner

  • Full Member
  • ***
  • Posts: 166
Re: I2C digispark slave of arduino
« Reply #6 on: November 07, 2013, 09:01:28 am »
Given that wiring diagram, the Digispark has to be powered presumably through the USB port, since there was no wire connecting the power to a common source.

sorphin

  • Newbie
  • *
  • Posts: 6
Re: I2C digispark slave of arduino
« Reply #7 on: November 09, 2013, 11:42:01 pm »
I'm actually doing exactly this in my EVSE (for my Leaf).. I have a digispark running the RFID reader. The digispark is a slave of the main 328p. I then have another 328p driving a 2nd LCD and being a software master to an eeprom, and slave to the main 328p. So there's a lot of i2c involved. :-)

The main 328p uses the Wire library, the EMON 328p is using Wire for slave and SoftI2C for master, the digispark is using TinyWireS.h

effedebe

  • Newbie
  • *
  • Posts: 8
Re: I2C digispark slave of arduino
« Reply #8 on: November 10, 2013, 09:31:46 pm »
Given that wiring diagram, the Digispark has to be powered presumably through the USB port, since there was no wire connecting the power to a common source.
Yes !  (It was just a forgot into my image thanks you, It is  changed into the first image)

I'm actually doing exactly this in my EVSE (for my Leaf).. I have a digispark running the RFID reader. The digispark is a slave of the main 328p. I then have another 328p driving a 2nd LCD and being a software master to an eeprom, and slave to the main 328p. So there's a lot of i2c involved. :-)

The main 328p uses the Wire library, the EMON 328p is using Wire for slave and SoftI2C for master, the digispark is using TinyWireS.h

Why is it better to use SoftI2C ?

sorphin

  • Newbie
  • *
  • Posts: 6
Re: I2C digispark slave of arduino
« Reply #9 on: November 11, 2013, 12:35:03 pm »
Why is it better to use SoftI2C ?

No choice.

Wire.h can't be a master and a slave (at least it doesn't work for me) on the same host. It locks up the i2c bus when the EMON is polling the eeprom to give the data back to EVSE. So I need to have them on 2 seperate busses. This being the case, I have to use a software i2c to accomplish this (since the 328p has a single i2c bus). This is my setup:

[EVSE Master] <-> [EMON Master/Slave] <-> [EEPROM Slave]
                         |---<-> [RGB LCD Slave]


effedebe

  • Newbie
  • *
  • Posts: 8
Re: I2C digispark slave of arduino
« Reply #10 on: November 16, 2013, 06:40:24 am »
Nobody know why my values are 255 ?

thx

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: I2C digispark slave of arduino
« Reply #11 on: November 18, 2013, 09:37:06 am »
Just had some minutes, to compare your code against some code, which is working for me:

If you stop calling blink(); on the digispark, everything works ok. 

The hint is seen in the example to TinyWireS, which also performs a blink:
Code: [Select]
Blink(LED1_PIN,byteRcvd);           // master must wait for this to finish before calling Wire.requestFrom
The problem is, that you are not ready to send something, while the master is already asking for more data. The library is broken in the fact, that you can't control the clock-line (clock-stretching), to tell the master, that you are not ready yet.

In that case the master reads 8 times the high-level of SDA, which is 255!

There are newer versions of the underlying library from Don Blake available, however I found no updated arduino-library in short time.

Check, if you find some newer library, which gives you control to the clock-line.

I had good luck with my implementation, as I defined 255 as "value out of range", which is discarded from the calling application ;-)


gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: I2C digispark slave of arduino
« Reply #12 on: November 19, 2013, 01:14:33 am »
I digged a little bit deeper into the I2C theme:

I found one library at github (https://github.com/eriksl/usitwislave) which is based on Don Blakes library. However the author has rewritten the library in a much better style for understanding.

The problem with USI I2C is:  There is one 8-bit shift register (USIDR) for incoming and outgoing data. In Receive mode, the content of that register is copied to an incoming buffer, while sending the content of that register is sent out over the wire.  There is a counter running, which generates an overflow interrupt everytime, 8bits are received/sent.  The interrupt handler is now responsible to move the content to/from receiving/sending buffers. While transferring to/from buffer the interrupt handler pulls SCL to low, to delay the I2C master.

Whenever you write to I2C, you are only storing data to the buffer; when you are reading from I2C, you are pulling data out of that buffer.  The real communication happens interrupt triggered in the background.

What is now missing from my current understanding is an additional state change in the state-engine. As soon, as the slave changes to send state, the overflow interrupt handler should be aware of it and needs to take SCL to low, while there is no data in the outgoing buffer, which could transferred to the USIDR register.

When you look now to the following piece of code (taken from the thread starters example, comments changed):
Code: [Select]
if (TinyWireS.available())  {   // the input buffer is not empty!
received = TinyWireS.receive();    // pull out one byte from input buffer
                // unclear status ? ? ?
if (received == 1)
                {
                    blink();
                    TinyWireS.send(1);
                }
}

After pulling out one byte from the input buffer (maybe the last, maybe not) the status is not clear. 
When writing a communication protocol, you should first hand make sure, that there are no more bytes in the receive buffer, and you are working on the whole command.
That could be done by checking ! TinyWireS.available() before writing an response to the output buffer.

But that does not solve the problem with reading 0xFF, when there is no output data available in the buffer.  Here I miss some piece of data, which pulls SCL low, when receiving an READ command, but the buffer is empty.
When SCL is not pulled to low, the Master reads all the time 0xFF, as SCA is pulled high with the resistors.  The only way, preventing the master from reading, is stretching the clock!
However, I have not yet fully understand the details of USI.

The Atmel background information is here:
www.atmel.com/Images/doc2560.pdf
http://www.atmel.com/images/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf    Chapter 15

regards

  Gogol
« Last Edit: November 19, 2013, 01:20:07 am by gogol »

effedebe

  • Newbie
  • *
  • Posts: 8
Re: I2C digispark slave of arduino
« Reply #13 on: January 10, 2014, 08:31:46 am »
Thank you.
I will try again.
I must stop my projet for now.