Encoder and switch program issues

Hello everyone,

I'm 16, I'm french and I am making a switch panel to act as a keyboard with an arduino pro micro to flight simulator on PC an XBOX. I want to use 16 switches with an off/on position connected to an CD74HC4067 and 3 rotary encoders directly to digital pins. Each switch must write a character when it is turned on, but only once. And each switch must write a character when it is turned off, but only once. About encoders, they must write a character for each step CW and each step CCW. I am a beginner and I'm bad at coding. I am trying to do a prototype with an arduino uno board that send information but not as keyboard key but as serial.print.

I wrote this code on wokwi to try and it's not working very well someone can help me pls ?


 #include <light_CD74HC4067.h>
 
 #define inputCLK 4
 #define inputDT 5
 #define inputCLK1 6
 #define inputDT1 7
 #define inputCLK2 2
 #define inputDT2 3


CD74HC4067 mux(A5, A4, A3, A2);

 
 int currentStateCLK;
 int previousStateCLK; 
 int currentStateCLK1;
 int previousStateCLK1; 
 int currentStateCLK2;
 int previousStateCLK2; 
 int previous[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 const int signal_pin = A1;
 int current[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

 void setup() { 
   
     
   pinMode (signal_pin,INPUT_PULLUP);
   pinMode (inputCLK,INPUT);
   pinMode (inputDT,INPUT);
   pinMode (inputCLK1,INPUT);
   pinMode (inputDT1,INPUT);
   pinMode (inputCLK2,INPUT);
   pinMode (inputDT2,INPUT);
   
   
   
   // Setup Serial Monitor
   Serial.begin (9600);
   
   
   // Assign to previousStateCLK variable
   previousStateCLK = digitalRead(inputCLK);
   previousStateCLK1 = digitalRead(inputCLK1);
   previousStateCLK2 = digitalRead(inputCLK2);

 } 

 void loop() { 
  
  // Read the current state of inputCLK
   currentStateCLK = digitalRead(inputCLK);
    
   // If the previous and the current state of the inputCLK are different then a pulse has occured
   if (currentStateCLK != previousStateCLK){ 
       
     // If the inputDT state is different than the inputCLK state then 
     // the encoder is rotating counterclockwise
     if (digitalRead(inputDT) != currentStateCLK) { 
       Serial.println("up");
       
     } else {
       // Encoder is rotating clockwise
       Serial.println("down");
       
       
     }
     
   } 
   // Update previousStateCLK with the current state
   previousStateCLK = currentStateCLK;


   currentStateCLK1 = digitalRead(inputCLK1);
    
   // If the previous and the current state of the inputCLK1 are different then a pulse has occured
   if (currentStateCLK1 != previousStateCLK1){ 
       
     // If the inputDT1 state is different than the inputCLK1 state then 
     // the encoder is rotating counterclockwise
     if (digitalRead(inputDT1) != currentStateCLK1) { 
       Serial.println("up");
       
     } else {
       // Encoder is rotating clockwise
       Serial.println("down");
       
       
     }
     
   } 
   // Update previousStateCLK1 with the current state
   previousStateCLK1 = currentStateCLK1;


   currentStateCLK2 = digitalRead(inputCLK2);
    
   // If the previous and the current state of the inputCLK2 are different then a pulse has occured
   if (currentStateCLK2 != previousStateCLK2){ 
       
     // If the inputDT2 state is different than the inputCLK state then 
     // the encoder is rotating counterclockwise
     if (digitalRead(inputDT2) != currentStateCLK2) { 
       Serial.println("up");
       
     } else {
       // Encoder is rotating clockwise
       Serial.println("down");
       
       
     }
     
   } 
   // Update previousStateCLK2 with the current state
   previousStateCLK2 = currentStateCLK2;
 
    for (byte i = 0; i < 16; i++) {
	          mux.channel(i);
	          current[i]= digitalRead(signal_pin);                       // Read analog value
	          if(current[i]!= previous[i]){
              if(current[i]== 0){
                Serial.print(i);
                Serial.println(". on");
                
              } else {
                Serial.print(i);
                Serial.println(". off");
              }
              }
  previous[i]=current[i];
  delay(50);
  }

}

Welcome to the forum

What is wrong with the sketch as it stands ?

If you are going to extend the sketch to deal with 16 switches then I suggest that you use an array of structs for the switch data to avoid repeating code

The struct could contain the input pin number, previous state, character to send when turned on, character to send when turned off, and any other switch specific data

You need for the state of the input pins to remain stable so consider using INPUT_PULLUP in pinMode(), wire the switches to go LOW when turned on and test for LOW to determine that they have been turned on

Put the checks for switch change of state in a for loop and iterate through the array and the code size will be reduced considerably

Hello,

Thank you for the fast help, about the sketch, when I change the position of a switch sometimes I have a value sometimes nothing, also when I turn a encoder it hardly ever sends back information. It might do that because I'm running the sketch on a simulation on WOKWI ?
About the array of struct you are telling me about, I don't understand, I'm already using 16 switches with the multiplexer CD74HC4067


I doubt that the problem is with Wokwi because has a good reputation, but I know very little about it. Others here may be able to help

As to the 16 switches, looking further I see that you are using a for loop to read them from the multiplexer. Is that part of the code working OK ?

I think the part about the multiplexer is working okay, because it sends me the good values about the position of every switches when I'm using this code ( same code with modifications at the end ).
Thank you again for the help


 #include <light_CD74HC4067.h>
 
 #define inputCLK 4
 #define inputDT 5
 #define inputCLK1 6
 #define inputDT1 7
 #define inputCLK2 2
 #define inputDT2 3


CD74HC4067 mux(A5, A4, A3, A2);

 
 int currentStateCLK;
 int previousStateCLK; 
 int currentStateCLK1;
 int previousStateCLK1; 
 int currentStateCLK2;
 int previousStateCLK2; 
 int previous[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 const int signal_pin = A1;
 int current[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

 void setup() { 
   
     
   pinMode (signal_pin,INPUT_PULLUP);
   pinMode (inputCLK,INPUT);
   pinMode (inputDT,INPUT);
   pinMode (inputCLK1,INPUT);
   pinMode (inputDT1,INPUT);
   pinMode (inputCLK2,INPUT);
   pinMode (inputDT2,INPUT);
   
   
   
   // Setup Serial Monitor
   Serial.begin (115200);
   
   
   // Assign to previousStateCLK variable
   previousStateCLK = digitalRead(inputCLK);
   previousStateCLK1 = digitalRead(inputCLK1);
   previousStateCLK2 = digitalRead(inputCLK2);

 } 

 void loop() { 
  
  // Read the current state of inputCLK
   currentStateCLK = digitalRead(inputCLK);
    
   // If the previous and the current state of the inputCLK are different then a pulse has occured
   if (currentStateCLK != previousStateCLK){ 
       
     // If the inputDT state is different than the inputCLK state then 
     // the encoder is rotating counterclockwise
     if (digitalRead(inputDT) != currentStateCLK) { 
       Serial.println("up");
       
     } else {
       // Encoder is rotating clockwise
       Serial.println("down");
       
       
     }
     
   } 
   // Update previousStateCLK with the current state
   previousStateCLK = currentStateCLK;


   currentStateCLK1 = digitalRead(inputCLK1);
    
   // If the previous and the current state of the inputCLK1 are different then a pulse has occured
   if (currentStateCLK1 != previousStateCLK1){ 
       
     // If the inputDT1 state is different than the inputCLK1 state then 
     // the encoder is rotating counterclockwise
     if (digitalRead(inputDT1) != currentStateCLK1) { 
       Serial.println("up");
       
     } else {
       // Encoder is rotating clockwise
       Serial.println("down");
       
       
     }
     
   } 
   // Update previousStateCLK1 with the current state
   previousStateCLK1 = currentStateCLK1;


   currentStateCLK2 = digitalRead(inputCLK2);
    
   // If the previous and the current state of the inputCLK2 are different then a pulse has occured
   if (currentStateCLK2 != previousStateCLK2){ 
       
     // If the inputDT2 state is different than the inputCLK state then 
     // the encoder is rotating counterclockwise
     if (digitalRead(inputDT2) != currentStateCLK2) { 
       Serial.println("up");
       
     } else {
       // Encoder is rotating clockwise
       Serial.println("down");
       
       
     }
     
   } 
   // Update previousStateCLK2 with the current state
   previousStateCLK2 = currentStateCLK2;
 
    for (byte i = 0; i < 16; i++) {
	          mux.channel(i);
	          current[i]= digitalRead(signal_pin);                       // Read analog value
	          Serial.print(i);
            Serial.print(". ");
            Serial.println(current[i]);

  
  delay(500);
  }

}

are you sure encoder module have pull-up resistors? if not have then use INPUT_PULLUP constant

Thank you for the reply but finally I'm not going to use the multiplexer, it clutters the program too much, now I have less pin available but It's okay.

......
  static int previous =  0;
  for (byte i = 0; i < 16; i++) {
    mux.channel(i);
    bool current = digitalRead(signal_pin) ;                    // Read analog value
    if (current != bitRead(previous, i)) {
      if (current == 0)Keyboard.print(i+65);
      bitWrite(previous, i, current);
    }
  }
  delay(50);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.