Hat switches?

Doon1

Member
Hi all,
New to Teensy and programming in general. I've built a collective to fly the DCS Huey. So far I have all the switches and both axis coded. I built a 4-way hat switch using 4 tactile switches and would like to define the hat switch inputs for the searchlight. I can't find any examples of the hat switch code though. Will someone point me in the right direction.
Thanks.
John
BTW: Teensy LC
 
Are you working from
https://www.pjrc.com/teensy/td_joystick.html
and file->examples>teensy->usbjoystick->complete?
The code in that example just spins the hat switch through 360 without further input
You want to read four buttons and then produce an angle output, then provide that angle to the hat write function. So there isn't magic code to do it.

The basic way to do it is to just:
int angle =-1;//no angle input
if (digitalRead(hatButton1)==LOW) angle =0;
if (digitalRead(hatButton2)==LOW) angle =90;
if (digitalRead(hatButton3)==LOW) angle =180;
if (digitalRead(hatButton4)==LOW) angle =270;
Joystick.hat(angle);
And suggest doing that for testing purposes.

This does not handle more than one button being down at once though. You can expand things by putting four more ifs AFTER the first set of tests for 1and2 down =45, 2 and 3 =135 etc or you can combine the four inputs into a 4 bit number and use a 16 entry array to read the angles out of, which gives you more control over situations like '1 and 2 and 4 down', which are probably unlikely in this case mechanically but bear thinking about when stacking IF statements together while reading multiple buttons.
 
Thank you. Sorry for taking so long to get back. I've been getting all the hardware drawn and printed for version 2 of my collective.
Yes I am using the example file as a guide. Unfortunately the assumption is made that one (sort of) knows how to code. I should probably invest in the Arduino dummies guide.
It would seem that there are many different languages to use for Arduino programming and they are not mix and match. Leading to a great deal of confusion for a NOOB such as myself.
This is what I have:

// Hat switch
int angle =-1;//no angle input
if (digitalRead(13)==LOW) angle =0;
if (digitalRead(14)==LOW) angle =90;
if (digitalRead(15)==LOW) angle =180;
if (digitalRead(16)==LOW) angle =270;
if (digitalRead(13 and 14)==LOW) angle =45;
if (digitalRead(14 and 15)==LOW) angle =135;
if (digitalRead(15 and 16)==LOW) angle =225;
if (digitalRead(16 and 13)==LOW) angle =315;
Joystick.hat(angle);

Thank you again for your help.
John
 
There are many different ways to organize the above code. Also the above code assumes that pin 13 is the one used for up, 14 right...

Also it assumes that somewhere the code has enabled these pins to be digital Input pins.

First real question to ask is how is this all wired up? That is for this to all work, pushing a button needs to complete a circuit. So what is on the other side of each of these buttons? That is often times, they will all either be connected to a ground pin or to some voltage pin, in your case that would be 3.3v. And how are the pins wired on the connection side of the pin. That is you don't simply want the IO pins to be floating as then digitalRead(13) as an example will not give you a consistent high or low when the button is not pressed.

If you were using simple button, my next question would be, is the button Normally Open (NO) or Normally Closed(NC) i.e are the two pins connected to each other when the button is not pressed... But in this case assuming Normally Open...

Why I ask all of this, is this all influences your code. That is if you call digitalRead(13) and it reads high does it imply it is pressed or not? Also if you don't have external pull up or down resistors, this will also influence your code.

For now I assume that the common pin is connected to ground to more closely match your code. And that you probably don't have external pull up resistors, to make sure your read when not pressed is high. So in that case I would at some location, either setup() or in an init code for your device or...

Code:
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
pinMode(15, INPUT_PULLUP);
pinMode(16, INPUT_PULLUP);


And your code above would be more like:
Code:
// Hat switch
int angle =-1;//no angle input
if (digitalRead(13)==LOW) angle =0;
if (digitalRead(14)==LOW) angle =90;
if (digitalRead(15)==LOW) angle =180;
if (digitalRead(16)==LOW) angle =270;
[COLOR="#FF0000"]if ((digitalRead(13)==LOW) && (digitalRead(14)==LOW)) angle =45;[/COLOR]
if (digitalRead(14 and 15)==LOW) angle =135;
if (digitalRead(15 and 16)==LOW) angle =225;
if (digitalRead(16 and 13)==LOW) angle =315;
Joystick.hat(angle);

Obviously would need to do same for others as well. Or you could reorganize this and do it maybe more like:
Code:
// Hat switch
int angle =-1;//no angle input
if (digitalRead(13)==LOW) 
{
    if (digitalRead(14)==LOW) angle = 45;
    else if (digitalRead(16)==LOW) angle =315;
    else angle = 0;
} 
else if (digitalRead(15)==LOW) 
{
    if (digitalRead(14)==LOW) angle = 135;
    else if (digitalRead(16)==LOW) angle = 225;
    else angle = 180;
} 
else if (digitalRead(14)==LOW) angle = 90;
else if (digitalRead(16)==LOW) angle =270;
Joystick.hat(angle);

But warning typed/edited on fly so probably issues.
 
So that's why the intermediate angles weren't working, Thank you! I've added the fix.
It's a simple 12 button, 4-way hat, 2 axis (slider) controller. My code is not elegant by any means but it works, so there's that.

Code:
void setup() {
  // Joystick buttons 1-12
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);

  // Hat switch buttons
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  pinMode(17, INPUT_PULLUP);

  }

void loop() {
    if (digitalRead(0) == LOW)
  {
            Joystick.button(1, 1);
    } 
    else {
            Joystick.button(1,0);
    }
    if (digitalRead(1) == LOW)
  {
            Joystick.button(2, 1);
    } 
    else {
            Joystick.button(2,0);
    }
    if (digitalRead(2) == LOW)
  {
            Joystick.button(3, 1);
    } 
    else {
            Joystick.button(3,0);
    }
    if (digitalRead(3) == LOW)
  {
            Joystick.button(4, 1);
    } 
    else {
            Joystick.button(4,0);
    }
    if (digitalRead(4) == LOW)
  {
            Joystick.button(5, 1);
    } 
    else {
            Joystick.button(5,0);
    }
    if (digitalRead(5) == LOW)
  {
            Joystick.button(6, 1);
    } 
    else {
            Joystick.button(6,0);
    }
    if (digitalRead(6) == LOW)
  {
            Joystick.button(7, 1);
    } 
    else {
            Joystick.button(7,0);
    }
    if (digitalRead(7) == LOW)
  {
            Joystick.button(8, 1);
    } 
    else {
            Joystick.button(8,0);
    }
    if (digitalRead(8) == LOW)
  {
            Joystick.button(9, 1);
    } 
    else {
            Joystick.button(9,0);
    }
    if (digitalRead(9) == LOW)
  {
            Joystick.button(10, 1);
    } 
    else {
            Joystick.button(10,0);
    }
    if (digitalRead(10) == LOW)
  {
            Joystick.button(11, 1);
    } 
    else {
            Joystick.button(11,0);
    }
    if (digitalRead(11) == LOW)
  {
            Joystick.button(12, 1);
    } 
    else {
            Joystick.button(12,0);
    }
   
 // Hat switch
  int angle =-1;//no angle input
if (digitalRead(14)==LOW) angle =0;
if (digitalRead(15)==LOW) angle =90;
if (digitalRead(16)==LOW) angle =180;
if (digitalRead(17)==LOW) angle =270;
if ((digitalRead(14)==LOW) && (digitalRead(15)==LOW)) angle =45;
if ((digitalRead(15)==LOW) && (digitalRead(16)==LOW)) angle =135;
if ((digitalRead(16)==LOW) && (digitalRead(17)==LOW)) angle =225;
if ((digitalRead(17)==LOW) && (digitalRead(14)==LOW)) angle =315;
Joystick.hat(angle);

 // Pitch and throttle axis  
  Joystick.sliderLeft(analogRead(4));
  Joystick.sliderRight(analogRead(5));
            
    }

Now to figure out how to rename the device and give it a unique identifier as I plan on using another Teensy for a button box.
Thanks again.
John
 
Hi,

Sorry to hijack the tread, it came up in google search.

I tried various methods to call Joystick.hat();

But every time i get this error:
Code:
src\main.cpp: In function 'void loop()':
src\main.cpp:352:27: error: no matching function for call to 'usb_joystick_class::hat(int&)'
         Joystick.hat(angle);
                           ^
In file included from C:\Users\gilie\.platformio\packages\framework-arduinoteensy\cores\teensy3/WProgram.h:60:0,
                 from C:\Users\gilie\.platformio\packages\framework-arduinoteensy\cores\teensy3/Arduino.h:6,
                 from src\main.cpp:1:
C:\Users\gilie\.platformio\packages\framework-arduinoteensy\cores\teensy3/usb_joystick.h:141:21: note: candidate: void usb_joystick_class::hat(unsigned int, int)
         inline void hat(unsigned int num, int angle) {
                     ^
C:\Users\gilie\.platformio\packages\framework-arduinoteensy\cores\teensy3/usb_joystick.h:141:21: note:   candidate expects 2 arguments, 1 provided
*** [.pio\build\teensy35\src\main.cpp.o] Error 1

But in all the examples i see the command with just the angle parameter.

What am i missing?

P.S.

How do i call more then one hat switch?

Is it possible to call the Joystick.Hat like so: Joystick.hat(270) ?

Thanks.
 
Back
Top