Связь I2C между Attiny85 в качестве ведущего устройства и Arduino UNO в качестве ведомого устройства

Я хочу, чтобы мои Attiny85 и Arduino UNO взаимодействовали друг с другом по протоколу I2C. Поскольку Attiny не поддерживает библиотеку Wire, я использую TinyWire от lucullusTheOnly и Wire на Uno.

Attiny отправляет данные в качестве ведущего устройства Uno, ведомого устройства.

Вот мой код:

Мастер

#include <TinyWire.h>

byte slave_address = 10;


void setup() {
    // настраиваем библиотеку TinyWire для основной функциональности I2C
    TinyWire.begin();
}

void loop() {
    TinyWire.beginTransmission(slave_address);
    TinyWire.send('c');
    // endTransmission отправляет байты из буфера ведомому устройству и возвращает 0, если ошибки не было
    TinyWire.endTransmission();
    delay(500);
}

Раб

#include <Wire.h>

void setup() {
  Wire.begin(10);                // подключаемся к шине i2c по адресу №10
  Wire.onReceive(receiveEvent); // регистрируем событие
  Serial.begin(9600);           // запускаем последовательный порт для вывода
}

void loop() {
  delay(100);
}

// функция, которая выполняется всякий раз, когда данные получены от мастера
// эта функция регистрируется как событие, см. setup()
void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // цикл по всем, кроме последнего
    char c = Wire.read(); // получаем байт как символ
    Serial.print(c);         // печатаем символ
  }
  int x = Wire.read();    // получаем байт как целое число
  Serial.println(x);         // печатаем целое число
}

Я подключаю контакт следующим образом:

Arduino --> Attiny
SCL ---- PIN 7
SDA ---- PIN 5

Я пытаюсь подключить тактовую частоту и линию передачи данных с помощью резисторов 2,2 кОм, но ничего не происходит, я ничего не получаю на Uno от Attiny. Есть идеи ? Спасибо!

, 👍1

Обсуждение

Также вопрос: http://forum.arduino.cc/index.php?topic=524760. Если вы собираетесь это сделать, пожалуйста, будьте достаточно внимательны, чтобы добавить ссылки на другие места, где вы размещаете перекрестные сообщения. Это позволит нам избежать траты времени из-за дублирования усилий, а также поможет другим, у кого возникнут такие же вопросы и кто найдет ваше сообщение, найти всю необходимую информацию., @per1234

Согласно правилам Stackexchange, я не думаю, что он обязан публиковать ссылки на другие форумы, где он просил ответить. Это его выбор. Тем не менее, спасибо за размещение ссылки на форумы, это поможет другим читателям., @dsignr


2 ответа


Лучший ответ:

1

Основная функциональность библиотеки TinyWire в настоящее время содержит ошибки. В качестве обходного пути вы можете запустить библиотеку на ATTiny также как подчиненную с адресом. При вызове функции endTransmission() библиотека временно переключается в главный режим для отправки байтов. Я протестировал это с вашим кодом в своей собственной настройке, и он работает. (Убедитесь, что частота в ATTiny установлена правильно. Я тестировал библиотеку только на 8 МГц. Для моего собственного ATTiny мне пришлось сделать дополнительный шаг и установить правильные фьюзы с помощью avrdude)

Я думаю, что чистая основная часть блокируется после первой передачи. Я добавлю проблему в проект github. Возможно, со временем я смогу это исправить.

Крисл, он же lucullusTheOnly

РЕДАКТИРОВАТЬ: мне пришлось подумать об этом и заглянуть в библиотеку. Проблема нашлась легко. В twi.cpp есть блок определения NOISE_TESTING в главной функции отправки/получения, который постоянно вызывает ошибку №6 (неожиданное условие остановки). В подчиненном режиме этого не происходит, поскольку непосредственно перед отправкой в качестве ведущего он вызывает функцию инициализации ведущего устройства, которая очищает все флаги USI, включая флаг условия остановки, опрашиваемый в функции отправки/получения.

Я деактивировал NOISE_TESTING в проекте github. Если вы не хотите загружать текущую версию, вы можете просто открыть twi.h и прокомментировать определение NOISE_TESTING.

,

Наконец-то я перехожу на библиотеку Serial, но скоро протестирую ваш новый код!, @Hugo Delannoy


0

У меня та же проблема, хотя у меня установлена последняя версия Github с отключенным блоком определения NOISE_TESTING.

Я полагаю, что это как-то связано со строкой 359 в TWI.cpp, где условие остановки не выдается, если происходит NACK:

      if( temp_result.result & (1<<TWI_NACK_BIT) ) 
  {
    if ( USI_TWI_state.addressMode )
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
    else
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
    return (FALSE);
  }

Я думаю, так и должно быть:

      if( temp_result.result & (1<<TWI_NACK_BIT) )
  {
    if ( USI_TWI_state.addressMode )
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
    else
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
    USI_TWI_Master_Stop();
    return (FALSE);
  }

Я попробовал это на ISIS только в чистом мастере, и это сработало. Я не знаю, является ли это жизнеспособным решением или оно вызовет какой-либо конфликт с тем, как работает остальная часть библиотеки.

,