[Tronixstuff] MCP23017 | I2C Port | Help wanted

Excerpt from midi-footspets: Using 23016

// Defines
// I2C registers
#define I2CregisterInput 0
#define I2CregisterOutput 2
#define I2CregisterPolarity 4
#define I2CregisterConfig 6
#define I2CregisterInterrupt 8
#define I2CregisterExpander 10
// I2C device addresses
#define ledAddress   (0x20 | 0x0)     // address of trigger LED indicators output
// Control Switch device bit masks
#define ddrTrigger 0x00000     // data direction register for trigger indictor LEDs

// Arduino pin assignments

#define midiChannel (byte)0


// Variable definations
int currentState[16]; // current state of sensors
int lastState[16];    // the last state of the sensors
int threshold = 0x90;  // sets the threshold value in deciding if a sensor is pressd.
int lastLedVal;
char control[16] = { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
#include <Wire.h>
#include <avr/pgmspace.h>

lastLedVal = 0;

// Setup I2C devices
Wire.begin(); // start the I2C interface
// Initilise registers 
gpio_write(ledAddress, ddrTrigger, I2CregisterConfig); // Make into outputs
gpio_write(ledAddress, 0, I2CregisterInput); // turn them all off
doSensorScan(); // get initial states

// the value of threshold determins the on / off point
void lookForChange(){
int ledVal = 0;
int ledMask = 1;
for(int i=0; i<16; i++){
if(currentState[i] < threshold) ledVal |= ledMask; // add a 1 in the position of sensors under threshold
ledMask = ledMask << 1;
}
if(lastLedVal != ledVal) { // something has changed
ledMask = 1;
for(int i=0; i<16; i++){
if((ledMask & ledVal) != (ledMask & lastLedVal)){
if((ledMask & ledVal) == 0) {
// note off
controlSend(0x80, control[i], 0x00); // turn off control message
//noTone(8);
 
}
else{
// note on
controlSend(0x90, control[i], currentState[i]>>3); // turn on control message
//tone(8, notes[i], 20);

}
}
ledMask = ledMask << 1;
}
// Update the trigger LEDs
gpio_writeByteInverse(ledAddress, ledVal, I2CregisterInput);
}
lastLedVal = ledVal; // record current state of LEDs and MIDI notes / messages

}
void gpio_write(int address, int data, int reg) {
// Send output register address
Wire.beginTransmission(address);
Wire.send(reg);
// Connect to device and send two bytes
Wire.send(0xff & data); // low byte
Wire.send(data >> 8); // high byte
Wire.endTransmission();
}

void gpio_writeByteInverse(int address, int data, int reg) {
// Send output register address
Wire.beginTransmission(address);
Wire.send(reg);
// Connect to device and send two bytes
Wire.send(data >> 8); // high byte
Wire.send(0xff & data); // low byte
Wire.endTransmission();
}

int gpio_read(int address) {
int data = 0;
// Send input register address
Wire.beginTransmission(address);
Wire.send(I2CregisterInput);
Wire.endTransmission();
// Connect to device and request two bytes
// Wire.beginTransmission(address);
Wire.requestFrom(address, 2);
if (!Wire.available()) { } // do nothing until data arrives
data = Wire.receive();

if (!Wire.available()) { } // do nothing until data arrives
data |= Wire.receive() << 8;
Wire.endTransmission();
return data;
}?

http://www.arduino.cc/en/Reference/Bitwise

A simple way to state this is "one or the other but not both."
Put differently, exclusive disjunction is a logical operation on two logical values, typically the values of two propositions, that produces a value of true only in cases where the truth value of the operands differ.
The opposite of XOR is logical biconditional, where the output of two compared values is true only if both A and B are the same.

//logical values
//propositions
//truth value
or
//logical disjunction
//operands
//true

====
I also found this very helpful:

A left arithmetic shift of a binary number by 1. The empty position in the least significant bit is filled with a zero. Note that arithmetic left shift may cause an overflow; this is the only way it differs from logical left shift.

A right arithmetic shift of a binary number by 1. The empty position in the most significant bit is filled with a copy of the original MSB.

Source: Arithmetic shift - Wikipedia

=====
:smiley:

Alternative conversion process
A shortcut to manually convert a binary number into its two's complement is to start at the least significant bit (LSB), and copy all the zeros (working from LSB toward the most significant bit) until the first 1 is reached; then copy that 1, and flip all the remaining bits. This shortcut allows a person to convert a number to its two's complement without first forming its ones' complement. For example: the two's complement of "0011 1100" is "1100 0100", where the underlined digits were unchanged by the copying operation (while the rest of the digits were flipped).
In computer circuitry, this method is no faster than the "complement and add one" method; both methods require working sequentially from right to left, propagating logic changes. The method of complementing and adding one can be sped up by a standard carry look-ahead adder circuit; the alternative method can be sped up by a similar logic transformation.

Source: Two's complement - Wikipedia

========
correct me if I'm wrong.

The logical operation exclusive disjunction, also called exclusive or (symbolized by the prefix operator J, or by the infix operators XOR, EOR, EXOR, ? or ?, /??ks ??r/ or /?z?r/), is a type of logical disjunction on two operands that results in a value of true if exactly one of the operands has a value of true.[1] A simple way to state this is "one or the other but not both."
Put differently, exclusive disjunction is a logical operation on two logical values, typically the values of two propositions, that produces a value of true only in cases where the truth value of the operands differ.