Remote controller with PCA9535

IMG_9431mini

I like TR-52D series IQRF, but in some cases, these modules has insufficient number of IOs (6 only). I mentioned this issue in this post. Unlike Relay board, I want 8 input pins (and more). So the simpliest way, how to do It, is port expander usage.

There are several ICs working as Port Expander. I think, there are noone, who do not know famous PCF8574. But now, this device is little bit old fashioned, so now it is time to something better, for example PCA9535 (I2C), PCA9555 (I2C), MCP23017 (I2C) or MCP23S17 (SPI). I prefer PCA9535, just beacause, I have lot of them :).

There is main part of circuit. PCA is connected to IQRF via I2C bus and Interrupt signal is connected IQRF SS pin. I have 10 buttons connected only. Full schematic sheet link is at the end of this article.

RCPCA9535

Software

We need PCA drivers. But at the beginning, we need I2C drivers. These drivers are available as part of startup package in the DDC-SE-01-i2c.c source code. There is list of functons for I2C bus:

void i2c_init(void);
void i2c_waitForIdle();
void i2c_start();
void i2c_repStart();
void i2c_stop();
uns8 i2c_read(uns8 ack);
uns8 i2c_write(uns8 i2cWriteData);

Port Expander Initialisation:

void cnf_IO()			
{
    i2c_start();
    i2c_write(I2C_ADR_W);               
    i2c_write(PCA9535_PortCfg0);                    
    i2c_write(0b01100111);              
    i2c_write(0b01110011);              
    i2c_stop();
    waitDelay(5);
    i2c_start();
    i2c_write(I2C_ADR_W);               
    i2c_write(PCA9535_InvertPol0);                    
    i2c_write(0xFF);         		    
    i2c_write(0xFF);          			
    i2c_stop();	
}

All unused pins are configured as output pins.

Pin state reading:

void read_IO()			
{
    uns16 tlacitka = 0;
    i2c_start();
    i2c_write(I2C_ADR_W);               
    i2c_write(PCA9535_InputPort1);                    
    i2c_repStart();
    i2c_write(I2C_ADR_R); 	
    btns_H = i2c_read(ACK);     
    btns_L = i2c_read(NO_ACK);
    i2c_stop();
}

All register operations are done as pair operations. If You are addressing and configuring registers for port 0, next processed register will be register for port 1. Please refer this feature in datasheet.

Main loop

There is draft of main loop.

If no button is pressed, IQRF module do nothing. If you press the button, PCA will generate interrupt signal on INT output and timeout is set on value 10. Then, button state reading via I2C is executed. If any button is active, timeout is refreshed, button value is copied to bufferRf registers and transmited. If you release button, additional 9 empty messages are generated and sent.

void APPLICATION()             
{

    uns8 timeout = 0;
    btns_H = btns_L = 0;

    disableSPI();
    waitDelay(5);
    i2c_init();
    waitDelay(5);
    cnf_IO();
    waitDelay(5);

    while (1)    // Main loop
    {
 	if (buttonPressed)   //   PCA interrupt
            timeout = 10;    //   10 TXs

		
        if (timeout > 0)    // 
        {
            read_IO();      // button state reading
			
            bufferRF[0] = btns_L;
            bufferRF[1] = btns_H;			
		
            if ((btns_L) || (btns_H)) timeout = 10;
            // in any button is pressed, refresh timeout.
		
            pulseLEDR();    // LEDR blink on background
            PIN = 0;        // P2P packet
            DLEN = 2;       // message lenght: 2 bytes
            RFTXpacket();   // data TX
            waitDelay(5);   // wait 50 ms
            timeout -= 1;   // decrease timeout		
        }
    }		                         
}

Done. Next time, we will do something with power consumption…

 

Download Attachments

Leave a Reply

Your email address will not be published. Required fields are marked *