Связь 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. Есть идеи ? Спасибо!
@Hugo Delannoy, 👍1
Обсуждение2 ответа
Лучший ответ:
Основная функциональность библиотеки 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
У меня та же проблема, хотя у меня установлена последняя версия 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 только в чистом мастере, и это сработало. Я не знаю, является ли это жизнеспособным решением или оно вызовет какой-либо конфликт с тем, как работает остальная часть библиотеки.
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- OVF в последовательном мониторе вместо данных
- ЖК-дисплей I2C отображает странные символы
- I2C с ATtiny85 на частоте 8 МГц с использованием библиотеки TinyWireM
- Соединение I2C зависает Ведущий если ведомый отключается
- Экран LCD 16*02 I2C показывает только первый напечатанный символ
Также вопрос: http://forum.arduino.cc/index.php?topic=524760. Если вы собираетесь это сделать, пожалуйста, будьте достаточно внимательны, чтобы добавить ссылки на другие места, где вы размещаете перекрестные сообщения. Это позволит нам избежать траты времени из-за дублирования усилий, а также поможет другим, у кого возникнут такие же вопросы и кто найдет ваше сообщение, найти всю необходимую информацию., @per1234
Согласно правилам Stackexchange, я не думаю, что он обязан публиковать ссылки на другие форумы, где он просил ответить. Это его выбор. Тем не менее, спасибо за размещение ссылки на форумы, это поможет другим читателям., @dsignr