c++microcontroller

MCP23017 / C++ erroneous values on read


I am trying to read the GPIOB / GPIOA values through my program. This is a threaded program that gets messages over tcp/ip as a signal to change the pins.

    unsigned char gpioMon::subtractiveLookup(gpioMon::gpio_data gpio_data_in, unsigned char        registry, unsigned char value) {
        std::lock_guard<std::mutex> lock(i2c_mutex_);

        unsigned int handle = i2cOpen(gpio_data_in.i2c_bus,gpio_data_in.i2c_addr,0);

        std::this_thread::sleep_for(std::chrono::microseconds(50));
        int retcode = i2cReadByteData(handle,registry);//Read byte prior to writing it

        std::cout<<"Hello from gpioMon::subtractiveLookup()! Read value : "<<retcode<<"\n";
        unsigned char temp_holder = static_cast<unsigned char>(retcode) - value;

        std::this_thread::sleep_for(std::chrono::microseconds(50));

        std::cout<<"Hello from gpioMon::subtractiveLookup()! Writing value : "<<static_cast<int>(temp_holder)<<"\n";
        retcode = i2cWriteByteData(handle,registry,temp_holder);

        std::this_thread::sleep_for(std::chrono::microseconds(50));
        return retcode;
}

additiveLookup is the same function with an addition of "temp_holder" rather than a subtraction.

Here is the terminal output and where the odd things start to happen. I think it is due to a timing problem, but please let me know what you think it is...

    Hello from gpioMon::readInputs(). Message is dout1 on
    Hello from gpioPool::gpioRequest! Received mesage : dout1 on
    Hello from gpioPool::gpioRequest! gpio_name : dout1
    Hello from gpioMon::additiveLookup()! Read value : 0
    Hello from gpioMon::additiveLookup()! Writing value : 1
    Received bytes : 9
    Hello from gpioMon::readInputs(). Message is dout1 off
    Hello from gpioPool::gpioRequest! Received mesage : dout1 off
    Hello from gpioPool::gpioRequest! gpio_name : dout1
    Hello from gpioMon::subtractiveLookup()! Read value : 121
    Hello from gpioMon::subtractiveLookup()! Writing value : 120
    Received bytes : 8
    Hello from gpioMon::readInputs(). Message is dout1 on
    Hello from gpioPool::gpioRequest! Received mesage : dout1 on
    Hello from gpioPool::gpioRequest! gpio_name : dout1
    Hello from gpioMon::additiveLookup()! Read value : 0
    Hello from gpioMon::additiveLookup()! Writing value : 1
    Received bytes : 9
    Hello from gpioMon::readInputs(). Message is dout1 off
    Hello from gpioPool::gpioRequest! Received mesage : dout1 off
    Hello from gpioPool::gpioRequest! gpio_name : dout1
    Hello from gpioMon::subtractiveLookup()! Read value : 1
    Hello from gpioMon::subtractiveLookup()! Writing value : 0
    Received bytes : 8
    Hello from gpioMon::readInputs(). Message is dout1 on
    Hello from gpioPool::gpioRequest! Received mesage : dout1 on
    Hello from gpioPool::gpioRequest! gpio_name : dout1
    Hello from gpioMon::additiveLookup()! Read value : 0
    Hello from gpioMon::additiveLookup()! Writing value : 1
    Received bytes : 9
    Hello from gpioMon::readInputs(). Message is dout1 off
    Hello from gpioPool::gpioRequest! Received mesage : dout1 off
    Hello from gpioPool::gpioRequest! gpio_name : dout1
    Hello from gpioMon::subtractiveLookup()! Read value : 65
    Hello from gpioMon::subtractiveLookup()! Writing value : 64
    Received bytes : 8
    Hello from gpioMon::readInputs(). Message is dout1 on
    Hello from gpioPool::gpioRequest! Received mesage : dout1 on
    Hello from gpioPool::gpioRequest! gpio_name : dout1
    Hello from gpioMon::additiveLookup()! Read value : 112
    Hello from gpioMon::additiveLookup()! Writing value : 113

If I run i2cget -y 1 0x27 0x13 after, it will show the real value. My fear is this program will actually write 113 to the registry and it will short out components.

What I am expecting to happen here is to read the registry and then add or subtract the current position from it. Example 0x00 + 0x01 --> GPIOB1 HI or 0x01 + 0x02 --> GPIOB0 HI / GPIOB1 HI .

I have tried adjusting the bus speed, adding in mutexes, adding in delays, trying file descriptors, trying pigpio methods. All seem to lead to the same outcome.

I think I am reading the documentation wrong and would appreciate some assistance with it.


Solution

  • Revisiting this again.

    Actually, my previously accepted answer was not what it ended up being.

    When using the MCP23017, I noticed that the GPIOA / GPIOB registry is very undesireable to poll when OUTPUTS are changed; but rather it is very consistent on INPUT changes.

    Instead of polling GPIOA/GPIOB for output status, I instead wrote to OLATA / OLATB which forces the chip to be in that state. I am not saying it will be 100% right, but it has lead me to far greater success. I hope this backtrack will help you in the future if needed.