Cockpitbuilders.com

sign up .

December 05, 2019, 09:48:27 pm

Login with username, password and session length
16 Guests, 2 Users
Members
Stats
  • Total Posts: 53571
  • Total Topics: 7170
  • Online Today: 162
  • Online Ever: 427
  • (December 01, 2019, 09:15:11 am)
Users Online
Users: 2
Guests: 16
Total: 18

COUNTDOWN TO WF2020


WORLDFLIGHT TEAM USA

Will Depart in...

Recent

Encoder with Arduino

Started by N606DL, December 02, 2019, 01:36:49 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

N606DL

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;
}

}

}

_alioth_


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.





N606DL

Hello, I am using Teensy 2.0++. So I have no problems with it turning, just with the acceleration.

_alioth_

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.

Trevor Hale

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
Trevor Hale

Owner
http://www.cockpitbuilders.com

Director of Operations
Worldflight Team USA
http://www.worldflightusa.com

VATSIM:

Fess_ter_Geek

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

N606DL

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.

_alioth_

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.

N606DL

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.

_alioth_

December 04, 2019, 01:45:54 am #9 Last Edit: December 04, 2019, 02:03:11 am by _alioth_
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:



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.

N606DL

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!

_alioth_


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.



Like the Website ?
Support Cockpitbuilders.com and Click Below to Donate