Found a possible bug in TeensyLC

raflyer

Well-known member
When using AccelStepper my TeensyLC will not communicate with x-plane 10. Remove it and it works perfect. In the Teensy com window inside x-plane it shows the Teensy being connected and disconnected ok. Just no other communication. If I flash it with any of the FlightSimControls examples it works fine. Below is the code I tried with AccelStepper,

Code:
#include <AccelStepper.h>

AccelStepper stepper1(1, 1, 0);

FlightSimFloat adiroll;
const int homeButton = 7;
const int ledPin = 13;
byte hBval;
float cur_pos;

void setup() {
  Serial.begin(9600);
  stepper1.setMaxSpeed(100); //nice and slow for testing
  stepper1.moveTo(-300);
  stepper1.setAcceleration(70);
  pinMode(homeButton, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  stepperHome(); //runs routine to home motor
  adiroll = XPlaneRef("sim/cockpit2/gauges/indicators/pitch_electric_deg_pilot");
}
void loop() {
  FlightSim.update();
  cur_pos = adiroll * 3.33;
  stepper1.moveTo(cur_pos);
  stepper1.runToPosition();
  Serial.print("Test position");
  Serial.println(cur_pos);
}

void stepperHome() { //this routine should run the motor
  hBval = digitalRead(homeButton);
  while (hBval == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper1.moveTo(-400);
    stepper1.run();
    digitalWrite(ledPin, LOW); //indicates it's doing something
    hBval = digitalRead(homeButton);
  }
  digitalWrite(ledPin, HIGH); //indicates it's doing something
  stepper1.setCurrentPosition(0); //should set motor position to zero and go back to main routine
}
 
One thought might be whether you have enough power for the AccellStepper.

If you are attaching USB and using the VIN pin to draw 5v power, on the 3.0/3.1 you can draw about 500mA of power, while according to the schematic, you can draw about 350mA from the LC.

If you are drawing power from the 3.3v pin, the LC datasheet says you can draw 120mA total (including what the LC needs), while the Teensy 3.1's limit is 185mA.
 
I am using a Pololu A4988 and it is powered by a separate PSU. Here is the test program that works great testing the stepper.
Code:
#include <AccelStepper.h>

AccelStepper stepper1(1, 1, 0);

const int homeButton = 7;
const int ledPin = 13;
byte hBval;


void setup(){
  stepper1.setMaxSpeed(100); //nice and slow for testing
  stepper1.setAcceleration(70);
  pinMode(homeButton, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  stepperHome(); //runs routine to home motor
}
void loop(){
  stepper1.moveTo(100); // random position to end for testing
  stepper1.runToPosition();
  delay(1000);
  stepper1.moveTo(0);
  stepper1.runToPosition();
  delay(2000);
  stepper1.moveTo(-100); // random position to end for testing
  stepper1.runToPosition();
  delay(1000);
}

void stepperHome(){ //this routine should run the motor
  hBval = digitalRead(homeButton);
  while (hBval == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper1.moveTo(-400);
    stepper1.run();
    digitalWrite(ledPin, HIGH); //indicates it's doing something
    hBval = digitalRead(homeButton);
  }
  digitalWrite(ledPin, HIGH); //indicates it's doing something
  stepper1.setCurrentPosition(0); //should set motor position to zero and go back to main routine
}
 
I've put this on my list of issues to investigate. Realistically, it might be a couple weeks until I can really look into this.
 
Ok, did some more testing this evening, If I comment out the stepperHome(); in Setup then it works in x-plane. Why does in the 2nd example, find home position then start the Loop ok but in the first example the Loop never starts. It stays in the stepperhome function. I am so confused.

I don't think it is a bug so i'll xfer the question to software support/questions. Sorry.
 
Last edited:
Paul,
I added some debug code, Serial monitor shows Done with StepperHome then Loop started just as it should but no communication with x-plane. If I comment out the StepperHome() function then it communicates and works perfect with X-plane. So i can now confirm it goes to Loop so I hope that helps you?
Rob


Code:
#include <AccelStepper.h>

AccelStepper stepper1(1, 3, 2);

FlightSimFloat adiroll;
const int homeButton = 7;
const int ledPin = 13;
byte hBval;
float cur_pos;

void setup() {
  Serial.begin(9600);
  stepper1.setMaxSpeed(1000); //nice and slow for testing
  stepper1.setAcceleration(900);
  pinMode(homeButton, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  stepperHome(); //runs routine to home motor
  adiroll = XPlaneRef("sim/cockpit2/gauges/indicators/roll_electric_deg_pilot");
}
void loop() {
  Serial.print("loop has started");
  FlightSim.update();
  cur_pos = adiroll * -6.67;
  stepper1.moveTo(cur_pos);
  stepper1.runToPosition();
}

void stepperHome() { //this routine should run the motor
  hBval = digitalRead(homeButton);
  while (hBval == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper1.moveTo(-800);
    stepper1.run();
    digitalWrite(ledPin, HIGH); //indicates it's doing something
    hBval = digitalRead(homeButton);
    Serial.print("HomeButton is");
    Serial.println(hBval);
  }
  digitalWrite(ledPin, LOW); //indicates it's doing something
  stepper1.setCurrentPosition(0); //should set motor position to zero and go back to main routine
  Serial.print("Done with stepper Home");
}
 
Last edited:
Rob,

you're calling runToPosition()] in your loop() function. Don't do this:

void AccelStepper::runToPosition ()
Moves the motor (with acceleration/deceleration) to the target position and blocks until it is at position. Dont use this in event loops, since it blocks.

runToPosition() waits for the stepper to reach the final position, so FlightSim.update() doesn't get called. Just use run() and it'll work:

boolean AccelStepper::run ()
Poll the motor and step it if a step is due, implementing accelerations and decelerations to acheive the target position. You must call this as frequently as possible, but at least once per minimum step time interval, preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due, based on the current speed and the time since the last step.

Cheers

Jorg
 
Back
Top