Buttonbox met joystick

Ik heb recent de buttonbox van 32 buttons gebouwd maar ik wil ipv 4 encoders maar 2 encoders gebruiken en de andere 2 vervangen door potentiometers van een joystick maar nu is mijn vraag wat moet ik dan aanpassen op deze code ik gebruik een atmega32u4 en heb aleen nog pin 2 en 3 over

`//BUTTON BOX 
//USE w ProMicro
//Tested in WIN10 + Assetto Corsa
//AMSTUDIO
//20.8.17

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMROTARIES 4
#define NUMBUTTONS 24
#define NUMROWS 5
#define NUMCOLS 5


byte buttons[NUMROWS][NUMCOLS] = {
  {0,1,2,3,4},
  {5,6,7,8,9},
  {10,11,12,13,14},
  {15,16,17,18,19},
  {20,21,22,23},
};

struct rotariesdef {
  byte pin1;
  byte pin2;
  int ccwchar;
  int cwchar;
  volatile unsigned char state;
};

rotariesdef rotaries[NUMROTARIES] {
  {0,1,24,25,0},
  {2,3,26,27,0},
  {4,5,28,29,0},
  {6,7,30,31,0},
};

#define DIR_CCW 0x10
#define DIR_CW 0x20
#define R_START 0x0

#ifdef HALF_STEP
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[6][4] = {
  // R_START (00)
  {R_START_M,            R_CW_BEGIN,     R_CCW_BEGIN,  R_START},
  // R_CCW_BEGIN
  {R_START_M | DIR_CCW, R_START,        R_CCW_BEGIN,  R_START},
  // R_CW_BEGIN
  {R_START_M | DIR_CW,  R_CW_BEGIN,     R_START,      R_START},
  // R_START_M (11)
  {R_START_M,            R_CCW_BEGIN_M,  R_CW_BEGIN_M, R_START},
  // R_CW_BEGIN_M
  {R_START_M,            R_START_M,      R_CW_BEGIN_M, R_START | DIR_CW},
  // R_CCW_BEGIN_M
  {R_START_M,            R_CCW_BEGIN_M,  R_START_M,    R_START | DIR_CCW},
};
#else
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const unsigned char ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
#endif

byte rowPins[NUMROWS] = {21,20,19,18,15}; 
byte colPins[NUMCOLS] = {14,16,10,9,8}; 

Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS); 

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, 
  JOYSTICK_TYPE_JOYSTICK, 32, 0,
  false, false, false, false, false, false,
  false, false, false, false, false);

void setup() {
  Joystick.begin();
  rotary_init();}

void loop() { 

  CheckAllEncoders();

  CheckAllButtons();

}

void CheckAllButtons(void) {
      if (buttbx.getKeys())
    {
       for (int i=0; i<LIST_MAX; i++)   
        {
           if ( buttbx.key[i].stateChanged )   
            {
            switch (buttbx.key[i].kstate) {  
                    case PRESSED:
                    case HOLD:
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              break;
                    case RELEASED:
                    case IDLE:
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
            }
           }   
         }
     }
}


void rotary_init() {
  for (int i=0;i<NUMROTARIES;i++) {
    pinMode(rotaries[i].pin1, INPUT);
    pinMode(rotaries[i].pin2, INPUT);
    #ifdef ENABLE_PULLUPS
      digitalWrite(rotaries[i].pin1, HIGH);
      digitalWrite(rotaries[i].pin2, HIGH);
    #endif
  }
}


unsigned char rotary_process(int _i) {
   unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
  rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
  return (rotaries[_i].state & 0x30);
}

void CheckAllEncoders(void) {
  for (int i=0;i<NUMROTARIES;i++) {
    unsigned char result = rotary_process(i);
    if (result == DIR_CCW) {
      Joystick.setButton(rotaries[i].ccwchar, 1); delay(50); Joystick.setButton(rotaries[i].ccwchar, 0);
    };
    if (result == DIR_CW) {
      Joystick.setButton(rotaries[i].cwchar, 1); delay(50); Joystick.setButton(rotaries[i].cwchar, 0);
    };
  }`Gebruik code tags om code te formatteren voor het forum``

Gelieve uw code te formatteren.

ik heb het aangepast

1 Like

De roterende encoder heeft geen limiet voor CW- of CCW-richting. De potentiometer wel. U kunt de ADC-invoer van de potentiometer verdelen met behulp van het commando map(). Dit commando verdeelt bijvoorbeeld een 10-bits ADC-lezing (0 ... 1023) van een potentiometer die is aangesloten op 0 en 5vdc in ongeveer 10 secties:

int value = map(analogRead(A0), 0, 1023, 0, 10);

U moet de secties programmeren om te werken zoals de roterende encoder.

kunt u dat mischien even in mijn bestaande code veranderen en dan doorstuuren want ik ken nog maar heel weinig van coderen ik heb bij de handleiding de code gewoon gekopieerd en geplakt ik heb dus alles van de handleiding nagedaan behalven voor 2 encoders die normaal aangesloten zijn op pin 2 en 3 en de 2de encoder op pin tx en rx dus aleen die zijn nog beschikbaar ik heb de joystick als volgt dus aangesloten : de rechter aansluiting van bijde potentiometers op de gnd en de linker van de bijde op pin vcc (5volt) en dan de middelste van de 2 kan ik apart aansluiten op pin 2,3,tx,rx

Hoi Jarne.

Vragen aan iemand die je wil helpen, om dan even code voor jou aan te passen of te schrijven zijn niet helemaal de bedoeling.
Je kunt ze wel stellen, maar dan moet je er niet van opkijken dat daaraan geen gevolg wordt gegeven.
Het is de bedoeling dat men leert, en zo op een gegeven moment zelf dingen kan bedenken en oplossen.
Dat leren wordt natuurlijk niks als iedereen maar code gaat schrijven voor anderen die daar om vragen, en dan van de uiteindelijke oplossing geen idee heeft wat het doet en hoe het werkt.
Het staat wel een ieder vrij om aan jouw verzoek te voldoen, maar ik zou daar niet al teveel op hopen.

Voor wat betreft de joystick: die is analoog.
Dat betekent dat je analoge ingangen moet gebruiken.
Dat zijn pinnen 0 (RX), 1 (TX), 2 en 3 niet.
pinnen 0 en 1 zou ik alleen gebruiken als het echt niet anders kan, omdat daar de seriële communicatie over gaat, vandaar RX en TX.
Wat je dan dus zou kunnen overwegen, is om de pin verdeling anders te gaan maken, en daar dan dus ook je code op aan te passen.
Dat aanpassen is in jouw code erg eenvoudig dus dat mag het probleem niet worden.

Dit is de afbeelding waarin de originele fabrikant laat zien hoe de pinnen verdeeld zijn, wanneer je op de afbeelding klikt kom je op de betreffende site uit:

Je ziet dus dat je om dit te verwerken, wat van de groen gemarkeerde pinnen vrij moet maken

ja dat snap ik maar ik ken er zo enorm weinig van ik wil het wel leren maar geen idee waar te beginnen dit is ook mijn aller eerste project dat ik maak waarbij er geen voorgemaakte code voor is en ik dus een bestaande moet aanpassen en daarom bv een reactie die ik al eerder gehad heb met een kleine uitleg wat ik zou kunnen doen begrijp ik niet veel van bv waar dat ik dat moet plaatsen in de code of door wat ik dat moet vervangen

maar op het gene wat u zij ivm de analoge pins ik heb een kleine aanpasing kunnen doen door de 2encoders te verwisselenen met de pinnen die bedoeld waren voor de andere 2encoders die ik eerst wou vervangen dus nu heb ik pinen 7,6,5,4 beschikbaar en zzoals ik kon zien op de de foto is pin 6 en 4 wel analoge pinnen

maar ik zou dus totaal geen idee hebben hoe ik nu verder moet

Ik ken de libraries die je gebruikt niet, dus kan er niet heel veel over vertellen.
Maar het lijkt er op dat je in dit stukje toewijst welke pinnen er gebruikt worden voor de encoders:

rotariesdef rotaries[NUMROTARIES] {
  {0,1,24,25,0},
  {2,3,26,27,0},
  {4,5,28,29,0},
  {6,7,30,31,0},
};

Je hebt nu dus 0, 1 en 2,3 weer in gebruik genomen en 4,5 en 6,7 buiten gebruik gesteld zodat je 4 en 6 nu zou kunnen gebruiken als analoge ingangen.
4 gaat nu A6 heten, en 6 gaat nu A7 heten.

Ik mis schijnbaar wel wat, want je hebt veel meer pinnen toegewezen dan je beschikbaar hebt.
Pinnen 24 tot en met 31 staan in de tabel, maar bestaan niet voor jouw Arduino.
Pin 0 bestaat wel maar in dit geval denk ik dat dit de niet gebruikte schakelaar van de encoder betreft.

De tabel hierboven heeft 4 rijen van 5 waardes.
In jouw code staat dat er 4 rotaries (==encoders) zijn, dat komt dus overeen met de 4 rijen.
Ik denk dat jij er nu dus nog 2 over hebt, en dus moet je dat ook aanpassen.
Dan verander je deze regel:

#define NUMROTARIES 4

Naar:

#define NUMROTARIES 2

En vervolgens maak je de 2 vervallen encoder aansluitingen ongeldig.
Dat kun je doen door te toewijzing naar commentaarregels te veranderen:

rotariesdef rotaries[NUMROTARIES] {
  {0,1,24,25,0},
  {2,3,26,27,0},
 // {4,5,28,29,0},
 // {6,7,30,31,0},
};

Regels waar een // voor staat zijn commentaar regels, en wanneer je dat met een code doet schakel je dus dat stukje code uit.
Zo kun je een sketch aanpassen zonder iets kwijt te raken waardoor je het na het testen weer ongedaan kunt maken of repareren.

Ik raad je wel aan om nadat je dit aangepast hebt, ook deze aangepaste code te uploaden en te testen of alles nog werkt naar wens (met name de encoders die je nog wel hebt dus).

Wanneer je dat voor mekaar hebt, kun je eens gaan kijken of je joysticks ook werken naar verwachting.
In feite is de joystick niets anders dan 2 potmeters die je met 1 hendeltje bedient.
Daarom kun je een voorbeeld sketch in de IDE opzoeken, bijvoorbeeld AnalogInOutSerial.
Zorg er in dat voorbeeld voor dat je de juiste ingangen gebruikt, dus A6 en A7.
En wanneer je nog andere zaken aan je Pro Micro hebt aangesloten, zorg er dan ook voor dat het schrijven naar een analoge uitgang geen probleem vormt, bijvoorbeeld door dat helemaal niet te doen.
Wanneer je zo gezien hebt dat je joystick werkt, kun je gaan werken aan het combineren van je joystick en je buttonbox.

Daar laat ik het voor nu even bij, ik ga slapen.

De libraries die ik gebruik zijn : deze zip bestand

En deze include libary

En mischien dat dit beetje meer duidelijkheid geeft over hoe de aansluitingen zijn gemaakt

De 1ste en 2de encoders zijn dus nu aangesloten en de 3de en 4de niet

Borden met een 32U4 gebruiken de native USB van de 32U4 en niet the Rx and Tx pinnen. Dus is het veilig voor Jarne1922 om deze te gebruiken zolang Serial1 niet gebruikt wordt.

ik heb dit al eens geprobeert voor 1 potentiometer en geupload en dat werkte maar omdat ik er 2heb heb ik geprobeerd de code zowat verdubbeld voor 2potentiometers dit is wat ik zelf geprobeerd heb


```cpp
/*
 
*/

// These constants won't change. They're used to give names to the pins used:
const int analogInPin1 = A6;  // Analog input pin that the potentiometer is attached to
const int analogInPin2 = A7;
const int analogOutPin1 = 0;  // Analog output pin that the LED is attached to
const int analogOutPin2 = 0;

int sensorValue1 = 0;  // value read from the pot
int outputValue1 = 0;  // value output to the PWM (analog out)
int sensorValue2 = 0;  // value read from the pot
int outputValue2 = 0;

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  sensorValue1 = analogRead(analogInPin1);
  sensorValue2 = analogRead(analogInPin2);
  // map it to the range of the analog out:
  outputValue1 = map(sensorValue1, 0, 1023, 0, 255);
  outputValue2 = map(sensorValue2, 0, 1023, 0, 255);
  // change the analog out value:
  analogWrite(analogOutPin1, outputValue1);
  analogWrite(analogOutPin2, outputValue2);


  // print the results to the Serial Monitor:
  Serial.print("sensor = ");
  Serial.print(sensorValue1);
  Serial.print("\t output = ");
  Serial.println(outputValue1);

  Serial.print("sensor = ");
  Serial.print(sensorValue2);
  Serial.print("\t output = ");
  Serial.println(outputValue2);

  // wait 2 milliseconds before the next loop for the analog-to-digital
  // converter to settle after the last reading:
  delay(500);
}

 ik weet niet of dit wel de juiste manier is maar het werkte wel nu verandert er in de seriele monitor met de 2potentiometers iets dit zijn de resultaten bij het bewegen van de joystick

rust :
sensor = 499   output = 124
sensor = 512   output = 127

omhoog :
sensor = 500   output = 124
sensor = 11023   output = 255

omlaag :
sensor = 500   output = 124
sensor = 0   output = 0

links :
sensor = 0   output = 0
sensor = 500   output = 124

rechts :
sensor = 1023   output = 255
sensor = 500   output = 124

Ik ga die libraries niet bestuderen, want daar gaat mij teveel tijd in zitten.
Er zijn meerdere keypad libraries, maar ik begrijp wel goed hoe die werken dus denk niet dat ik daar in hoef te duiken.

Bij het schetsje van je encoders, zie ik bij elk van de 4 encoders 15 in de linker bovenhoek staan in zwart.
In de linker onderhoek zie ik telkens een uniek nummer staan in blauw.
Zijn die met de desbetreffende pin verbonden ?
Het lijkt er op dat dat de schakelaars van de encoder zijn (die actief wordt wanneer je op de knop drukt in plaats van er aan draait).
Dat klopt ook met hoe zo'n encoder er meestal uit ziet, met aan 1 kant 3 pinnen en aan diens overkant 2 pinnen.
Omdat ik die nummers ook zie staan bij de schakelaars en drukknoppen, vermoed ik dat die dus gepollt worden en daarmee een functie delen met de andere schakelaars.
Pollen is dus hoe de keypad werkt, je maakt een voor een 9,10 14 en 16 hoog, en kijkt dan of je op 15 iets ziet binnenkomen.
Wanneer dat zo is, dan vertelt de combinatie 14 en 15 dus dat de knop bij de encoder met RX en TX, is ingedrukt.
Wat ik dus niet weet is wat de waardes zoals 24,25,0 in rotariesdef doen.
Dat komt ook omdat ik dan niet ga uitzoeken nu.
Maar wanneer dit niet tot problemen leidt, gaan we er ook geen probleem van maken.

De analoge waardes zijn overeenkomstig met de positie van je joystick, dus OK.
De waarde 11023 klopt niet maar ik denk dat je daar per ongeluk 2 keer de 1 hebt getypt, en dan klopt dat wel (we tellen de nul altijd mee, en daarmee is 1023 de hoogste waarde die je kunt bereiken met de 10 beschikbare bits voor de analoge ingangen).
512 is dan het midden, maar je ziet aan de waarden die je uitgelezen hebt, dat daar wel wat variatie op zit, want meestal zie je daar de waarde 500.
Die wordt dan naar 8 bits vertaald zodat je dan 124 krijgt, terwijl dat eigenlijk 127 zou moeten zijn.
Je moet dus wanneer je dit gaat gebruiken, wel een hysteresis inbouwen zodat je uiteindelijk een niet al te nerveus signaal gaat krijgen.
Daar zijn verschillende oplossingen voor te bedenken, maar ik denk dat je eerst nog beter andere dingen in orde kunt maken.

Met andere woorden: dit ziet er goed uit, en je kunt nu gaan werken aan het combineren van deze 2 sketches.
Houd er rekening mee dat je het best begint met de globale defines zoals je nu ook al hebt in de sketches, en dat je maar 1 keer de functie setup() kunt hebben en 1 keer de functie loop().
Dus je kunt niet zomaar 2 sketches achter elkaar plakken.

Ja ik heb al wat geprobeerd met het te combineren maar krijg vaak foutmelingen bij het laatste dat ik getest heb is uit gebleken als ik test via de pc dat zodra ik knop 5 induw de joystick naar linksbiven word geplaatst en daar dan ook de hele tijd blijft

Linksboven en knop 5 zeggen mij niet heel veel want ik weet natuurlijk niet hoe jij de joystick vasthoud en de knoppen hebt ingebouwd.
Je kunt ook vertellen welke knop op jouw schets (een schets is een tekening, een sketch is Arduino code) hierboven het is, dus de vijfde drukknop in de tekening is de knop die op A1 en 8 aangesloten is.
Maar het betekent dat zowel A6 (4) als A7 (6) een waarde binnen krijgen, en dat kan dan zijn allebei 5 volt, allebei nul volt of de een 5 en de ander nul volt.
Dit kan wanneer je ergens nog niet hebt opgegeven dat een pin niet meer voor een encoder gebruikt moet worden, en / of A6 en A7 niet als analoge ingang, maar als digitale ingang zijn gedeclareerd (kan dus zijn dat je library dit doet).