Cockpitbuilders.com

Main => Builders Discussions => Topic started by: N606DL on December 02, 2019, 01:36:49 AM

Title: Encoder with Arduino
Post by: N606DL on December 02, 2019, 01:36:49 AM
Hello, I am trying to get this program to work using Clickinterval, so when I spin the encoder faster it changes the dataref in X Plane faster.
I can get the encoder to work perfectly but I can't get it to spin faster when I turn the encoder faster. Turning it slow is fine. Here is my program if anyone who is familiar with this help me out?



#include <Encoder.h>

Encoder IasEncoder = Encoder(1,2);

int countIas = 0;
int IasEncoder_prev = 0;
int IasEncoderVal = 0;

FlightSimCommand IasUP;
FlightSimCommand IasDN;


elapsedMillis IASEncoderClickInterval = 0;




void setup() {
// put your setup code here, to run once:

pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);


IasUP = XPlaneRef("1-sim/comm/AP/spdUP");
IasDN = XPlaneRef("1-sim/comm/AP/spdDN");




}

void loop() {

FlightSim.update();





long IasEnc = IasEncoder.read();
if (IasEnc != IasEncoder_prev){
IasEncoderVal = (IasEnc - IasEncoder_prev);
if(IasEncoderVal == -1){
countIas++;
}
if(IasEncoderVal ==1){
countIas--;
}
IasEncoder_prev = IasEnc;

if(countIas==2){
IasDN.once();
countIas = 0;
}

if(countIas ==-2){
IasUP.once();
countIas = 0;
}

if(IASEncoderClickInterval > 30){
IasEncoderVal = IasEnc * .25;
}else{
IasEncoderVal = IasEnc * 5.0;
IASEncoderClickInterval = 0;
}

}

}
Title: Re: Encoder with Arduino
Post by: _alioth_ on December 02, 2019, 02:15:16 AM

Which Arduino are you using?
For good performance, you should connect encoders to pins with hardware interrupt capacities. Hardware interrupt will make you don't loose any signal change in pins.

You are using pins 1 and 2, and Arduino UNO and MEGA don't have hardware interrupt in pin 1.

If using UNO, you should use pins 2 and 3
If Mega, then use  2,3,18,19,20 or 21.  (in Mega you can use until 3 encoders, because it has 6 hardware interrupt pins).

Arduino DUE, or Teensy 3-4, have hadrware interrupt in all pins. This is the main reason I am using DUEs. I need hardware interrupts in all pins not only to read encoders well, but most importand, to read pwm signals with precision.

I don't see any other problem in your code. I have not tested the acceleration function based in click interval you are using, but it seems ok in first sight.




Title: Re: Encoder with Arduino
Post by: N606DL on December 02, 2019, 02:59:12 AM
Hello, I am using Teensy 2.0++. So I have no problems with it turning, just with the acceleration.
Title: Re: Encoder with Arduino
Post by: _alioth_ on December 02, 2019, 01:10:34 PM
I have wrote a teensy encoder test.
It is the first time I use a teensy. I had a 3.5 in a box :)

I can confirm that this sketch works:

Quote from: undefined#include <Encoder.h>

Encoder knob(0, 1);

void setup() {
  Serial.begin(9600);
}

long positionValue  = -999;

unsigned long oldMillis = 0;
int limitRange = 30;

void loop() {
  long newValue;
  newValue = knob.read();

  if (newValue != positionValue ) {

    if (millis() - oldMillis > limitRange) {
      oldMillis = millis();
      if (newValue < positionValue) {
        Serial.println ("_________right______");
      } else {
        Serial.println ("_____left___________");
      }
    } else {
      if (newValue < positionValue) {
        Serial.println ("_______________RIGHT");
      } else {
        Serial.println ("LEFT________________");
      }
    }
    positionValue = newValue;
  }
}


Here it is a vid showing the result:



I don't have xplane so I can't use the xplane library.
But I think it is simple to add the lines needed.

Arturo.
Title: Re: Encoder with Arduino
Post by: Trevor Hale on December 02, 2019, 04:21:05 PM
I have proposed your question to another member that doesn't get on the forum very often, he has said there is more of a limitation with the speed at which Xplane accepts the data than with Prepar3D however the Arduino should be able to count the pulses per (25ms) or so, and you could change your code to allow it to collect the data and based on the number of pulses in a very short window to determine if it sends a 1 to increase or decrease, verses sending a 10 to increase or decrease the value.

I will try to get him here to post a portion of his code, which is better than what you have but still may not be as fast as you want.

Trev
Title: Re: Encoder with Arduino
Post by: Fess_ter_Geek on December 03, 2019, 04:37:37 AM
Trev mentioned this to me last night as I have some code for Xplane, but most of my stuff has been centered on P3D.
I was having trouble with my acceleration code with Xplane but I solved it last night in a bout of insomnia.
My code differs greatly from yours, I do not use an encoder library and I communicate with Xplane thru a pyscript and Python plugin. I haven't put in the time to write my own stand alone plugin yet. But I'm getting closer.

Anyhoo, I measure or "clock" the time between clicks on the encoder and then depending on the speed I send a number to move the HDG bug or OBS, up or down.
I dont use the command ref to move the bugs up or down. Instead I read the dataref, add or subtract to it, then write the dataref. By adding 1 for slow then adding 1, 3 and 5 for speeds clocked between 250ms to less than 100ms it has made for a beautiful effect.

I wont be able to post the code for a few days.

~Fess
Title: Re: Encoder with Arduino
Post by: N606DL on December 03, 2019, 05:54:56 AM
Thanks guys, Arturo I will incorporate my Xplane data in your sketch and try it out.
Fess looking forward to seeing your script, even though I don't use Python, still interested in seeing what you come up with. Thanks a million guys.
Title: Re: Encoder with Arduino
Post by: _alioth_ on December 03, 2019, 12:01:34 PM
Ok. I have installed XPlane demo just to test with teensy.
This code works. You can get the idea:

Quote from: undefined#include <Encoder.h>

Encoder knob(0, 1);
FlightSimInteger courseHSI;


long positionValue  = -999;
unsigned long oldMillis = 0;
int limitRange = 40;
long newValue = 0;

void setup() {
  courseHSI = XPlaneRef("sim/cockpit2/radios/actuators/hsi_obs_deg_mag_pilot");
  Serial.begin(9600);
}

void loop() {

  FlightSim.update();
 
  newValue = knob.read();
  if (newValue != positionValue ) {
    if (millis() - oldMillis > limitRange) {
     
      if (newValue < positionValue) {
        //Serial.println ("_________right______");
        courseHSI = courseHSI + 1;
      } else {
        //Serial.println ("_____left___________");
        courseHSI = courseHSI - 1;
      }
    } else {
      if (newValue < positionValue) {
        //Serial.println ("_______________RIGHT");
        courseHSI = courseHSI + 5;
      } else {
        //Serial.println ("LEFT________________");
        courseHSI = courseHSI - 5;
      }
    }
    oldMillis = millis();
    positionValue = newValue;
  }

  if (courseHSI >360) courseHSI = courseHSI - 360;
  if (courseHSI <0) courseHSI = courseHSI + 360;
 
}



Arturo.
Title: Re: Encoder with Arduino
Post by: N606DL on December 04, 2019, 01:35:09 AM
Hey Arturo, I tried your sketch and it works really good, except when I turn it to the left
it kinda sticks, like the encoder is bouncy. Its a new encoder cts288 from Leo Bodnar. But other than that I really like the speed its spot on. Now if I can just fix turning the opposite way.
Title: Re: Encoder with Arduino
Post by: _alioth_ on December 04, 2019, 01:45:54 AM
Quote from: N606DL on December 04, 2019, 01:35:09 AMlike the encoder is bouncy.

Depending on the encoder, you should debounce it by hardware/software.

I have used the cts288 in the example video too!!
And I can confirm to you that bouncing happened to me too if not using any debouncing method.
It can't be seen in the video, but I have debounced mine with hardware, like this pic:

(https://ic.pics.livejournal.com/elchupanibrei/30212434/38097/38097_original.jpg)

Just two ceramic capacitors 0.1 uF (104 code) do the job perfect.
It can be done with software, but the hardware mode is always better.
You don't need pullups resistors because the encoder library uses the in built pull up resistors in teensy, which I think they are about 33kohm.
And 33kohm, 3.3v, 2.0v to high level logic and 0.1uf capacitors take about 3ms debounce, which is fine to rotary encoders.

Arturo.
Title: Re: Encoder with Arduino
Post by: N606DL on December 04, 2019, 02:19:07 AM
AHH ok that makes alot of sense then. Also I am going to switch to a teensy 3.2 which is faster than the 2.0++. Thanks again!
Title: Re: Encoder with Arduino
Post by: _alioth_ on December 04, 2019, 02:33:16 AM

Just to test right now, you can simply add a  delay(5);   in the main loop and it probably will do the job.
It is just a quick method to test, not the correct way to do it.

And if you want to go with software debouncing route, there are good debouncing arduino libraries.