Enviar comandos via I2C

Olá pessoal,
gostaria de saber se é possível enviar comandos do tipo "don't care" via I2C, por exemplo, ao utilizar um expansor de portas, podemos enviar comandos em binário, porém, se eu quiser que apenas uma porta mude de estado (1 ou 0), mas sem alterar o estado atual das outras portas, é possível?

Sei que da pra fazer a mesma coisa utilizando vários comandos de condição, porém fica muito mais trabalhoso.

agradeço desde já

Que expansor de portas...

Normalmente a melhor maneira de o fazer e ler o estado das portas para uma variavel, mudar o bit que pretendes nessa variavel e escrever essa variavel.

unsigned char estado = read_port();
estado |= 0x01; // colocar o bit 0 a 1
write_port(estado);

Mas tudo isto depende do teu expansor de portas...

Estou usando o expansor PFC8574AP, fazendo a comunicação usando a biblioteca Wire, eu tentei fazer o seguinte:

Wire.beginTransmission(0x38);
Wire.write(B001xxxxx);
Wire.endTransmission(0x38);

onde "x" seriam as portas que não quero alterar nesta parte da programação, porém desta forma não funciona pois o arduino não entende este x.

acho que B nao funciona... mas nao tenho a certeza... se nao me engano, precisas de escrever 0b00010001 se queres definir algo em binario.

x nao e binario e como tal o Arduino nao vai aceitar.

Antes de mais... tambem nao sei se estaras a enviar o endereco correcto... se o teu chip e o 8574A e nao o 8574... o endereco e o 0x78.
Se for o 8574 certamente que nao e 0x38.

http://www.nxp.com/documents/data_sheet/PCF8574.pdf

Isto aqui em baixo pisca o pino que pretendes de segundo a segundo... deve dar para tirares o que pretendes daqui.

setup(){

Wire.begin();


}

void loop()
{
    Wire.requestFrom(33,1); 
    if(Wire.available())     //If the request is available
    {
        x=Wire.receive();       //Receive the data
        x |= 0b00100000;
        Wire.beginTransmission(32);     //Begin the transmission to PCF8574
        Wire.send(x);                                //Send the data to PCF8574
        Wire.endTransmission();            //End the Transmission

    }
    delay(1000);

    Wire.requestFrom(33,1); 
    if(Wire.available())     //If the request is available
    {
        x=Wire.receive();       //Receive the data
        x &= 0b11011111;
        Wire.beginTransmission(32);     //Begin the transmission to PCF8574
        Wire.send(x);                                //Send the data to PCF8574
        Wire.endTransmission();            //End the Transmission

    }
    delay(1000);
}

Sim, como diz o bubulindo, "don't care" é OR com 0 ou AND com 1. Como lê o valor que lá estava antes da operação lógica, se, por exemplo, lá estivesse 0100 1110 e quisesse apagar o bit 6, deveria fazer o AND com 1011 1111 (ou 0xBF). Se quiser ligar o bit 4, por exemplo, deve fazer OR com 0001 0000 (ou 0x10).

Também como o bubulindo diz o B01001110, não funciona. Pode funcionar, se algures no código estiver a linha:

#define B01001110 0x4E

Mas isto não é muito prático, especialmente se tiver que definir os 256 códigos possíveis (2⁸=256).

O que se pode fazer é adicionar:
0x - para heXadecimal;
0b- para Binário
0o - para Octal ( :smiley: este não é bem assim, até porque ficava mal, então acrescenta-se apenas o "zero").

bubu, com esta programação, é possível controlar apenas uma porta sem interferir as outras?

luis

a sintaxe utilizando (B10011011) aqui funcionou corretamente;

o principal problema é que se eu for usar as condicionais OR ou AND para modificar apenas uma porta vou ter que considerar muitas combinações, ficaria inviável fazer isso.

Fica inviavel porque??? Tu sabes qual e o bit que queres mudar... crias uma funcao ou macro para o fazer com OR e AND e pronto.

Tirando compiladores em especifico que dao a possibilidade de manipular bits directamente, esta e a unica maneira que tens de fazer isto.

Queres explicar qual e o teu projecto?

Interessante esses macros, vou tentar implementa-los no sistema, obrigado.

Meu projeto é uma automação residencial, com controle de temperatura, umidade, contagem de pessoas, controle de cortina, entre outras coisas, por isso vou precisar expandir o número de portas do arduino, pois o que estou usando é o uno, e ele já está cheio, dai veio a necessidade de modificar um bit numa comunicação wire.

Acho que facilmente vais chegar a conclusao que provavelmente sera melhor teres mais do que um processador para tudo isso em vez de portas...

Se procurares, certamente que encontras bibliotecas para o Arduino usar esse cihp e nao teras muitas dores de cabeca, mas ter mais poder de processamento podera ser interessante.