Pages: 1 [2] 3 4 ... 6   Go Down
Author Topic: Addressing 23017/4051 using I2C Serial Interface & PROGMEM  (Read 11116 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19367
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#include "Defines.h"
#include <Wire.h>
//Give convenient names to the control pins
#define CONTROL0 5   
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

//Create arrays for data from the the MUXs
//See the Arduino Array Reference: http://www.arduino.cc/en/Reference/Array
int mux0array[16];
int mux1array[16];
int mux2array[16];

void setup()
{
    w = 0;

Well, where is this file?

Code:
sketch_may08b.cpp:11:21: error: Defines.h: No such file or directory




Code:
sketch_may08b.cpp: In function 'void setup()':
sketch_may08b:28: error: 'w' was not declared in this scope

You don't have "w" declared.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1287
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I made a few changes, mainly to make the mux array a 2 dimensional array that allows you to use loops (always easier).

Good job so far. Remember to compile often to work out mistakes more easily.


* passeetryagainapril2012.ino (10.51 KB - downloaded 11 times.)
« Last Edit: May 08, 2012, 07:00:08 am by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Basically the MCP23017 and the MCP23016 are not the same chip. The clue is in the fact that they have different numbers.
While they have roughly similar features there are a number of major differences that stop one being a direct replacement for the other:-
1) The pinout of the two chips is different therefore any schematic or PCB will have to be changed to accomidate this.
2) The MCP23017 has an external reset pin that needs driving or at least biasing.
3) The MCP23016 has an external RC to determine the internal clock frequency, this affects things like time to respond to an interrupt.
4) Most importantly the registers are at different addresses in the two devices so any software will have to take this into account.
5) There are also more registers in the MCP23017 giving it more options than the MCP23016.
Logged

New York City, NY
Offline Offline
Full Member
***
Karma: 0
Posts: 141
Arduino Rocks!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is what I have now, but this comes from Grumpy_Mike's project using MCP23016, unmodified.
Code:
// 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
Quote
1) The pinout of the two chips is different therefore any schematic or PCB will have to be changed to accomidate this.
2) The MCP23017 has an external reset pin that needs driving or at least biasing.
3) The MCP23016 has an external RC to determine the internal clock frequency, this affects things like time to respond to an interrupt.
4) Most importantly the registers are at different addresses in the two devices so any software will have to take this into account.
5) There are also more registers in the MCP23017 giving it more options than the MCP23016.

thanks for your reply and post Grumpy_Mike, To start off I couldn't find the mcp23016 online for sale. I wired the 23017 as described in example on the tronixstuff website. And was able to test the LEDS going in sequence a.k.a knightrider scanner (centipede shield library and sketch) so I've had atleast the basic wiring changes for the mcp23017 to work. I haven't gotten the mx shield yet as I wanted to try it with just one maybe two mcp23017's first.  Not sure how to bias the external reset pin and most importantly I don't know how to edit the code to accommodate for the register being at different addresses. I hope I don't make you feel as overwhelmed as I do, but my I'm really up against a deadline. marco_c has been a great help in rewriting my sketch but it'll be wrong if I don't provide the right information. And based on what you've said I might have provided some erroneous info. Can you help me at least with points #2 and  #4 of your reply. Your 5th point about the MCP23017 having more options makes it some complicated (for me) to use at this point smiley-sad    

This is what I used to test the mcp23017 chip knightrider style (no human interaction) http://docs.macetech.com/doku.php/centipede_shield

This is the chip I have and am attempting to use
http://ww1.microchip.com/downloads/en/devicedoc/21952b.pdf

This is the one uesed by Grumpy_Mike in the midifootsteps project ( from where I get the I2C setup we are discussing)
http://ww1.microchip.com/downloads/en/DeviceDoc/20090C.pdf
so parts dealing with the latter should be make to suite the former.....
« Last Edit: May 08, 2012, 11:04:13 am by Pitchoilcan » Logged

================================
http://twit.tv/floss61
Think different
Think UbuntuStudio
============================

New York City, NY
Offline Offline
Full Member
***
Karma: 0
Posts: 141
Arduino Rocks!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Example of the MCP23017 using centipede library and sketch. KnightRider style. No Human interaction. The mus shield is wired up to my inputs i.e. Piezo sensors. thought not in use here the midi shield is used to output midi note data (again not used here). Stay tuned.
PS adafru.it has a library for the mcp23017 however Grumpy_mike uses an MCP23016 with just the wire library. Please note that in all cases the wire library in being used

The centipede shield was NOT used in this demo!
My i2c bus wiring
in the above photo I'm using the mega 2560 but in my project and in the test I'm using the duemilanove. The only resistor used are on the 16 attached to the LED pins. Arduino pins 4 and 5 have no resistors at this point.

the library and the code can be found here http://docs.macetech.com/doku.php/centipede_shield
« Last Edit: May 08, 2012, 02:21:22 pm by Pitchoilcan » Logged

================================
http://twit.tv/floss61
Think different
Think UbuntuStudio
============================

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So why do you not use the centipede library with your own project? Then you would not have to rewrite anything.
As for the reset pin I connect it to an arduino output and toggle it on start up.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if(w != x)
  {   // something has changed
// write the value of x to your LED port expander interface here
    y = 1;

Quote
some have resistors on pins 4 and 5 other don't,
The ones without pull up resistors on pins 4 & 5 are wrong, no debate about it, it is just wrong.

Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK lets spell it out. Use the Centipede library and change your code to write out all 16 bits at once to light your LEDs:-
Code:
if(w != x)
  {   // something has changed
// write the value of x to your LED port expander interface here
   myInstance.portWrite(0, x);
    y = 1;
Having first made an instance ( I called it myInstance ) like you did in the knightrider program, and setting all the bits to outputs  like you did in the knightrider program.
Logged

New York City, NY
Offline Offline
Full Member
***
Karma: 0
Posts: 141
Arduino Rocks!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

add
Code:
#include <Centipede.h>
and change
Code:
if(w != x)
  {   // something has changed
// write the value of x to your LED port expander interface here
    y = 1;
to
Code:
if(w != x)
  {   // something has changed
// write the value of x to your LED port expander interface here
   myInstance.portWrite(0, x);
    y = 1;
« Last Edit: May 20, 2012, 09:22:04 am by Pitchoilcan » Logged

================================
http://twit.tv/floss61
Think different
Think UbuntuStudio
============================

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Add:-
Code:
#include <Centipede.h>
Centipede myInstance; // create Centipede object

Then inside the setup() function add:-
Code:
  myInstance.initialize(); // set all registers to default
  myInstance.portMode(0, 0); // set all pins on chip 0 to output

then what I said before:-
Code:
if(w != x)
  {   // something has changed
// write the value of x to your LED port expander interface here
   myInstance.portWrite(0, x);
    y = 1;
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

But this is totally different code to what you posted earlier. I can't even see the variable x mentioned in this code you have just posted. Do you understand what you are trying to do?
You need to send to the LEDs a 16 bit value, an integer. Each bit in the integer represents an LED that will turn on or off. When you scan through all the sensors that other code was putting a bit in an integer that represented the state of that sensor.
What is that code you posted? Have you missed things out of it?
Logged

New York City, NY
Offline Offline
Full Member
***
Karma: 0
Posts: 141
Arduino Rocks!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mike Thanks for the info I checked and now my running v1.0. So I'll Try to leave the whole thing intact including the qtrSensors, and see how far I get. I understand what I'm trying to do but not how to do it.  And marco_c I've made note of your update to the mux section.  So my focus is still on the LEDs

and trying to turn them on/off based on whats happening here
Code:
void checkSensors(int analogPin){

  for(int pin=0; pin < 16; pin++){
    //hitavg = analogRead(pin);                              // read the input pin
    //hitavg = muxArray[pin];    // read the input pin
    if(analogPin==0){
      hitavg = mux0array[pin];
      pad=pin;
    }
    else if(analogPin==1){
      hitavg = mux1array[pin];
      pad=pin+16;
    }
    else if(analogPin==2){
      hitavg = mux2array[pin];
      pad=pin+32;
    }

    if((hitavg > PadCutOff[pin])){
 
        //Serial.write("hitavg > PadCutOff[pin])");
        //Serial.write(' ');
      if((activePad[pad] == false)){
        if(VelocityFlag == true){
          //hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin]));    // With full range (Too sensitive ?)
          hitavg = (hitavg / 8) -1 ;                                                 // Upper range
        }
        else{
          hitavg = 127;
        }
        if (analogPin==0 && PadNote[pad]==42){ //  array position = 7 , Hihat is handeld in a special way
    
          qtra.readCalibrated(sensorValues);
        
          unsigned char i;

          for (i = 0; i < NUM_SENSORS; i++){
            //Serial.write(sensorValues[i] * 10 / 1001);
            //Serial.write(' ');
            hihatPos = sensorValues[i] * 10 / 1001;
            if (hihatPos==0){
              MIDI_TX(144,42,hitavg);
              PinPlayTime[7] = 0;
              activePad[7] = true;
             // hihatWasTriggered=false;
            }
            else if (hihatPos >0 && hihatPos <= 6){
              MIDI_TX(144,44,hitavg);
              PinPlayTime[9] = 0;
              activePad[9] = true;
             // hihatWasTriggered = true;
            }
            else{

              MIDI_TX(144,46,hitavg);
              PinPlayTime[11] = 0;
              activePad[11] = true;
             // hihatWasTriggered = true;
            }
          }
        }

        else{

            MIDI_TX(144,PadNote[pad],hitavg);
            PinPlayTime[pad] = 0;
            activePad[pad] = true;
        }
      }
      else{    
        PinPlayTime[pad] = PinPlayTime[pad] + 1;
      }
    }
    else if((activePad[pad] == true)){
      PinPlayTime[pad] = PinPlayTime[pad] + 1;

      if(PinPlayTime[pad] > MaxPlayTime[pad]){
        activePad[pad] = false;
        MIDI_TX(128,PadNote[pad],127);
      }
    }
  }
  
}
« Last Edit: May 10, 2012, 11:02:12 pm by Pitchoilcan » Logged

================================
http://twit.tv/floss61
Think different
Think UbuntuStudio
============================

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1287
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You really need to understand what you are trying to achieve rather than just copying code, because your data mapping may/will be different from what others have done. Discipline is required!

Here's what I suggest as an approach:
1. Understand the commands you need to send to the MCP chip and how tio interact with it. As you had your knightrider thing going I am going to assume that you have some idea on how this needs to be done. Add the code to initialise the MCP thru the I2C in the setup function.

2. You need to work out how the data in your arrays (activePad?) maps to the bits for the MCP. Actually do this on a bit of paper - which element goes to which output bit - if is not clear. Hopefully you have a design that is linear and all the bits are consecutive which makes it easier as you can use loops.

3. Once the mapping is done, you then construct the 16 bit words using the ORing function we discussed at the start of this thread.

4. Then send those bytes to the MCP using the right address on the I2C interface.
« Last Edit: May 10, 2012, 03:42:44 am by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

New York City, NY
Offline Offline
Full Member
***
Karma: 0
Posts: 141
Arduino Rocks!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the suggestion!
working on the steps.........
#include <Wire.h>
#include <Centipede.h>
 
 
/* Available commands
  .digitalWrite([0...127], [LOW...HIGH]) - Acts like normal digitalWrite
  .digitalRead([0...127]) - Acts like normal digitalRead
 .pinMode([0...127], [INPUT...OUTPUT]) - Acts like normal pinMode
 .portWrite([0...7], [0...65535]) - Writes 16-bit value to one port (chip)
  .portRead([0...7]) - Reads 16-bit value from one port (chip)
.portMode([0...7], [0...65535]) - Write I/O mask to one port (chip)
  .pinPullup([0...127], [LOW...HIGH]) - Sets pullup on input pin
  .portPullup([0...7], [0...65535]) - Sets pullups on one port (chip)
  .init() - Sets all registers to initial values
 
  Examples
  CS.init();
  CS.pinMode(0,OUTPUT);
  CS.digitalWrite(0, HIGH);
  int recpin = CS.digitalRead(0);
  CS.portMode(0, 0b0111111001111110); // 0 = output, 1 = input
  CS.portWrite(0, 0b1000000110000001); // 0 = LOW, 1 = HIGH

  int recport = CS.portRead(0);
  CS.pinPullup(1,HIGH);
 CS.portPullup(0, 0b0111111001111110); // 0 = no pullup, 1 = pullup
*/
« Last Edit: May 11, 2012, 08:15:15 am by Pitchoilcan » Logged

================================
http://twit.tv/floss61
Think different
Think UbuntuStudio
============================

New York City, NY
Offline Offline
Full Member
***
Karma: 0
Posts: 141
Arduino Rocks!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 [ Two's complement ]
doing the steps
TABLE 1-2:
REGISTER ADDRESSES
Quote
Address
IOCON.BANK = 1
00h 10h 01h 11h 02h 12h 03h 13h 04h 14h 05h 15h 06h 16h 07h 17h 08h 18h 09h 19h 0Ah 1Ah
Address
IOCON.BANK = 0
00h 01h 02h 03h 04h 05h 06h 07h 08h 09h 0Ah 0Bh 0Ch 0Dh 0Eh 0Fh 10h 11h 12h 13h 14h 15h

Access to:
IODIRA  IPOLA  GPINTENA  DEFVALA  INTCONA  IOCON GPPUA  INTFA  INTCAPA  GPIOA  OLATA
IODIRB IPOLB  GPINTENB  DEFVALB  INTCONB  IOCON GPPUB INTFB  INTCAPB  GPIOB  OLATB
my muX bits

LSB                                                       MSB
     0 1  2 4 5 6 7 8 9 10 11 12 13 14 15

http://ww1.microchip.com/downloads/en/devicedoc/21952b.pdf

The default mode of the mcp2317 is the sequential mode which is more like the knightrider example, however what I need is BYTE mode....
« Last Edit: May 11, 2012, 11:58:21 pm by Pitchoilcan » Logged

================================
http://twit.tv/floss61
Think different
Think UbuntuStudio
============================

Pages: 1 [2] 3 4 ... 6   Go Up
Jump to: