Значение параметра cmd в write_i2c_block_data

12

Я тестирую i2c связь между Пи и Ардуино.

Док говорит:

write_i2c_block_data(addr,cmd,vals)  Block Write transaction.    int addr,char cmd,long[]    None

У меня есть этот тест:

На пи:

import smbus
bus = smbus.SMBus(0)
bus.write_i2c_block_data(address, 48, [49, 50, 51] )

На Ардуино:

void receiveData(int byteCount){
    Serial.print("byte count=");
    Serial.println(byteCount);

    while(Wire.available()) {
        number = Wire.read();
        Serial.print((char)number);
     }
}

На Arduino я вижу этот вывод:

byte count=4
0123

Мой вопрос: в чем польза от cmdпараметра? Я не вижу различия в Arduino, какой байт представляет что.
Я думаю, что могу справиться с этим по своему усмотрению. Может быть, я хочу использовать первые 2 байта в качестве команды.

На этой странице мало информации о методе: http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc

Гус Смит
источник
Возможно, вы захотите определить, что это за cmdпараметр ... Мне нужно было немного подумать, чтобы понять, что вы имели в виду. Хотя я не нашел ответа ... Он может использоваться только определенными чипами, такими как расширитель GPIO или что-то в этом роде ...
Баттерс
Хорошо, я добавил ссылку на документацию (что не так много)
Гас Смит
6
У меня нет времени, чтобы дать полный ответ прямо сейчас (я надеюсь, что кто-то ответит), но вкратце - так работает I²C. Мастер может просто отправить ему несколько байтов данных (после отправки правильного адреса), и нет никакой спецификации относительно того, каковы эти байты на самом деле (их значение определяется для каждого устройства). Так уж получилось, что первый байт часто является номером команды (или регистра). Также вы всегда должны отправлять хотя бы один байт, так что в отличие от этого vals, cmdэто обязательно.
Кшиштоф Адамски
1
@KrzysztofAdamski Это звучит как довольно полный ответ для меня.
Баттерс

Ответы:

8

I²CПротокол очень прост. Он на самом деле не определяет структуры данных, которые передаются по проводам. Кадр состоит из адреса подчиненного устройства (с битом направления, указывающим, хочет ли мастер чтения или записи) и (в случае записи) некоторых байтов данных. Поскольку не имеет смысла начинать запись с 0 байтов данных, первый байт является обязательным.

Этот первый байт часто используется как адрес ведомого регистра или номер команды, но это не обязательно. Могут быть или не быть дополнительные байты после первого. Протокол более высокого уровня, определяющий, что означает каждый байт, зависит от устройства.

Это может объяснить, почему существует два отдельных аргумента: первый ( cmd) является обязательным, а второй ( vals) - необязательным. Хотя ваш пример написан на Pythonязыке, используемый здесь API представляет собой очень близкое отображение исходного CAPI, где вы не можете легко создавать необязательные аргументы.

Кшиштоф Адамски
источник
Это немного более длинное объяснение того, что я написал в комментарии под вопросом.
Кшиштоф Адамски
Я рад, что ты сделал! Такие простые, но все же "ага!" объяснения действительно полезны иногда, как сегодня :-)
ухх
3

Когда вы выпускаете блок записи / чтения из Pi с помощью:

bus.write_i2c_block_data(address, 48, [49, 50, 51] )

или

bus.read_i2c_block_data(address, 48, [49, 50, 51] )

Две вещи случаются (могут) на Arduino в зависимости от чтения или записи.

Байт cmd - это первый байт, записанный на шину I2C от Pi, он всегда отправляется как запрос «записи». Это означает, что если Pi выдает

bus.read_i2c_block_data

или

bus.write_i2c_block_data

сначала пишет

cmd

на шину I2C, прежде чем он читает .

Это полезная функция, потому что некоторое оборудование I2C требует инициализации, прежде чем можно будет выполнить чтение.

На Arduino это означает, что:

Во-первых,

Wire.onReceive(yourCallback)

функция вызывается, потому что cmdбыл записан в шину Pi. cmdбудет первым байтом, доступным на шине. Если Pi отправил запрос на запись, то Arduino будет оставаться в обратном вызове Wire.onReceive до завершения функции. Если Pi отправил запрос на чтение, Arduino завершит Wire.onReceive, а затем вызовет обратный вызов Wire.onRequest.

Вы должны убедиться, что значение, помещенное в cmd, не вызывает непреднамеренного поведения в вашей системе, должным образом обрабатывая его значение. Если, например, обратный вызов Wire.onReceive выключает светодиод, когда Wire.read = 0x30. Затем, даже если вы отправили запрос на чтение , он сначала выключил бы светодиод, записав 0x30, а затем считал запрошенные байты с шины.

deltatango
источник
1

Я пишу на жидкокристаллический дисплей I2C, Newhaven NHD ‑ 0216K3Z ‐ FL ‐ GBW ‐ V3. Его спецификации можно найти в Google. В его случае, когда командный байт равен 0xfe, это означает, что следующий байт является командой - их около 20. Очистка, подсветка, мигание курсора и тд. Если cmd не 0xfe, это просто какой-то символ для отображения.

собачьих упряжках
источник