Teensy 3.2 and MCP23S17 expanded i/o

Status
Not open for further replies.

gr8guitar

Member
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.
 
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.

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.
 
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... GCU button pad layout-small.JPGGCU button soldered connections-2 small.JPGGCU-PCB-2 40-pin connectors small.JPG
 
Added a picture of the Teensy and 8 MCP23S17's:GCU-PCB-A small.JPG
 

Attachments

  • GCU button soldered connections small.JPG
    GCU button soldered connections small.JPG
    95.2 KB · Views: 106
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.
 
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:
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
 
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.
 
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.
 
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:
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?
 
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.
 
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:
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.
 
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
 
here is an schematic of the mcp23s17 using inputs and outputs set and read by the bit read functions
mcp23s17_rotary.png

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:
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.
 
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);
 
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.
 
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.
USBAnalyzer Data.jpg
 
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.

EntireTeensySetup.jpg

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.
 
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.
 
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.
 
Status
Not open for further replies.
Back
Top