Как отправлять данные через I2C без проводной библиотеки?
У меня есть следующий цифровой потенциометр: DS1803-100, которым, согласно спецификации, можно управлять с помощью двухпроводного последовательного интерфейса. Мне удалось заставить его работать с помощью провода, однако я не могу заставить его работать, используя только digitalWrite (ссылка на код). Кто-нибудь может сказать мне, почему? Для справки, 0x50-это бит адреса + r/!w, 0xA9-это команда (запись в pot 0 в моем случае), а следующий 0xA9-это значение для записи. Я знаю, что с кодом что-то не так, но не могу понять, что именно. Заранее благодарю вас!
EDIT: Вот код
int PIN_SCK = 12;
int PIN_SDA = 11;
const int delayvalue = 10;
void setup(){
digitalWrite(PIN_SCK, 1); // I can first declare the state
digitalWrite(PIN_SDA, 1);
pinMode(PIN_SCK, OUTPUT); // then turn them on
pinMode(PIN_SDA, OUTPUT);
delay(1000);
digitalWrite(PIN_SDA, 0); // start bit
shift_out(PIN_SDA, PIN_SCK, 0x50);
shift_out(PIN_SDA, PIN_SCK, 0xA9);
shift_out(PIN_SDA, PIN_SCK, 0xA9);
digitalWrite(PIN_SDA, 1); // stop bit
}
void loop(){
}
// uint8_t is the same as 8 bits aka one byte
void shift_out(uint8_t datapin, uint8_t clockpin, uint8_t val){
uint8_t i;
for (i = 0; i < 8; i++) {
digitalWrite(datapin, !!(val & (1 << (7 - i))));
delay(1);
digitalWrite(clockpin, 0);
delay(delayvalue);
digitalWrite(clockpin, 1);
delay(delayvalue);
}
digitalWrite(datapin, 0); // to enable stop bit
delay(100); // wait fro aknowledgement
}
@Calin, 👍2
Обсуждение2 ответа
Лучший ответ:
Ну, короткий ответ: это был бит подтверждения, я забыл отправить тактовый импульс, чтобы получить его (да! мое устройство генерирует часы для подключенного потенциометра, я ждал, пока устройство "пошлет" мне бит, мне нужно было "запросить" бит на восходящем фронте часов).
Длинный ответ: сейчас код выглядит так:
int PIN_SCK = 12;
int PIN_SDA = 11;
const int delayvalue = 10;
void setup(){
digitalWrite(PIN_SCK, 1); // Я могу сначала объявить состояние
digitalWrite(PIN_SDA, 1);
pinMode(PIN_SCK, OUTPUT); // затем включите их
pinMode(PIN_SDA, OUTPUT);
delay(1000);
digitalWrite(PIN_SDA, 0); // start bit
delay(10);
digitalWrite(PIN_SCK, 0);
delay(10);
shift_out(PIN_SDA, PIN_SCK, 0x50);
shift_out(PIN_SDA, PIN_SCK, 0xA9);
shift_out(PIN_SDA, PIN_SCK, 0xA9);
digitalWrite(PIN_SDA, 1); // stop bit
}
void loop(){
}
// uint8_t-это то же самое, что 8 бит aka one byte
void shift_out(uint8_t datapin, uint8_t clockpin, uint8_t val){
uint8_t i;
for (i = 0; i < 8; i++) {
digitalWrite(datapin, !!(val & (1 << (7 - i))));
delay(1);
digitalWrite(clockpin, 1);
delay(delayvalue);
digitalWrite(clockpin, 0);
delay(delayvalue);
}
digitalWrite(datapin, 0); // to enable stop bit
delay(10);
// Здесь я обрабатываю сигнал AKNOWLEDGE, который происходит после
// каждый отправленный байт. Будь то адрес, команда или значение
digitalWrite(clockpin, 1);
delay(10);
digitalWrite(clockpin, 0);
delay(10);
}
Таким образом, в основном я следовал и точно воспроизводил сигналы на этой временной диаграмме с одним небольшим исключением: я не генерировал восходящее ребро, когда ожидал бит подтверждения (в основном диаграмма, но с SCK, равным 0 прямо под битами подтверждения).
Надеюсь, это кому-нибудь поможет!
I2C намного сложнее, чем просто смещение байтов.
См.: I2C - Двухпроводный периферийный интерфейс - для Arduino
Ваш код, похоже, не принимает ничего из этого во внимание.
Почему вы не хотите использовать проводную библиотеку? Аппаратное обеспечение на чипе (какой чип у вас есть?) поддерживает его. Зачем игнорировать это и пытаться сделать это самостоятельно?
У меня нет проблем с использованием библиотеки wire, однако мне было интересно, почему этот код не работал в первую очередь, так как, по моему мнению, он должен был работать. И да, я уже закончил тем, что использовал провод на своем Arduino Pro Mini. Спасибо за информацию! :), @Calin
Мне действительно любопытно, что я сделал не так в своем коде. Разве я не принял во внимание бит подтверждения, я просто подождал 100 мс, пока подчиненный отправит этот бит, и продолжил, или что я сделал?, @Calin
Ну, мне удалось заставить его работать, я опубликую ответ немного позже., @Calin
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- OVF в последовательном мониторе вместо данных
- ЖК-дисплей I2C отображает странные символы
- Соединение I2C зависает Ведущий если ведомый отключается
- Экран LCD 16*02 I2C показывает только первый напечатанный символ
- Последовательная связь между несколькими устройствами (или ардуино)
Что это за код? Не стесняйтесь размещать код здесь., @Nick Gammon
Хорошо, отредактировал код., @Calin