Significado de cmd param em write_i2c_block_data

12

Estou testando a comunicação i2c entre Pi e Arduino.

O documento diz:

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

Eu tenho este teste:

No Pi:

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

No Arduino:

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

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

No Arduino, vejo esta saída:

byte count=4
0123

Minha pergunta é: para que serve o cmdparâmetro? Não vejo uma distinção no Arduino de qual byte represente o quê.
Acho que posso lidar com isso como achar melhor. Talvez eu queira usar os 2 primeiros bytes como um comando.

Esta página não possui muitas informações sobre o método: http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc

Gus Smith
fonte
Você pode definir qual é o cmdparâmetro ... Eu tive que procurar bastante para descobrir o que você queria dizer. Eu não encontrar uma resposta embora ... Ele só pode ser usado por chips específicos como um expansor GPIO ou algo assim ...
Butters
Ok, eu adicionei o link para a documentação (que não é muito)
Gus Smith
6
Não tenho tempo para responder agora (espero que alguém o faça), mas resumindo - é assim que o I²C funciona. O mestre pode simplesmente enviar alguns bytes de dados (após o envio do endereço apropriado) e não há especificação sobre o que esses bytes realmente são (seu significado é definido por dispositivo). Acontece que o primeiro byte geralmente é um número de comando (ou registro). Além disso, você sempre deve enviar pelo menos um byte, ao contrário vals, cmdé obrigatório.
Krzysztof Adamski
1
@KrzysztofAdamski Isso soa como uma resposta bastante completa para mim.
Butters

Respostas:

8

I²Cprotocolo é muito simples. Realmente não define estruturas de dados que são enviadas por fio. O quadro consiste em um endereço escravo (com o bit de direção indicando se o mestre deseja ler ou escrever) e (em caso de gravação) alguns bytes de dados. Como não faz sentido iniciar a gravação com 0 bytes de dados, o primeiro byte é obrigatório.

Esse primeiro byte é frequentemente usado como endereço de registro escravo ou número de comando, mas não é necessário. Pode haver ou não bytes adicionais após o primeiro. O protocolo de nível superior que define o significado de cada byte é específico do dispositivo.

Isso pode explicar por que existem dois argumentos separados - o primeiro ( cmd) é obrigatório e o segundo ( vals) é opcional. Enquanto o seu exemplo está no Pythonidioma, a API usada aqui é realmente um mapeamento muito próximo da CAPI original, onde você não pode criar facilmente argumentos opcionais.

Krzysztof Adamski
fonte
Esta é uma explicação um pouco mais longa do que escrevi no comentário sob a pergunta.
Krzysztof Adamski
Estou feliz que você fez! Esses tipos de simples, mas "aha!" as explicações são realmente úteis algumas vezes, como hoje :-)
uhoh
3

Quando você emite um bloco de gravação / leitura do Pi com:

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

ou

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

Duas coisas acontecem (podem) no Arduino, dependendo da leitura ou gravação.

O cmd byte é o primeiro byte gravado no Pi I2C a partir do Pi, sempre é enviado como uma solicitação de "gravação". Isso significa que, se o Pi estiver emitindo um

bus.read_i2c_block_data

ou

bus.write_i2c_block_data

primeiro escreve

cmd

ao barramento I2C antes ele .

Esse é um recurso útil, porque alguns hardwares I2C requerem inicialização antes que uma leitura possa ser feita.

No Arduino, isso significa que:

Primeiro o,

Wire.onReceive(yourCallback)

função é chamada porque cmdfoi escrita no barramento pelo Pi. cmdserá o primeiro byte disponível no barramento. Se o Pi enviou uma solicitação de gravação, o Arduino permanecerá no retorno de chamada Wire.onReceive até que a função seja concluída. Se o Pi enviou uma solicitação de leitura, o Arduino concluirá o Wire.onReceive e, em seguida, chamará o retorno de chamada Wire.onRequest.

Você deve garantir que o valor colocado no cmd não cause comportamento não intencional no seu sistema, manipulando-o adequadamente. Se, por exemplo, seu retorno de chamada Wire.onReceive apaga um LED quando o Wire.read = 0x30. Então, mesmo que você enviasse uma solicitação de leitura , ele primeiro desligaria o LED escrevendo 0x30 e, em seguida, leria os bytes solicitados no barramento.

deltatango
fonte
1

Estou escrevendo em um LCD I2C, o Newhaven NHD-0216K3Z-FL-GBW-V3. Sua folha de especificações pode ser pesquisada no Google. Nesse caso, quando o byte de comando é 0xfe, significa que o seguinte byte é um comando - existem cerca de 20 deles. Limpar, luz de fundo, piscar o cursor e assim por diante. Se cmd não for 0xfe, é apenas um caractere a ser exibido.

trenó
fonte