Hello,
Im looking for a hand to get a CTS-288 Encoder working properly.
My code guy says he cant find "the timing diagram" and the end result is the Encoders missing clicks and in general not working like how i know them to with more commercial grade boards.
here's the code and here's a link to the Encoders,
https://www.digikey.ca/products/en?keywords=288T232R161A2
PS there is the original "alps funky switch" also installed on this, so there's a reason for the multiple encoder stuff.
// Version 2.1 - Fixed PUSH IN problem when pushing the button forward, reverse, left or right
// Version 2.2 - Fixed Encoder Debounce time from 1ms to 5ms (datasheet of the encoder states that maximum debounce time is 4ms)
// Version 2.3 - Test with interrupts
// Version 2.4 - Test with encoder library
// Version 2.5 - Added two more encoders
#include <Bounce.h>
#include <Encoder.h>
//#include <avr/io.h>
//#include <avr/interrupt.h>
//////////////////////////////////////
// Added by TadyTheFish
// This was added so if you want to change a pin that a button is connected to, you do it here and don't have to search the code to make changes
int PinButton0 = 2; // Button0 is connected to pin 2 on Teensy (it is Mandatory to connect the PUSH IN button to this pin or it will not work, unless you change the bottom of the program)
int PinButton1 = 0; // Use this and the next three pins for direction buttons (forward,backward,left and right)
int PinButton2 = 1;
int PinButton3 = 3;
int PinButton4 = 4;
int PinButton7 = 7; // Use this one as you like
int PinButton8 = 8; // Use this one as you like
int PinButton9 = 9; // Use this one as you like
int PinButton12 = 12;
int PinButton16 = 16;
int PinButton17 = 17;
int PinButton18 = 18;
int PinButton19 = 19;
int PinButton20 = 20;
int PinButton21 = 21;
int PinButton22 = 22;
int PinButton23 = 23;
int PinButton5 = 5; // 5 These are encoder inputs
int PinButton6 = 6; // 6
int PinButton10 = 10;
int PinButton11 = 11;
int PinButton14 = 14;
int PinButton15 = 15;
//Current connection:
/* (Windows) (teensy pin)
* Button1 = pin 0
* Button2 = pin 1
* Button3 = pin 2
* Button4 = pin 3
* Button5 = pin 4
* Button8 = pin 7
* Button9 = pin 8
*
* Encoder:
* Button11 pulsing if turning in one direction
* Button12 pulsing if turning in the other direction
*/
//////////////////////////////////////
// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(PinButton0, 10);
Bounce button1 = Bounce(PinButton1, 10); // 10 = 10 ms debounce time
Bounce button2 = Bounce(PinButton2, 10); // which is appropriate for
Bounce button3 = Bounce(PinButton3, 10); // most mechanical pushbuttons
Bounce button4 = Bounce(PinButton4, 10);
Bounce button7 = Bounce(PinButton7, 10);
Bounce button8 = Bounce(PinButton8, 10);
Bounce button9 = Bounce(PinButton9, 10);
Bounce button12 = Bounce(PinButton12, 10);
Bounce button16 = Bounce(PinButton16, 10);
Bounce button17 = Bounce(PinButton17, 10);
Bounce button18 = Bounce(PinButton18, 10);
Bounce button19 = Bounce(PinButton19, 10);
Bounce button20 = Bounce(PinButton20, 10);
Bounce button21 = Bounce(PinButton21, 10);
Bounce button22 = Bounce(PinButton22, 10);
Bounce button23 = Bounce(PinButton23, 10);
//////////////////////////////////////
// Added by TadyTheFish
//Bounce button5 = Bounce(PinButton5, 5); // Debounce time increased from 1ms to 5ms.
//Bounce button6 = Bounce(PinButton6, 5); //
//Bounce button10 = Bounce(PinButton10, 1); // Debounce time increased from 1ms to 5ms.
//Bounce button11 = Bounce(PinButton11, 1); //
//Bounce button15 = Bounce(PinButton15, 1); // Debounce time increased from 1ms to 5ms.
//Bounce button14 = Bounce(PinButton14, 1); //
long ResetButtonToZeroA1; // This is used to store at what time the "1" bit was sent to the PC. When you turn an encoder you have 50/50 chance that the input will stay "ON". We use this time to compare so we can reset the bit
long ResetButtonToZeroB1; // to "OFF" after some time if the button was not toggled
bool ResetOnceA1; // When we reset the button to "OFF", this is used to ensure that the bit is reset only once
bool ResetOnceB1;
long ResetButtonToZeroA2; // This is used to store at what time the "1" bit was sent to the PC. When you turn an encoder you have 50/50 chance that the input will stay "ON". We use this time to compare so we can reset the bit
long ResetButtonToZeroB2; // to "OFF" after some time if the button was not toggled
bool ResetOnceA2; // When we reset the button to "OFF", this is used to ensure that the bit is reset only once
bool ResetOnceB2;
long ResetButtonToZeroA3; // This is used to store at what time the "1" bit was sent to the PC. When you turn an encoder you have 50/50 chance that the input will stay "ON". We use this time to compare so we can reset the bit
long ResetButtonToZeroB3; // to "OFF" after some time if the button was not toggled
bool ResetOnceA3; // When we reset the button to "OFF", this is used to ensure that the bit is reset only once
bool ResetOnceB3;
long oldPosition;
long oldPosition2;
long oldPosition3;
//long newPosition;
long oldMillisPosition;
long oldMillisPosition2;
long oldMillisPosition3;
long LoopTime;
Encoder myEnc(PinButton5, PinButton6);
Encoder myEnc2(PinButton10, PinButton11);
Encoder myEnc3(PinButton14, PinButton15);
//////////////////////////////////////
void setup() {
pinMode(PinButton0, INPUT_PULLUP);
pinMode(PinButton1, INPUT_PULLUP);
pinMode(PinButton2, INPUT_PULLUP);
pinMode(PinButton3, INPUT_PULLUP);
pinMode(PinButton4, INPUT_PULLUP);
pinMode(PinButton7, INPUT_PULLUP);
pinMode(PinButton8, INPUT_PULLUP);
pinMode(PinButton9, INPUT_PULLUP);
pinMode(PinButton12, INPUT_PULLUP);
pinMode(PinButton16, INPUT_PULLUP);
pinMode(PinButton17, INPUT_PULLUP);
pinMode(PinButton18, INPUT_PULLUP);
pinMode(PinButton19, INPUT_PULLUP);
pinMode(PinButton20, INPUT_PULLUP);
pinMode(PinButton21, INPUT_PULLUP);
pinMode(PinButton22, INPUT_PULLUP);
pinMode(PinButton23, INPUT_PULLUP);
//////////////////////////////////////
// Added by TadyTheFish
//pinMode(PinButton5, INPUT_PULLUP); // The encoder is connected the same way as a button
//pinMode(PinButton6, INPUT_PULLUP);
//pinMode(PinButton10, INPUT_PULLUP);
//pinMode(PinButton11, INPUT_PULLUP);
//pinMode(PinButton15, INPUT_PULLUP);
//pinMode(PinButton14, INPUT_PULLUP);
//////////////////////////////////////
//pinMode(32,INPUT_PULLUP);
//pinMode(31,INPUT_PULLUP);
//attachInterrupt(5, Count, FALLING);
//myEnc.write(512); // try to init in middle
//Joystick.button(4, 1);
}
void loop() {
//delay(30);
//LoopTime = micros();
long newPosition = myEnc.read();
long newPosition2 = myEnc2.read();
long newPosition3 = myEnc3.read();
//long newPosition = myEnc.read()/2;
//Serial.println(newPosition);
// ------------- Encoder 1 ------------- //
if (newPosition > oldPosition ) {
oldPosition = newPosition;
Joystick.button(12, 0);
Joystick.button(11, 1);
oldMillisPosition = millis();
}
if (newPosition < oldPosition ) {
oldPosition = newPosition;
Joystick.button(11, 0);
Joystick.button(12, 1);
oldMillisPosition = millis();
}
if(newPosition == oldPosition){
if(millis()-oldMillisPosition > 30){
oldMillisPosition = millis();
Joystick.button(11, 0);
Joystick.button(12, 0);
}
}
// ------------- Encoder 2 ------------- //
if (newPosition2 > oldPosition2 ) {
oldPosition2 = newPosition2;
Joystick.button(7, 0);
Joystick.button(6, 1);
oldMillisPosition2 = millis();
}
if (newPosition2 < oldPosition2 ) {
oldPosition2 = newPosition2;
Joystick.button(6, 0);
Joystick.button(7, 1);
oldMillisPosition2 = millis();
}
if(newPosition2 == oldPosition2){
if(millis()-oldMillisPosition2 > 30){
oldMillisPosition2 = millis();
Joystick.button(6, 0);
Joystick.button(7, 0);
}
}
// ------------- Encoder 3 ------------- //
if (newPosition3 > oldPosition3 ) {
oldPosition3 = newPosition3;
Joystick.button(15, 0);
Joystick.button(14, 1);
oldMillisPosition3 = millis();
}
if (newPosition3 < oldPosition3 ) {
oldPosition3 = newPosition3;
Joystick.button(14, 0);
Joystick.button(15, 1);
oldMillisPosition3 = millis();
}
if(newPosition3 == oldPosition3){
if(millis()-oldMillisPosition3 > 30){
oldMillisPosition3 = millis();
Joystick.button(14, 0);
Joystick.button(15, 0);
}
}
// Update all the buttons. There should not be any long
// delays in loop(), so this runs repetitively at a rate
// faster than the buttons could be pressed and released.
button0.update();
button1.update();
button2.update();
button3.update();
button4.update();
button7.update();
button8.update();
button9.update();
button12.update();
button16.update();
button17.update();
button18.update();
button19.update();
button20.update();
button21.update();
button22.update();
button23.update();
//////////////////////////////////////
// Added by TadyTheFish
//button5.update(); // The encoder is connected the same way as a button
//button6.update();
//////////////////////////////////////
// Check each button for "falling" edge.
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button0.fallingEdge() && digitalRead(PinButton1) == HIGH && digitalRead(PinButton2) == HIGH && digitalRead(PinButton3) == HIGH && digitalRead(PinButton4) == HIGH ) { // This prevents an accidental PUSH IN to be activated if we are pushing the button Forward, Reverse, Left or Right
Joystick.button(1, 1);
}
if (button1.fallingEdge()) {
Joystick.button(1, 0); // If pushed IN button is active, deactivate it
Joystick.button(2, 1);
}
if (button2.fallingEdge()) {
Joystick.button(1, 0); // If pushed IN button is active, deactivate it
Joystick.button(3, 1);
}
if (button3.fallingEdge()) {
Joystick.button(1, 0); // If pushed IN button is active, deactivate it
Joystick.button(4, 1);
}
if (button4.fallingEdge()) {
Joystick.button(1, 0); // If pushed IN button is active, deactivate it
Joystick.button(5, 1);
}
if (button7.fallingEdge()) {
Joystick.button(8, 1);
}
if (button8.fallingEdge()) {
Joystick.button(9, 1);
}
if (button9.fallingEdge()) {
Joystick.button(10, 1);
}
////////
if (button12.fallingEdge()) {
Joystick.button(13, 1);
}
if (button16.fallingEdge()) {
Joystick.button(17, 1);
}
if (button17.fallingEdge()) {
Joystick.button(18, 1);
}
if (button18.fallingEdge()) {
Joystick.button(19, 1);
}
if (button19.fallingEdge()) {
Joystick.button(20, 1);
}
if (button20.fallingEdge()) {
Joystick.button(21, 1);
}
if (button21.fallingEdge()) {
Joystick.button(22, 1);
}
if (button22.fallingEdge()) {
Joystick.button(23, 1);
}
if (button23.fallingEdge()) {
Joystick.button(24, 1);
}
// Check each button for "rising" edge
// Update the Joystick buttons only upon changes.
// rising = low (pressed - button connects pin to ground)
// to high (not pressed - voltage from pullup resistor)
if (button0.risingEdge()) {
Joystick.button(1, 0);
}
if (button1.risingEdge()) {
Joystick.button(2, 0);
}
if (button2.risingEdge()) {
Joystick.button(3, 0);
}
if (button3.risingEdge()) {
Joystick.button(4, 0);
}
if (button4.risingEdge()) {
Joystick.button(5, 0);
}
if (button7.risingEdge()) {
Joystick.button(8, 0);
}
if (button8.risingEdge()) {
Joystick.button(9, 0);
}
if (button9.risingEdge()) {
Joystick.button(10, 0);
}
///////
if (button12.risingEdge()) {
Joystick.button(13, 0);
}
if (button16.risingEdge()) {
Joystick.button(17, 0);
}
if (button17.risingEdge()) {
Joystick.button(18, 0);
}
if (button18.risingEdge()) {
Joystick.button(19, 0);
}
if (button19.risingEdge()) {
Joystick.button(20, 0);
}
if (button20.risingEdge()) {
Joystick.button(21, 0);
}
if (button21.risingEdge()) {
Joystick.button(22, 0);
}
if (button22.risingEdge()) {
Joystick.button(23, 0);
}
if (button23.risingEdge()) {
Joystick.button(24, 0);
}
//////////////////////////////////////
// Added by TadyTheFish
/*if (button5.risingEdge()) { // This works in the opposite way that the upper code does. It turns off the button. If this was removed the button would be constantly ON
if(digitalRead(PinButton6) == LOW){
Joystick.button(11, 0);
}
}
if (button6.risingEdge()) { // This works in the opposite way that the upper code does. It turns off the button. If this was removed the button would be constantly ON
if(digitalRead(PinButton5) == LOW){
Joystick.button(12, 0);
}
}
if(millis() - ResetButtonToZeroA1 > 100 && ResetOnceA1 == false){ // This rutine is called when (current time) - (last time the button was active) is more than 100ms, and reset is flase
Joystick.button(11, 0);
ResetOnceA1 = true; // Here we set the reset to TRUE so when the code loops again it does not send another "0" to the PC. This prevents false triggers
}
if(millis() - ResetButtonToZeroB1 > 100 && ResetOnceB1 == false){
Joystick.button(12, 0);
ResetOnceB1 = true;
}
//////////////////////////////////
*/
///////////////////////////////////
/*if (button15.risingEdge()) { // This works in the opposite way that the upper code does. It turns off the button. If this was removed the button would be constantly ON
if(digitalRead(PinButton14) == LOW){
Joystick.button(14, 0);
}
}
if (button14.risingEdge()) { // This works in the opposite way that the upper code does. It turns off the button. If this was removed the button would be constantly ON
if(digitalRead(PinButton15) == LOW){
Joystick.button(15, 0);
}
}
if(millis() - ResetButtonToZeroA3 > 100 && ResetOnceA3 == false){ // This rutine is called when (current time) - (last time the button was active) is more than 100ms, and reset is flase
Joystick.button(14, 0);
ResetOnceA3 = true; // Here we set the reset to TRUE so when the code loops again it does not send another "0" to the PC. This prevents false triggers
}
if(millis() - ResetButtonToZeroB3 > 100 && ResetOnceB3 == false){
Joystick.button(15, 0);
ResetOnceB3 = true;
}*/
//////////////////////////////////////
//Serial.println(micros()- LoopTime);
}