Hey everyone,
I have some strange behaviour that I cannot figure out.
I've wired up an MCP23017 multiplexer to read inputs. I've created test code to read the inputs from General Purpose pins A and B. The code works flawelessly for all inputs.
/*
Example 41.2 - Microchip MCP23017 with Arduino
http://tronixstuff.wordpress.com/tutorials > chapter 41
John Boxall | CC by-sa-nc
*/
// MCP23017 pins 15~17 to GND, I2C bus address is 0x20
// Clock goes to pin A5 //yellow->blue
// Data goes to pin A4 // green ->green
// Buttons have Red to 5V, and Black to general purpose pins
// From each pin, have a 10k pull-down resistor to ground
// Have a 4.7k pull-up resistor from clock and data pins to 5V
#include "Wire.h"
byte inputs=0;
byte P1=0;
byte P2=0;
int delayTime=150; //150 seems most responsive while still debouncing
void setup()
{
Serial.begin(9600);
Wire.begin(); // wake up I2C bus
}
void loop()
{
Wire.beginTransmission(0x20); //Open comms with multiplexer
Wire.write(0x13); // set MCP23017 memory pointer to GPIOB address
Wire.endTransmission(); // Close comms with multiplexer
// // info from pins 1-8
Wire.requestFrom(0x20, 1); // request one byte of data from MCP20317
// Parse the bytes out into something meaningful:
P1 = Wire.read(); //First recieved byte stored here
if (P1>0) // if a button was pressed
{
Serial.println(P1, BIN); // display the contents of the GPIOB register in binary
delay(delayTime); // for debounce
}
Wire.beginTransmission(0x20); //Open comms with multiplexer
Wire.write(0x12); // set MCP23017 memory pointer to GPIOA address
Wire.endTransmission(); // Close comms with multiplexer
// // info from pins 21-28
Wire.requestFrom(0x20, 1); // request one byte of data from MCP20317
// Parse the bytes out into something meaningful:
P2 = Wire.read(); //First recieved byte stored here
if (P2>0) // if a button was pressed
{
Serial.println(P2, BIN); // display the contents of the GPIOB register in binary
delay(delayTime); // for debounce
}
}
I've created a 16x16 matrix display consisting of 4 8x8 matrices, where I'm communicating via SPI, and again, I've created test code to light these up and see that they work.
// Define what pins to use
// NOTE: Can use ANY type of pin for outputs.
// Did a test and tried using PWM pins and
// non-PWM pins for each connection and worked
// for all cases
//Pin connected to ST_CP of 74HC595
int latchPin = 2;
//Pin connected to SH_CP of 74HC595
int clockPin = 3;
////Pin connected to DS of 74HC595
int dataPin1 = 4;
//Initialize a byte array
byte matrix[4][8] = {{0,0,0,0,0,0,0,0}, //Diagonal line
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0} };
//holder for information you're going to pass to shifting function
int byteScan = 0;
int byte1 = 0;
int byte2 = 0;
int byte3 = 0;
int byte4 = 0;
void setup() {
// put your setup code here, to run once:
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
// Initializer Serial Communication Speed for Reading Analog Inputs
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
int i=0;
for (i=7; i>=0; i--) {
digitalWrite(latchPin, 0);
delay(00); //Delay to get nice Display
matrix[0][i] = pow(2,i-1+stepVar)+1; //Diagonal Line
matrix[1][i] = pow(2,i-1+stepVar)+1; //Diagonal Line
matrix[2][i] = pow(2,i-1+stepVar)+1; //Diagonal Line
matrix[3][i] = pow(2,i-1+stepVar)+1; //Diagonal Line
byteScan = 1<<i; //UDN, ROW SCANNER
byte1 =matrix[0][i];
byte2 = matrix[1][i];
byte3 = matrix[2][i];
byte4 = matrix[3][i];
// Print Values to Serial Monitor for testing
//Serial.println(byte1);
//Serial.println(byteScan);
// Send the Bytes to the shift registers
shiftOut(dataPin1, clockPin, byte4);
shiftOut(dataPin1, clockPin, byteScan);
//
shiftOut(dataPin1, clockPin, byte3);
shiftOut(dataPin1, clockPin, byteScan);
//
shiftOut(dataPin1, clockPin, byte2);
shiftOut(dataPin1, clockPin, byteScan);
//
shiftOut(dataPin1, clockPin, byte1);
shiftOut(dataPin1, clockPin, byteScan);
//return the latch pin to high to drop the bits from the register
// memory and into place to make the lasers do their thing
digitalWrite(latchPin, 1);
}
}
}
// Drop a byte into the shift register, one bit at a time
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut?
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
// for i=7:-1:0
digitalWrite(myClockPin, 0);
// Me: I think the clock works like a click-counter,
// where each time you increment up by 1 you need to click. So
// it's zero here tells it hey, stay here, don't shift, and setting
// it to 1 below acts to click the counter and shift over 1.
//Them: if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1. (Delete this Later
// if my explanation below is right).
//
//Me: If the i'th Bit of the input Byte is 1, then tell the
// shift register to be 1. But if the i'th Bit of the input
// Byte is 0, then tell the shift register to be 0.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
When I try to run code that combines both of these, I have some very very strange behavior that initially made me think that there was somehow a short somewhere in the circuit, but after testing multiple times with a multimeter, I can't find any instances of continuity in places where there shouldn't be.
Final Code:
See comment Below, too many characters for a single post
I've set up the code so that:
in1 = GPA(); //Read inputs from General purpose register A
in1 = 1; //Overwrite the input from the register
P1 = in1; //Not exactly, but in the code above I check in1 on every i loop, and then use the values in P1 on the 16th iteration to debounce
Serial.println(P1) ;
I've overwritten what's actually being read and assigned it to because I seem to be having issues with the arduino crashing. In both of the examples pieces of code, the Serial.println shows results in the serial monitor and loops through endlessly, but here, the serial monitor will print 1 or 2 values, and then it will cease showing anything at all. It's like the arduino has inexplicably crashed... or maybe it's failing to connect to the multiplexer and just doesn't know what to do?
It's also worth mentioning that when I comment out the code to checkGPA and checkGPB, and just have the code below, it loops through endlessly:
P1 = in1; //Not exactly, but in the code above I check in1 on every i loop, and then use the values in P1 on the 16th iteration to debounce
Serial.println(P1) ;
I also thought it could be hardware related, but after checking and rechecking all of the connections, there does not appear to be any shorts and everything is wired properly (as far as I can tell, and as far as I can assume since the test code works).
The ONLY thing I can think of that may be a problem, but can't find any straight answers for anywhere, is that the RESET pin on the multiplexer should maybe be 'pulled high' with a resistor to Vdd, and not connected directly to Vdd? Any ideas? Thanks!