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


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.


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 lê .

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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.