I2c

Bonjour à tous, en ces vacances, petits moments de détente pour en apprendre d’avantage sur I2c et les drivers.
Pour l’instant tout va bien, je controle mes relais avec une télécommande IR,
mais j’ai un problème, dans mon switch comment modifier un seul bit pour pouvoir modifier qu’un seul relais ?
Avec le code cela devrait être plus simple à comprendre…

#include <IRremote.h>
#include <Wire.h>
#define adress 0x20
int RECV_PIN = 11;
int relaisOn[]={0,0,0,0};
IRrecv irrecv(RECV_PIN);

decode_results results;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
   Wire.begin();
  Write(B00000000);
}

void loop() {
  // put your main code here, to run repeatedly:

  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC);

    
    switch(results.value){
      case 16724175:
    if(relaisOn[0]==0){
      Write(B10000000);  
      relaisOn[0]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      Write(B00000000);  
      relaisOn[0]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); // Receive the next value
    break;
    case 16724176:
    if(relaisOn[1]==0){
      Write(B10000000);  
      relaisOn[1]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      Write(B00000000); 
      relaisOn[1]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume();
    break;
    case 16724177:
    if(relaisOn[2]==0){
      Write(B10000000);  
      relaisOn[2]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      Write(B00000000);  
      relaisOn[2]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume();
    break;
    case 16724178:
    if(relaisOn[3]==0){
      Write(B10000000);
      relaisOn[3]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      Write(B00000000); 
      relaisOn[3]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); 
    break;
    default:
    break;
  }
  delay(1000);
}
}
void Write(byte _data) {
 Wire.beginTransmission(adress); // Commence la transmission sur l'adresse défini plus haut
 Wire.write(_data);              // On envoie la donnée
 Wire.endTransmission();         // On termine la transmission
}

Donc voilà dans Wire(B********) j’aimerai modifier qu’un seul bit de façon à agir que sur un seul relais :slight_smile:

Peut être opération bit à bit ?

Merci de votre aide et bonne journée !

Salut

Je peux déjà dire que tu envoies la même commande dans les quatre cas.

          Write(B10000000);

Tu devrais préciser quel composant I2C tu utilises, et aussi quel est le comportement actuel de ton logiciel.

@+

Hello,
alors oui j'envoie la même commande, mais c'est juste pour des tests, j'ai juste fait des copier/coller :slight_smile:

C'est un pcf8574 et pour l'instant tout fonctionne sur mon arduino, dès que j'appuie sur un bouton de ma télécommande, j'ai bien le relais qui s'active. Mais le problème c'est que dès que je rentre dans un cas du switch je change tout les états des relais sans savoir les états dans lesquels ils étaient. Donc imaginons mon relais n°2 est à l'état haut, et bien quand je vais vouloir activer mon relais n°1 cela va changer l'état de mon relais n°2 aussi, et ça c'est problématique forcément...

merci de ta réponse !

Dans chaque cas, contente-toi de positionner les états de chaque relais dans le tableau relaisOn.
Au lieu de passer par un tableau de 4 entiers, utilises plutôt un uint8_t qui représente la donnée que tu vas envoyer au PCF8574.
Tu mets à 1 le bit qui correspond au relais que tu veux commander avec un OU, et tu le baisse avec un ET en prenant le complément.

En supposant que les relais soient clés sur les bits 7, 6, 5, 4 :

  static uint8_t state;

  if (!(state & 0x80)) {
    // met le bit 7 à 1
    state |= 0x80;
  }
  else {
    // met le bit 7 à 0
    state &= 0x7f;
  }

  if (!(state & 0x40)) {
    // met le bit 6 à 1
    state |= 0x40;
  }
  else {
    // met le bit 6 à 0
    state &= 0xbf;
  }

  if (!(state & 0x20)) {
    // met le bit 5 à 1
    state |= 0x20;
  }
  else {
    // met le bit 5 à 0
    state &= 0xdf;
  }

  if (!(state & 0x10)) {
    // met le bit 4 à 1
    state |= 0x10;
  }
  else {
    // met le bit 4 à 0
    state &= 0xef;
  }

Ensuite tu envoie la variable directement au PCF8576.

***** EDIT *****
La loop complète :

void loop() {
  static uint8_t state;

  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC);

    switch (results.value) {
      case 16724175:

        if (!(state & 0x80)) {
          // met le bit 7 à 1
          state |= 0x80;
        }
        else {
          // met le bit 7 à 0
          state &= 0x7f;
        }
        break;
      case 16724176:
        if (!(state & 0x40)) {
          // met le bit 6 à 1
          state |= 0x40;
        }
        else {
          // met le bit 6 à 0
          state &= 0xbf;
        }
        break;
      case 16724177:
        if (!(state & 0x20)) {
          // met le bit 5 à 1
          state |= 0x20;
        }
        else {
          // met le bit 5 à 0
          state &= 0xdf;
        }
        break;
      case 16724178:
        if (!(state & 0x10)) {
          // met le bit 4 à 1
          state |= 0x10;
        }
        else {
          // met le bit 4 à 0
          state &= 0xef;
        }
        break;
      default:
        break;
    }
    delay(1000);          // pour quoi faire ?
    irrecv.resume();
    Write(state);
    delay(1000);
  }
}

@+

Haaaaaaa j’aime beaucoup t’as réponse, je l’aime bien parce que c’est ça que je voulais faire au début, appliquer des masques pour faire des tests, et utiliser les opérations et et ou !

En tout cas merci pour le rappel !
J’ai entre temps cherché un peu de mon coté et j’en suis arrivé à ça, c’est parfaitement fonctionnel :slight_smile:

Merci à tous et bonne soiré !

#include <IRremote.h>
#include <Wire.h>
#define adress 0x20
int RECV_PIN = 11;
int relaisOn[]={0,0,0,0,0,0,0,0};
IRrecv irrecv(RECV_PIN);

decode_results results;
int value=0;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
   Wire.begin();
  Write(B00000000);
}

void loop() {
  // put your main code here, to run repeatedly:

  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC);

    
    switch(results.value){
      case 16724175: ///////////////////////premier relais
    if(relaisOn[0]==0){
      value+=128;
      Write(value);  
      relaisOn[0]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=128;
      Write(value);  
      relaisOn[0]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); // Receive the next value
    break;////////////////////////////////////////////////////////////////////////////////////
    case 16718055://///////////////////////////deuxieme
    if(relaisOn[1]==0){
      value+=64;
      Write(value);  
      relaisOn[1]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=64;
      Write(value); 
      relaisOn[1]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume();
    break;//////////////////////////////////////////////////////////////////////////////////////////////
    case 16743045://///////////////////////////////////troisieme
    if(relaisOn[2]==0){
      value+=32;
      Write(value);  
      relaisOn[2]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=32;
      Write(value);  
      relaisOn[2]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume();
    break;////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 16716015://///////////////////////////////////quatrieme
    if(relaisOn[3]==0){
      value+=16;
      Write(value);
      relaisOn[3]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=16;
      Write(value); 
      relaisOn[3]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); 
    break;/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 16726215://////////////////////////////////////////////////////cinquieme
    if(relaisOn[4]==0){
      value+=8;
      Write(value);
      relaisOn[4]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=8;
      Write(value); 
      relaisOn[4]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); 
    break;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 16734885://///////////////////////////////////////////////sixieme
    if(relaisOn[5]==0){
      value+=4;
      Write(value);
      relaisOn[5]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=4;
      Write(value); 
      relaisOn[5]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); 
    break;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 16728765://///////////////////////////////septieme
    if(relaisOn[6]==0){
      value+=2;
      Write(value);
      relaisOn[6]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=2;
      Write(value); 
      relaisOn[6]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); 
    break;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 16730805://////////////////////////////////////huitieme
    if(relaisOn[7]==0){
      value+=1;
      Write(value);
      relaisOn[7]=1;
      Serial.println("je passe relais a 1");
    }
    else{
      value-=1;
      Write(value); 
      relaisOn[7]=0;
      Serial.println("je passe relais a 0");
    }
    delay(1000);
    irrecv.resume(); 
    break;/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 16738455://///////////////////////////////////rien
    value=0;
      Write(value);
      for(int cpt=0;cpt<8;cpt++){
        relaisOn[cpt]=0;
      }
     
      
    delay(1000);
    irrecv.resume(); 
    break;/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 16732845://///////////////////////////////////all
    value=255;
      Write(value);
      for(int cpta=0;cpta<8;cpta++){
        relaisOn[cpta]=1;
      }
    delay(1000);
    irrecv.resume(); 
    break;
    default:
    break;
  }
  delay(1000);
}
}
void Write(byte _data) {
 Wire.beginTransmission(adress); // Commence la transmission sur l'adresse défini plus haut
 Wire.write(_data);              // On envoie la donnée
 Wire.endTransmission();         // On termine la transmission
}

La solution des masques est plus lisible pour un développeur logiciel.