I2C Arbitraje perdido en ATtiny85

0

Soy nuevo en I2C y estoy intentando que dos ATtiny85 se hablen entre sí.

  • Tengo Arduino IDE 1.8.0
  • Utilicé este enlace (damellis) para instalar el tablero de ATtiny en el IDE
  • Utilizo un Arduino nano para programar el ATtiny85.
  • Utilizo esta biblioteca TinyWire de lucullusTheOnly.

El ATtiny tiene que ser capaz de ser maestro y esclavo. Basé mi código en este ejemplo de lucullusTheOnly.

Tengo un programa muy simple (ver más abajo) que envía un carácter en el bus, pero aparece un error 0x0C USI_TWI_ARBITRATION_LOST .

Reduje mi configuración solo al maestro en el tablero con 5kOhm pullups en los dos cables I2C (2x10kOhm en paralelo) a 5V para eliminar el resto del tráfico. Pero el error permanece. Realmente nada más en el tablero.

ATtiny pin usage
3 --> 1kOhm --> LED --> GND (for flashing out error-code)
4 --> GND
5 --> Pullup 5kOhm --> 5v
6 --> Pullup 5kOhm --> 5v
8 --> 5V

No tengo un alcance para controlar el tráfico en el bus. Puedo ir a un laboratorio la próxima semana, pero eso es una larga espera; - /

En Arduino IDE, tengo la velocidad de reloj de ATtiny configurada en 1Mhz (estaba predeterminada). ¿Podría ser el problema? ¿Debo aumentar eso? ¿Puedo simplemente cambiar eso en el menú Herramientas > Reloj? Pensé que leí en algún lugar que también tenía que grabar el gestor de arranque.

Programa de prueba:

#include <TinyWire.h>

int error_led_pin = 3; // == physical pin 2 on attiny

byte own_address = 10;
byte slave_address = 11;


void setup() {
   // config error_led_pi as Output for driving an LED
   pinMode(error_led_pin, OUTPUT);   
   // config TinyWire library for I2C slave functionality
   TinyWire.begin( own_address );

   TinyWire.beginTransmission( slave_address );
   // fill the send buffer
   TinyWire.send('b');
   // execute the master sending and check for an error
   // returns 0 if there was no error (otherwise you can find the different error code definitions in TinyWire.h)
   int errorCode = TinyWire.endTransmission();
   if(errorCode!=0) {
      // turn on the error LED, if there was an error
      handleError(errorCode);
   }
}

void loop() {

}

void handleError(int code) {
   if (code != 0) {
      // *** ERROR ***
      // errors defined at https://github.com/lucullusTheOnly/TinyWire/blob/master/TinyWire.h
      digitalWrite(error_led_pin, LOW); // TODO: remove!
      delay(500);
      // blink resultCode number of times  // TODO: should be led at pin 2 = push button
      for (int i = 0; i <= code; i++) {
         digitalWrite(error_led_pin, HIGH);
         delay(500);
         digitalWrite(error_led_pin, LOW);
         delay(500);
      }
   }
}

¿Alguna idea sobre cómo descubrir por qué obtengo USI_TWI_ARBITRATION_LOST?

    
pregunta mvermand

3 respuestas

2

He visto esta biblioteca en GitHub de donde la obtuviste y miré el archivo TinyWire.h . Esto es lo que dice sobre la excepción que está recibiendo.

" #define USI_TWI_ARBITRATION_LOST 0x0C // The master lost the arbitration due to the transmission of another master "

Parece que estás tratando de hacer I2C entre más de un maestro cuando en realidad necesitas un esclavo. Así es como funciona I2C. Por lo tanto, cuando recibe este error, existe un conflicto de intereses con su I2C y no permitirá que uno de los maestros se conecte hasta que tenga un esclavo.

He intentado buscar otro código para ver dónde el autor de esta biblioteca de TinyWire ha demostrado dónde se produce esta excepción, pero no he encontrado nada más al respecto.

EDITAR: ¡Espera! Encontré algo al respecto ... Esto está en el archivo twi.cpp .

#ifdef BUS_ARBITRATION if(!ack && (USISR & (1<<USIDC))) { // Check data collision bit Twi_slave_init(slaveAddress); result.result = 0; result.error_code = USI_TWI_ARBITRATION_LOST; return result;

Mirando esta declaración if aquí, si no ha habido acuse de recibo del esclavo mientras USISR (que parece ser una variable para un indicador) realiza una operación AND con USIDC = 0 ( USIDC se define desde arriba) que siempre te dará cero, generará esa excepción. En otras palabras, si su esclavo no lo reconoce y si los indicadores se establecen en cero, obtendrá este error.

    
respondido por el KingDuken
1

Un maestro de I2C pensará que ha perdido el arbitraje si libera el pin SDA y el pin SDA no se eleva. Puede suceder si tiene demasiada capacitancia en el bus y, por lo tanto, el aumento de SDA es lento. Esto puede ser un gran problema, especialmente en altas frecuencias.

Intente reducir la resistencia de pullup a 1k y vea si eso ayuda.

    
respondido por el Annie
0

No se puede hablar entre maestros I2C. Necesitas un amo y un esclavo. Vea también ¿Por qué no pueden hablar los maestros? entre sí en un bus I2C? .

Recibes el error porque tus dos maestros están tratando de subirse al bus I2C y uno de ellos pierde.

    
respondido por el Oldfart

Lea otras preguntas en las etiquetas