Signification de cmd param dans write_i2c_block_data

12

Je teste la communication i2c entre Pi et Arduino.

Le doc dit:

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

J'ai ce test:

Sur Pi:

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

Sur Arduino:

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

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

Sur l'Arduino, je vois cette sortie:

byte count=4
0123

Ma question est: quelle est l'utilité du cmdparamètre? Je ne vois pas de distinction sur l'Arduino dont l'octet représente quoi.
Je suppose que je peux y faire face comme bon me semble. Peut-être que je veux utiliser les 2 premiers octets comme commande.

Cette page n'a pas beaucoup d'informations sur la méthode: http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc

Gus Smith
la source
Vous voudrez peut-être définir ce qu'est le cmdparamètre ... J'ai dû faire un peu de recherche pour comprendre ce que vous vouliez dire. Je n'ai pas trouvé de réponse cependant ... Elle ne peut être utilisée que par des puces spécifiques comme un expanseur GPIO ou quelque chose ...
Butters
Ok, j'ai ajouté le lien vers la documentation (ce qui n'est pas beaucoup)
Gus Smith
6
Je n'ai pas le temps de répondre en ce moment (j'espère que quelqu'un le fera) mais en bref - c'est ainsi que fonctionne I²C. Le maître peut simplement lui envoyer des octets de données (après avoir envoyé la bonne adresse) et il n'y a aucune spécification sur ce que sont réellement ces octets (leur signification est définie par périphérique). Il se trouve que le premier octet est souvent un numéro de commande (ou de registre). De plus, vous devez toujours envoyer au moins un octet, contrairement à ce valsqui cmdest obligatoire.
Krzysztof Adamski
1
@KrzysztofAdamski Cela me semble être une réponse assez complète.
Butters

Réponses:

8

I²Cle protocole est très simple. Il ne définit pas vraiment les structures de données envoyées sur le câble. La trame se compose d'une adresse esclave (avec un bit de direction indiquant si le maître veut lire ou écrire) et (en cas d'écriture) de quelques octets de données. Puisqu'il n'est pas logique de lancer l'écriture avec 0 octet de données, le premier octet est obligatoire.

Ce premier octet est souvent utilisé comme adresse de registre esclave ou numéro de commande, mais ce n'est pas obligatoire. Il peut y avoir ou non des octets supplémentaires après le premier. Le protocole de niveau supérieur définissant ce que signifie chaque octet est spécifique au périphérique.

Cela peut expliquer pourquoi il existe deux arguments distincts - le premier ( cmd) est obligatoire et le second ( vals) est facultatif. Alors que votre exemple est en Pythonlangage, l'API utilisée ici est en réalité un mappage très proche de l' CAPI d' origine où vous ne pouvez pas facilement créer des arguments facultatifs.

Krzysztof Adamski
la source
Ceci est une explication un peu plus longue de ce que j'ai écrit dans le commentaire sous la question.
Krzysztof Adamski
Je suis content que tu l'aies fait! Ces types de simples, mais "aha!" les explications sont parfois très utiles, comme aujourd'hui :-)
uhoh
3

Lorsque vous émettez un bloc d'écriture / lecture à partir du Pi avec:

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

ou

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

Deux choses se produisent (peuvent) sur l'Arduino selon la lecture ou l'écriture.

L'octet cmd est le premier octet écrit sur le bus I2C à partir du Pi, il est toujours envoyé comme une requête "d'écriture". Cela signifie que si le Pi émet un

bus.read_i2c_block_data

ou

bus.write_i2c_block_data

il écrit d' abord

cmd

au bus I2C avant qu'il lit .

Il s'agit d'une fonctionnalité utile car certains matériels I2C nécessitent une initialisation avant qu'une lecture puisse être effectuée.

Sur l'Arduino, cela signifie que:

Premièrement les,

Wire.onReceive(yourCallback)

La fonction est appelée car elle a cmdété écrite sur le bus par le Pi. cmdsera le premier octet disponible sur le bus. Si le Pi a envoyé une demande d'écriture, l'Arduino restera dans le rappel Wire.onReceive jusqu'à ce que la fonction soit terminée. Si le Pi a envoyé une demande de lecture, l'Arduino terminera le Wire.onReceive puis appellera le callback Wire.onRequest.

Vous devez vous assurer que la valeur placée dans cmd ne provoque pas de comportement inattendu dans votre système en gérant correctement sa valeur. Si par exemple, votre rappel Wire.onReceive éteint une LED lorsque Wire.read = 0x30. Ensuite, même si vous avez envoyé une demande de lecture , il éteindrait d' abord la LED en écrivant 0x30, puis il lirait les octets demandés depuis le bus.

deltatango
la source
1

J'écris sur un écran LCD I2C, le Newhaven NHD ‐ 0216K3Z ‐ FL ‐ GBW ‐ V3. Sa fiche technique peut être googlé. Dans son cas, lorsque l'octet de commande est 0xfe, cela signifie que l'octet suivant est une commande - il y en a environ 20. Effacer, rétro-éclairage, curseur clignotant, etc. Si cmd n'est pas 0xfe, c'est juste un caractère à afficher.

traîneau à chiens
la source