Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 31

Thread: Teensy 3.2 and MCP23S17 expanded i/o

  1. #1
    Junior Member
    Join Date
    Jun 2019
    Posts
    15

    Teensy 3.2 and MCP23S17 expanded i/o

    Hello. A bit of background. Recently I purchased a used GCU (Garmin Control Unit) thinking it was a basically a keyboard (long story); to find out it is not. It is however a typical USB HID. Using (HHDSoftware) a USB analyzer, I could see the data packets when I press a button or turned a knob. I thought, why don't I import the data packets into Excel? Well, that's a bit more work than I want. I could use Visual Basic but that requires learning it first. Then I thought, why don't I replace the Teensy (and keep original intact) and make it a joystick. There is a great program out there called: FSUIPC. It allows interface between joysticks and keyboards to the flight simulator. I would prefer to make the Teensy a joystick but FSUIPC only see 32 inputs per hardware device. So a keyboard would work better. I've seen a keyboard example but the GCU also has 8 MK20DS17 expanded i/o modules. What code would be required to make the teensy a FULL keyboard using the expanded i/o? Thank you.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,343
    I don't really understand the "background" part of your message. But I'll try to answer the one part of your message I do understand.

    Quote Originally Posted by gr8guitar View Post
    What code would be required to make the teensy a FULL keyboard using the expanded i/o?
    This is really 2 separate parts, which you would combine together.

    To make Teensy behave as a USB keyboard, you click Tools > USB Type in Arduino and select Keyboard. Then you use functions like Keyboard.print() or Keyboard.press() and Keyboard.release() to cause Teensy to send keystrokes. Detailed documentation is here:

    https://www.pjrc.com/teensy/td_keyboard.html

    In Arduino, click File > Examples > Teensy > USB_Keyboard to find examples you can use to get started.


    The other part involves how to read those I/O expander chips. I haven't personally used that one. The I2C version is much more common. But if you have ready-to-use modules, hopefully the vendor provides a library which you can use to access them?

    If you somehow bought I/O expander modules that have absolutely no Arduino software library or examples, maybe we can help you figure out how to use them. But perhaps you could give a little more detail, like a link to the place you bought them, or at least photos of the hardware so we can actually see (rather then guess) what hardware you're actually using.

  3. #3
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello. Thank you for your reply. I was able to get the keyboard to work but only using the existing pins on the Teensy. What I need is to get access to the pins on the MCP23S17 (corrected part number) expanded I/O boards. I will try to keep this short but hopefully succinct. I purchased a Garmin Control Unit (GCU) from Ebay. Currently the manufacturer (Noble Flight Simulations) made this is for the flight simulator X-Plane only. I use FS2004(FS9) and FSX and FSUIPC for hardwire interface. However, after conversing with the seller and the manufacturer, I was under the impression I was getting basically a keyboard. So I bought it only to find out, it is not. It is however a standard USB HID controller. I then thought of exporting the data packets into Excel. Later found out I need to learn Visual Basic. Using a USB analyzer (HDDSoftware), I found out the "brain" is a Teensy. To re-instate, this is an already assembled product with a Teensy 3.2, with 8 MCP23S17 ( = 128 bits) expanded I/O boards that goes through 2 40-pin connectors that goes to 93 switches/rotary encoders and 35 LED's. How 128 pins goes through 80 wires has me confused; thinking there is some kind of multiplexing going on because there are no diodes for a switch matrix). That isn't so important to me as just getting the MCP23S17's to work. I understand the basic hardwire part of the MCP23S17 and verified the wiring from the Teensy to the MCP23S17's makes sense. I have downloaded various SPI.h and MCP23S17.h examples but cannot get any of them to work when I push any button or switch. Another part has me confused about the MCP23S17 is that the information online shows that +3v must go to pin 25, RESET but the GCU worked without external power.; only using the USB cable to the Teensy. When I applied +3v from the Teensy directly to pin 25, then the Teensy didn't work. Here are some pictures...Click image for larger version. 

Name:	GCU button pad layout-small.JPG 
Views:	13 
Size:	41.0 KB 
ID:	16923Click image for larger version. 

Name:	GCU button soldered connections-2 small.JPG 
Views:	13 
Size:	117.4 KB 
ID:	16924Click image for larger version. 

Name:	GCU-PCB-2 40-pin connectors small.JPG 
Views:	11 
Size:	81.8 KB 
ID:	16925

  4. #4
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Added a picture of the Teensy and 8 MCP23S17's:Click image for larger version. 

Name:	GCU-PCB-A small.JPG 
Views:	24 
Size:	87.5 KB 
ID:	16926
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	GCU button soldered connections small.JPG 
Views:	9 
Size:	95.2 KB 
ID:	16927  

  5. #5
    does the existing board transmit data using serial ?

  6. #6
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello. Thank you for your reply. No, it does not transmit serial data. I wished because I could use Excel to parse out the data. I've done this with GPS sentences. Before I removed the initial program in the Teensy, this device did put out data packets. I could see the data packets using a USB analyzer (HDDSoftware) For example, when I rotated the heading dial to the left, I would get:

    NFSG1000GCU_HEADING_DECR

    Again, this was not through the Serial/COM port; only through the USB port.

  7. #7
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    899
    these chips have the option to use interrupts, so there may have been a set up in code to wait, or it may have been set up to poll. I use Sumotoys library and use polling with the Teensy 3.5, as this is fast enough. You can find his library and documentation here: https://github.com/sumotoy/gpio_expander

    the chip wiring:
    IOB-0 [| U |] IOA-7
    IOB-1 [| |] IOA-6
    IOB-2 [| |] IOA-5
    IOB-3 [| |] IOA-4
    IOB-4 [| |] IOA-3
    IOB-5 [| |] IOA-2
    IOB-6 [| |] IOA-1
    IOB-7 [| |] IOA-0
    +VE [| |] INT-A
    GND [| |] INT-B
    t35 10 --> CS/SS [| |] RST (connect to +)
    t35 13/14 --> SCK [| |] A2
    t35 11 --> MOSI [| |] A1
    t35 12 <-- MISO [|_____|] A0

    Addressing the chips:

    Basic Address: 00100 A2 A1 A0 (from 0x20 to 0x27)
    A2,A1,A0 tied to ground = 0x20

    There are two banks of IO, A and B

    You set the pins in SumoToy library by
    Code:
    #include <SPI.h>        // import library
    #include <mcp23s17.h>   // import library
    Code:
    //*****************instances of each MCP23S17 Port expander chip****************//
    mcp23s17 mcp0(10, 0x20,30000000);//all three ground
    mcp23s17 mcp1(10, 0x21,30000000);//A0 +ve, A1 gnd, A2 gnd
    mcp23s17 mcp2(10, 0x22,30000000);//A0 gnd, A1 +ve, A2 gnd
    mcp23s17 mcp3(10, 0x23,30000000);//A0 +ve, A1 +ve, A2 gnd
    mcp23s17 mcp4(10, 0x24,30000000);//A0 gnd, A1 gnd, A2 +ve
    mcp23s17 mcp5(10, 0x25,30000000);//A0 +ve, A1 gnd, A2 +ve
    mcp23s17 mcp6(10, 0x26,30000000);//A0 gnd, A1 +ve, A2 +ve
    mcp23s17 mcp7(10, 0x27,30000000);//all three positive
    in void Setup
    Code:
      SPI.setSCK(14);//avoid the led pin 13
      mcp0.begin();
      mcp1.begin();
      mcp2.begin();
      mcp3.begin();
      mcp4.begin();
      mcp5.begin();
      mcp6.begin();
      mcp7.begin();
    Code:
     mcp0.gpioRegisterWriteByte(mcp0.IODIR,0b00011111, true);//zero = output //gpio 0 to 3 = output, gpio 4 to 7 = input
      mcp1.gpioRegisterWriteByte(mcp1.IODIR,0b00011111, true);
      mcp2.gpioRegisterWriteByte(mcp2.IODIR,0b00011111, true);
      mcp3.gpioRegisterWriteByte(mcp3.IODIR,0b00011111, true);
      mcp4.gpioRegisterWriteByte(mcp4.IODIR,0b00011111, true);
      mcp5.gpioRegisterWriteByte(mcp5.IODIR,0b00011111, true);
      mcp6.gpioRegisterWriteByte(mcp6.IODIR,0b00011111, true);
      mcp7.gpioRegisterWriteByte(mcp7.IODIR,0b00011111, true);
    alternatively:
    //setup the gpio!
    Code:
      /*        7     6     5       4     3   2     1    0
       IOCON = BANK MIRROR SEQOP DISSLW HAEN ODR INTPOL -NC- */
      mcp0.gpioRegisterWriteByte(mcp0.IODIR,0b00011111, true);//zero = output //gpio 0 to 3 = output, gpio 4 to 7 = input
      mcp0.gpioRegisterWriteByte(mcp0.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
      mcp0.gpioRegisterWriteByte(mcp0.GPPU, 0xff, true);//pull-up only required input pins?
    to read all the chip ports and not use interrupts, put all the chip addresses in an array and iterate over in your loop if you can get it go fast enough:

    Code:
    //update all chips every loop = buttons and rotary values into array
      for(int x=0;x<8;x++){ mcpChips[x]=mcpArray[x].readGpioPort();//read all chips
        }
    where the chips are in the array as example:
    Code:
    //new arrangenment of chips
    mcp23s17 mcpArray[8] = {
    mcp3,mcp2,mcp1,mcp0,
    mcp7,mcp6,mcp5,mcp4
    };
    Last edited by mortonkopf; 07-08-2019 at 08:21 AM.

  8. #8
    did you overwrite the original code on the teensy ?

    PaulStoffregen is there a way to clone the rom so it can be reprogrammed at a later date ?

    does this device talk to your flight simulator program ?

    you may have to return it to the manufacturer to get it reprogrammed

  9. #9
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    899
    Quote Originally Posted by Gadget999 View Post
    you may have to return it to the manufacturer to get it reprogrammed
    The best course of action is to return for reprogramming

  10. #10
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello Mortonkopf. Thank you for that information, that was the type of hint I was looking to obtain. Hello Gadget999, thank you for your reply. I did try to export the code before I "reformatted" it but when I looked at it *.hex), it was just blank so nothing got exported. I may be able to return to the original manufacturer (Noble Flight Simulations) to re-code, probably around the cost of a new one (~$1000) since I bought a used one from Ebay and not from the manufacturer. 1 ) Cost - ugh! 2) I really don't need/want the original code anyway because it's for the X-Plane. I use the FS2004(FS9) and FSX. 3) This device is also hardware specific to the manufacturer's setup and aircraft. My way will allow it to be used with any aircraft in FS9 or FSX (and the new one due out next year). 4) I would have to learn Visual Basic to extract the data packets from the original code. I really wanted, and thought I was getting a keyboard device. So I will either pursue getting the Teensy I have to work with the MCP23S17's or re-wire the buttons/rotary encoders to either a keyboard device or joystick device(s). It's been nice to be exposed to the versatility of the Teensy/Arduino but with all this messing around so far, I could have had the latter part done by now and been back to "flying." If I'm able, or someone else out there, to be successful with getting it to work, it can be useful for any of Microsoft's flight simulators. Again, thanks for the assistance - onward to Mortonkopf's suggestion.

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,343
    Quote Originally Posted by Gadget999 View Post
    PaulStoffregen is there a way to clone the rom so it can be reprogrammed at a later date ?
    Teensy's bootloader and the Teensy Loader application are specifically designed to *not* allow this. We have many people who create products using Teensy, who do not wish to see their code cloned.

  12. #12
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello Mortonkopf. I have a question, what do you mean by "t" mentioned above at #7:

    t35 10 --> CS/SS [| |] RST (connect to +)
    t35 13/14 --> SCK [| |] A2
    t35 11 --> MOSI [| |] A1
    t35 12 <-- MISO [|_____|] A0

    Also, aren't A2,A1,A0 used for addressing, not SCK, MOSI, and MISO respectively?

    I found a drawing from some example for the MCP23S17, with my modifications, that showed this:

    __ __
    [-- PIN 1 IOB-0 [| U |] IOA-7 --] PIN 28
    | PIN 2 IOB-1 [| |] IOA-6 | PIN 27
    | PIN 3 IOB-2 [| |] IOA-5 | PIN 26
    | PIN 4 IOB-3 [| |] IOA-4 | PIN 25
    Port B PIN 5 IOB-4 [| |] IOA-3 Port A PIN 24
    | PIN 6 IOB-5 [| |] IOA-2 | PIN 23
    | PIN 7 IOB-6 [| |] IOA-1 | PIN 22
    [-- PIN 8 IOB-7 [| |] IOA-0 --] PIN 21
    PIN 9 ++++ [| |] INT-A PIN 20
    PIN 10 GND [| |] INT-B PIN 19
    PIN 11 CS [| |] RST (connect to +) PIN 18
    PIN 12 SCK [| |] A2 -| PIN 17
    PIN 13 MOSI [| |] A1 -|-- ADDR PIN 16
    PIN 14 MISO [|______|] A0 -| PIN 15

    Also, I get an error message " 'mcp' was not declared in this scope. I hate to admit it but I'm completely new to Teensy, and for that matter C, C+, C#, etc. I am thinking that the 'mcp' must be made some data type, if so, how does one determine that from an example such as this?
    Last edited by gr8guitar; 07-09-2019 at 02:25 AM.

  13. #13
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello Mortonkopf. By the way, how are you extracting the individual pin status from the above information? To me, it looks like byte reads/writes, yes?

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,343
    Quote Originally Posted by gr8guitar View Post
    I hate to admit it but I'm completely new to Teensy, and for that matter C, C+, C#, etc.
    You're probably going to need to put some time into learning the basics. We have a tutorial, which admittedly is pretty old (screenshots from a very old version of Arduino) but all the info is still good.

    https://www.pjrc.com/teensy/tutorial.html

    If you've already installed Arduino and know how to upload code to your Teensy 3.2, then you can skip the first page.

    Probably the most important info to learn is on page 3. You will need to print stuff to the serial monitor. Even though this tutorial is for connecting a single button to a pin directly on the Teensy (not an I/O expander chip), the info in this tutorial is essential background you will need. Familiarity with using the serial monitor is especially important. Even if you intend to ultimately have Teensy act as a USB keyboard, the serial monitor is tool you'll use to get almost all of your project working.

    Your best path is probably to get another Teensy and the tutorial kit parts, and a solderless breadboard if you don't already have one. While this involves buying more stuff, it's not very expensive... compared to having a painful "learning experience" which damages that rather expensive circuit board.

    Please, do yourself a huge favor and work on getting the single button result printing in the serial monitor from that tutorial. I highly recommend connecting a voltmeter, as shown in the tutorial. This same approach will serve you well for trying to get this project working, so I hope you'll at least do page 3 of the tutorial.


    Also, I get an error message " 'mcp' was not declared in this scope.
    Everyone starts as a beginner. We get that, and we can help you with these sorts of errors. But we do expect you to follow certain guidelines and rules, where the main one is in red at the top of every page on this forum. You really need to show the complete program that gives the error. Imagine that I or anyone else on this forum actually will copy the code into Arduino and click Verify. If any part of the code is missing, we'll get a different error.

    Copying the code is easy. In Arduino, just press Ctrl-A to select it all, and Cltr-C to copy to the clipboard. Then here on the form, click that little "#" button for the code tags (which preserve the spacing and shows it in a small section if the code is really long) and press Ctrl-V to copy all the code into your message.

    Don't be shy. We want to help you. If you look around this forum's old messages, you'll see countless times where we quickly figure out what's wrong when we see the complete code, and unfortunately many more where it takes a long time and a lot of guesswork when we're kept in the dark.

  15. #15
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello. I'm surprised you mentioning getting a Teensy, etc. to experiment. I just bought a Teensy from your company a few days ago. And yes I have a breadboard, etc. I also have the keyboard part working, etc. too. And I have the serial working; sort of... Using HDDSoftware's USB analyzer, I can see the Serial information I coded but for some reason, Ardruino's Serial Monitor doesn't seem to work - verified COM port. More importantly, what is not working currently is the expanded I/O. I've been reading rigorously since I got the Teensy, so yes, I realize there are many things to learn. So far, the downloaded MCP23S17 examples are not working. Hopefully I'll get there though. Thank you.
    Last edited by gr8guitar; 07-09-2019 at 06:18 PM.

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,343
    Quote Originally Posted by gr8guitar View Post
    but for some reason, Ardruino's Serial Monitor doesn't seem to work - verified COM port.
    Maybe add "while (!Serial) ; " in setup(), so your program waits for the serial monitor to be opened.

    If that doesn't work, maybe try showing a complete program that reproduces the problem (that "forum rule" again) and we'll probably be able to help you with something better than a blind guess.

  17. #17
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    899
    hi there @Gr8guitar. Happy to try and help out, I am not sure of how familiar you are with the language and the programming environment, the support for these chips is not the easiest to get your head around. If you download and install Sumotoy library you will see on the GitHub page (https://github.com/sumotoy/gpio_expander ) that there is a command list. in it there is the command to read the pins "readGpioPort();". if you attach this command to the chip you want to read, then it will read the bit values of each of the expander port bits. So in my example above, i first of all gave each of the mcl expanders a name, to instantiate it, such as "mcp23s17 mcp0(10, 0x20,30000000);",

    mcp is the name I gave the chip when I instantiated it; mcp0, mcp1, mcp2 etc.

    my setting out the pins on the chip were confusing, I agree. t35 was my shorthand for Teensy3.5, and the brackets show the chip between the two sides of the chip. so yes sck, mosi etc are on one side, and the address pins are on the other side.
    Code:
    t35 10 --> CS/SS [| |] RST (connect to +)
    t35 13/14 --> SCK [| |] A2
    t35 11 --> MOSI [| |] A1
    t35 12 <-- MISO [|_____|] A0

  18. #18
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    899
    here is an schematic of the mcp23s17 using inputs and outputs set and read by the bit read functions
    Click image for larger version. 

Name:	mcp23s17_rotary.png 
Views:	11 
Size:	194.5 KB 
ID:	16945

    you might some reaction from the chips using this code if you know which chip is address zero. copy and paste into a fresh sketch, and make sure you have the right mcp23 library, as the calls will be different.

    Code:
    //using the library from SUMOTOY at https://github.com/sumotoy/gpio_expander
    #include <SPI.h>        // import library
    #include <mcp23s17.h>   // import library 
    
    
    //*****************instances of each MCP23S17 Port expander chip****************//
    mcp23s17 mcp0(10, 0x20,30000000);//all three ground
    
    int portRead =0;
    
    void setup() {
    
      Serial.begin(31250);
      mcp0.begin();
      //set the pins either input or output 0=output, 1=input.
      mcp0.gpioRegisterWriteByte(mcp0.IODIR,0b00011111, true);//zero = output //gpio 0 to 3 = output, gpio 4 to 7 = input
     
      mcp0.gpioRegisterWriteByte(mcp0.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
      mcp0.gpioRegisterWriteByte(mcp0.GPPU, 0xff, true);//pull-up only required input pins???
    }
    
    void loop() {
      portRead = mcp0.readGpioPort();
      Serial.println("hello serial");
      Serial.println(portRead);  
    }
    Last edited by mortonkopf; 07-09-2019 at 07:31 PM.

  19. #19
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello. Prior to Mortonkopt's aned Paul's recent reply this is what I had: (which the expanded i/o did not work - more on that later)
    Code:
    #include <SPI.h>
    #include <mcp23s17.h>   // import library
    
    //define CS pin and using HAEN or not
    //to use HAEN, address should be 0x20 to 0x27
    mcp23s17 mcp0(10,0x20,30000000);//instance (address A0,A1,A2 tied to GND)
    //mcp23s17 mcp1(10,0x21,30000000);//A0 +ve, A1 gnd, A2 gnd
    mcp23s17 mcp2(10,0x22,30000000);//A0 gnd, A1 +ve, A2 gnd
    mcp23s17 mcp3(10,0x23,30000000);//A0 +ve, A1 +ve, A2 gnd
    mcp23s17 mcp4(10,0x24,30000000);//A0 gnd, A1 gnd, A2 +ve
    mcp23s17 mcp5(10,0x25,30000000);//A0 +ve, A1 gnd, A2 +ve
    mcp23s17 mcp6(10,0x26,30000000);//A0 gnd, A1 +ve, A2 +ve
    mcp23s17 mcp7(10,0x27,30000000);//all three positive
    
    
    
    void setup(){
    
      Serial.begin(9600);
       SPI.setSCK(14);//avoid the led pin 13
    
    //----- Chip Zero -------   
     
     int ChipZeroPinZero = 0;
     int ChipZeroPinOne = 0;
     int ChipZeroPinTwo = 0;
     
      mcp0.begin();//x.begin(1) will override automatic SPI initialization
    
     mcp0.gpioPinMode(0,INPUT_PULLUP);
     mcp0.gpioPinMode(1,INPUT_PULLUP);
     mcp0.gpioPinMode(2,INPUT_PULLUP);
     
    //----- Chip One -------
    
      int ChipOnePinZero = 0;
      int ChipOnePinOne = 0;
      
      mcp1.begin();//x.begin(1) will override automatic SPI initialization
      mcp1.gpioPinMode(INPUT);
    
    
    
     mcp6.begin(); // maybe output
     mcp6.gpioPinMode(OUTPUT); 
    
     mcp7.begin(); // maybe output
     mcp7.gpioPinMode(OUTPUT); 
     
    }
    
    void loop(){
     
    mcp0.gpioRegisterWriteByte(mcp0.IODIR,0b11111111, true);
    mcp0.gpioRegisterWriteByte(mcp0.IOCON, 0b01101110);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
    mcp0.gpioRegisterWriteByte(mcp0.GPPU, 0xff, true);//pull-up only required input pins?
    
     
     int ChipZeroPinZero = mcp0.gpioDigitalRead(0);
         if (ChipZeroPinZero == 7)
         {
          Serial.println ("C0P0 is ON");
          Serial.println(); 
         }
         else
         {
          Serial.println("C0P0 is OFF");
          Serial.print('\n');
         }
    
     int ChipZeroPinOne= mcp0.gpioDigitalRead(1);
         if (ChipZeroPinOne == 1)
         {
          Serial.println ("C0P1 is ON");
          Serial.print('\n');
         }
         else
         {
          Serial.println("C0P1 is OFF");
          Serial.println();
         }
    
         int ChipZeroPinTwo= mcp0.gpioDigitalRead(2);
         if (ChipZeroPinTwo == 1)
         {
          Serial.println ("C0P2 is ON");
         }
         else
         {
          Serial.println("C0P2 is OFF");
          Serial.println();
         }
        
    
    //---------- Chip One -----------
    
    mcp1.gpioRegisterWriteByte(mcp1.IODIR,0b11111111, true);
    mcp1.gpioRegisterWriteByte(mcp1.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
    mcp1.gpioRegisterWriteByte(mcp1.GPPU, 0xff, true);//pull-up only required input pins?
     int ChipOnePinZero = mcp1.gpioDigitalRead(0);
    
        if (ChipOnePinZero == 1)
         {
          Serial.println ("C1P0 is ON");
           }
         else
         {
          Serial.println("C1P0 is OFF");
       
    //---------- outputs -----
    
    
    //mcp6.gpioRegisterWriteByte(mcp6.IODIR,0b00000000, true);
    //mcp6.gpioRegisterWriteByte(mcp6.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
    
    //mcp7.gpioRegisterWriteByte(mcp7.IODIR,0b00000000, true);
    //mcp7.gpioRegisterWriteByte(mcp7.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
    
    
    
        delay(1000);
       
     
    }
    As I mentioned, I do have the Serial working but only with using HHDSoftware's USB analyzer. With it, I can see the Serial code written. I have gone over Microchip's manual on the MCP23x17's PDF but it did not really make much sense as I could not find the direct information used by Sumotoy's examples. You are so correct Mortonkopf, the parameters either don't make sense to me - yet or when I try to apply them (i.e.: mcp6.gpioRegisterReadByte(mcp6.IODIR,0b1111111, true); or mcp6.gpioRegisterWriteByte(mcp6.IODIRA,0b11111111, true); have some data type mismatch. I will now look at Mortonkopf's and Paul's above message and see where I go. I appreciate the time and information. Also as a caveat, there are 80 pin connectors used to communicate with 93 inputs and 35 outputs so I'm not sure how a direct reading will of a pin will occur but I will let you know if it makes sense to me.

  20. #20
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    899
    It looks like this is going to be a long haul. your best best is to get used to the serial monitor built in with the Arduino IDE, it makes life very simple when Debugging, as you can insert simple lines into your code at strategic points to see if the programme reaches that point or not. I would start with the simplest possible code to read a single mcp chip and use Serial.Println command to write to the serial monitor of the IDE.

    Also as a caveat, there are 80 pin connectors used to communicate with 93 inputs and 35 outputs so I'm not sure how a direct reading will of a pin will occur but I will let you know if it makes sense to me.
    the library has two parts to do this. first you set the chip pins to input or output using gpio.gpioPinMode(INPUT or OUTPUT); or set an individual pin gpio.gpioPinMode(pin,mode);//set an individual pin as INPUT or OUTPUT, where gpio. is the name given to your mcp chip (mcp0 in the example I gave above).

    you then read the chip pin state by using the command gpio.readGpioPort();

    To make use of this info, you need to put the read bit state into a variable that you will access later to do something with. So, you would have a line of code that says our variable ourBitStates = gpio.readGpioPort(); or ourBitStates = mcp0.readGpioPort();

    you will do this for each chip, so each chip will have a variable to store the read values. such as ourBitStates2 = mcp2.readGpioPort();

    you can then use the values in ourBitStates. for example, you can print what the value is to the serial monitor, such as Serial.Println(ourBitStates); this will only appear as a bit states / binary (rather than hex or decimal format if you tell it to appear that way. we do this by using Serial.Println(ourBitStates, BIN);

  21. #21
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,343
    Quote Originally Posted by gr8guitar View Post
    As I mentioned, I do have the Serial working but only with using HHDSoftware's USB analyzer.
    I really want to know why the normal Arduino serial monitor isn't working. Can you give us a screenshot, so we can see how it's not working (error message, opening with a blank window, etc...)

    Normally all you need to do is upload, then when your program is running, select the correct port in the Tools > Ports menu, then open the serial monitor.

  22. #22
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello Mortonkopf. I will revisit the project today and see about what you mentioned above. Paul, I don't think I need to send a picture because, I'm just getting a blank window. I think it's partially working because on the initial setup, it had detected I selected the wrong COM port, when I selected COM5 then the window opened up but blank. I will send what I observed with the USB analyzer - which will show the Serial code written. Also, it can be seen from the analyzer, that C0P0 (ChipZeroPinZero) is ON and the readPort shows a 65535 at the same time. To get that, I accidentally rotated the Heading knob and pressed one of the Alphabet keys. For a short time, I could turn on and off this way but after, say 2,3 minutes, then nothing would happen. So, for a short period I am getting the expanded I/O to respond but very unpredictably.
    Click image for larger version. 

Name:	USBAnalyzer Data.jpg 
Views:	2 
Size:	109.3 KB 
ID:	16952

  23. #23
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Okay, an update. Attached is the Teensy setup I currently have. 1) As it can be seen, no data on the Serial Monitor but there is on the USB analyzer. 2) I mistyped above, I mentioned the Heading knob but it is the Course (CRS) knob and an Alphabet key. Notice though, that I have mcp0 and mcp1 as INPUT and mcp6 as OUTPUT, all binary data is 1111111111111111 (= 65535). No matter what button I press or knob I turn, it does not show in the data packet. Attached is the screenshot and code I currently have.

    Click image for larger version. 

Name:	EntireTeensySetup.jpg 
Views:	5 
Size:	92.6 KB 
ID:	16956

    Code:
    #include <SPI.h>
    #include <mcp23s17.h>   // import library
    #include <keyboard.h>
    
    //define CS pin and using HAEN or not
    //to use HAEN, address should be 0x20 to 0x27
    mcp23s17 mcp0(10,0x20,30000000);//instance (address A0,A1,A2 tied to GND)
    mcp23s17 mcp1(10,0x21,30000000);//A0 +ve, A1 gnd, A2 gnd
    mcp23s17 mcp2(10,0x22,30000000);//A0 gnd, A1 +ve, A2 gnd
    mcp23s17 mcp3(10,0x23,30000000);//A0 +ve, A1 +ve, A2 gnd
    mcp23s17 mcp4(10,0x24,30000000);//A0 gnd, A1 gnd, A2 +ve
    mcp23s17 mcp5(10,0x25,30000000);//A0 +ve, A1 gnd, A2 +ve
    mcp23s17 mcp6(10,0x26,30000000);//A0 gnd, A1 +ve, A2 +ve
    mcp23s17 mcp7(10,0x27,30000000);//all three positive
    
    void setup(){
      Keyboard.begin();
      Serial.begin(9600);
       while (!Serial) ; 
      SPI.setSCK(14);//avoid the led pin 13
     
      int ChipZeroPinZero = 0;
      int ChipZeroPinOne = 0;
     
      mcp0.begin();//x.begin(1) will override automatic SPI initialization
      mcp0.gpioPinMode(INPUT);
    
      mcp1.begin();//x.begin(1) will override automatic SPI initialization
      mcp1.gpioPinMode(INPUT);
    
    mcp0.gpioRegisterWriteByte(mcp0.IODIR,0b11111111, true);
    mcp0.gpioRegisterWriteByte(mcp0.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
    mcp0.gpioRegisterWriteByte(mcp0.GPPU, 0xff, true);//pull-up only required input pins?
    
    mcp1.gpioRegisterWriteByte(mcp1.IODIR,0b11111111, true);
    mcp1.gpioRegisterWriteByte(mcp1.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
    mcp1.gpioRegisterWriteByte(mcp1.GPPU, 0xff, true);//pull-up only required input pins?
    
    mcp6.gpioRegisterWriteByte(mcp6.IODIR,0b00000000, true);
    mcp6.gpioRegisterWriteByte(mcp6.IOCON, 0b00101000);//HAEN,SEQOP,MIRROR -remove mirror (ie INT pin connection)
    mcp6.gpioRegisterWriteByte(mcp6.GPPU, 0xff, true);//pull-up only required input pins?
      
    //----- Chip One -------
    
      int ChipOnePinZero = 0;
      int ChipOnePinOne = 0;
      
      mcp1.begin();//x.begin(1) will override automatic SPI initialization
      mcp1.gpioPinMode(INPUT);
    
    // ------- Outputs for LED's ? --------
    
     mcp6.begin(); // maybe output
     mcp6.gpioPinMode(OUTPUT); 
    
     mcp7.begin(); // maybe output
     mcp7.gpioPinMode(OUTPUT); 
     
    }
    
    void loop(){
     
     int ChipZeroPinZero = mcp0.gpioDigitalRead(0);
         if (ChipZeroPinZero == 1)
         {
          Serial.println ("C0P0 is ON");
          
        //  Serial.print('\n');
        //  Keyboard.print('A');
          Serial.print('A');   
          Serial.println(); 
         }
         else
         {
          Serial.println("C0P0 is OFF");
          Serial.print('\n');
         }
    
     int ChipZeroPinOne= mcp0.gpioDigitalRead(1);
         if (ChipZeroPinOne == 1)
         {
          Serial.println ("C0P1 is ON");  
         }
         else
         {
          Serial.println("C0P1 is OFF");
             Serial.print('\n');
         }
        
    //---------- Chip One -----------
    
     int ChipOnePinZero = mcp1.gpioDigitalRead(0);
         if (ChipOnePinZero == 1)
         {
          Serial.println ("C1P0 is ON");
          // I get this when I cycle the CRS dial and hit the A,B,C,D,E,F 
                     //                                      G,H,I,J,1 or 2 button
         }
         else
         {
          Serial.println("C1P0 is OFF");
         }
    
    int portReadZero = mcp0.readGpioPort();
    Serial.println (portReadZero,BIN);
    
    int portReadSix = mcp6.readGpioPort();
    Serial.println (portReadSix,BIN);
    
        delay(1000);   
     
    }
    Any suggestions would be greatly appreciated.

  24. #24
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    899
    I think that you will save yourself a lot of time by seeing if the manufacturer will reprogramme the Teensy. Anyhow, can you see from the traces which pins are being used for SPI? it may be there is no response from MCP chips as the correct pins have not been assigned for SPI.

  25. #25
    Junior Member
    Join Date
    Jun 2019
    Posts
    15
    Hello. I've done some wiring tracing. I found out the addresses (A0,A1,A2) are wired in the default mode of the respective MCP23S17's. I haven't delved into the Interrupts, etc. yet. I did put in a request to the manufacturer if he'd be willing to re-program the GCU to be just a keyboard controller; have not heard back yet. If they are, might be cost-prohibited. The manufacturer (nobleflightsim.com) sells a very program-specific (X-Plane), aircraft-specific (Cirrus SR22) and hardware-specific (their own). The quality is high and so reflects its cost. Frankly, I don't see the logic as I don't know if there are many people willing to spend that kind of money on such a general aviation aircraft-specific for a flight simulator. Personally, I think they could sell more GCU's (Garmin Control Unit), at least, if it was more user-friendly to other flight simulators, and more aircraft; as a generic product. Especially since the Teensy can be a combination of keyboard, joystick, mouse or serial functions. As I mentioned before, I will try to get the GCU to function as a keyboard with the existing hardware in the next couple of days. If I can't, I can have the GCU wired up to joystick control boards fairly quickly. I'm not too concerned about the LED's. I do not know if people in this forum are aware of a great program called hidMacros. It's now been changed to luaMacros. I use the hidMacros as it's quite simple to use. It allows keyboards on the same computer to be independent to program-specific needs. This was the motivation to get the GCU when communications suggested it was a keyboard. If I use the joystick control boards, of course the hidMacros isn't needed as FSUIPC interfaces with joysticks and keyboards. I thank you for your help, time and information.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •