rwaldron / johnny-five

JavaScript Robotics and IoT programming framework, developed at Bocoup.
http://johnny-five.io
Other
13.26k stars 1.76k forks source link

ESC #530

Closed carldanley closed 9 years ago

carldanley commented 9 years ago

I'm trying to use this ESC: https://traxxas.com/products/parts/otherparts/xl5waterproof. I have jumper wires that run from the ground and input on the ESC to the arduino. The arduino is being powered by my macbook (over USB) and the ESC is being powered properly with the RC car's battery.

I'm running this code:

const five = require('johnny-five');
const board = new five.Board();

board.on('ready', function() {

  // ENGINE
  const motorServo = new five.Servo({
    pin: 10
  });

  this.repl.inject({
    s: motorServo
  });

});

From the repl, I can run s.to(90) to stop the motor. I can increase the speed from 90 to 160 where 160 is the maximum speed (35mph) for the RC car.

The RC car is supposed to be able to reverse and I've found that no matter what values I use, I cannot switch from forward to reverse and back. I've gotten both directions to work independently but I do not know what I did to get them to work.

Any suggestions or ideas as to what I need to be doing for this to work properly?

carldanley commented 9 years ago

Video of it in action: https://dl.dropboxusercontent.com/u/36532100/IMG_0743.MOV.

dtex commented 9 years ago

There is an ESC class though what you have here should work. ESC method names might just feel better. Also we should expand the ESC syntax to support ESC's with reverse, then it would really be ideal.

This model of ESC has multiple modes (Sport, Competition). There is no reverse in competition mode. Make sure you are in sport.

Since 90 is stop I would expect 0 to be full on reverse.

How did you arrive at the 160 value? Perhaps 20 is the right value for reverse? (if you are still using Servo).

carldanley commented 9 years ago

I tried using the ESC class and it works well but still the same results (just different numbers). I can get by with this for now :)

I tried values less than 90 and they do not work for reverse. I'm not sure what exactly the problem is.

I arrived at 160 because after 160, the motor stops and resets.

dtex commented 9 years ago

And you checked to make sure the ESC is in "Sport" mode? Sorry if you did, just eliminating likely suspects.

carldanley commented 9 years ago

No worries - I need to figure out how to put it in "sport" mode tbh. Looking now.

rwaldron commented 9 years ago

The existing ESC class has no notion of forward/reverse, just "speed" and direction is handled in the connection between the circuit and the brushless dc motor. That's not to say that it can't have that, just that it doesn't yet have support.

(I hit the button too soon)

If the device is just PWM based and has a sub range for one direction and a sub range for another, it should just work, but it would be nice to have API for such things.

reconbot commented 9 years ago

I'm wondering if the 1600Hz this device operates at is an issue. I've recently learned that Servos work on 50Hz and the PWM out put of an arduino is 500Hz. It could be reading the width as double what you expect or .. other weirdness.

nebrius commented 9 years ago

Are we not setting a clock divider on the Arduino's PWM? I know I had to do that with the RPi to get it to drive a servo (and I had to use an o-scope to tighten the timings properly, ugh).

reconbot commented 9 years ago

You can override the timings for servos if you burn a custom firmata. Exactly how I can't seem to figure out as it seems to have changed over the years. It's a function of Arduino Servo objects and not actually firmata itself.

dtex commented 9 years ago

Back in ancient times (the late 80's) R/C speed controls were variable resistors that used a standard servo to move the contact point across a resistor bar (speed was literally controlled by servos). The big ESC manufacturers at the time (Tekin and Novak) designed their devices to be drop-in replacements for standard servos (at the time Airtronics and Futaba).

I know these things because I am old.

I'll bet two LED's and a bunch of resistors I will never use that this ESC is exactly the same. My money is still on it not being in sport mode.

Resseguie commented 9 years ago

Dang, now I'm itching to break out my old Traxxas and hook it up to an Arduino. I have enough projects on my to-do list already!

carldanley commented 9 years ago

As an update, I put the RC car into sports mode by following the directions listed here. Still no luck :(

What's the easiest thing I can do to help you debug this?

reconbot commented 9 years ago

I would write up a little C program to try the higher frequency servo control and see if that works. I think you can manually sleep in a loop while turning a digital write on and off. At the very least you'll rule out the pwm as the cause of your troubles.


Francis Gulotta wizard@roborooter.com

On Tue, Dec 16, 2014 at 3:21 PM, Carl Danley notifications@github.com wrote:

As an update, I put the RC car into sports mode by following the directions listed here https://traxxas.com/support/Programming-Your-Traxxas-Electronic-Speed-Control. Still no luck :(

What's the easiest thing I can do to help you debug this?

— Reply to this email directly or view it on GitHub https://github.com/rwaldron/johnny-five/issues/530#issuecomment-67224991 .

landshark22 commented 9 years ago

Did anyone ever solve this problem? We are having a few issues communicating with our ESC including getting reverse to work properly.

ETA: we are using a hobbyking CAR-45A ESC

rwaldron commented 9 years ago

No, not yet. @carldanley was going to ship his bot to me so I could work on it... not sure if that's still the plan. I just bought an ESC that has reverse capabilities—that will be here on Tuesday, which is the soonest I can work on this. I appreciate your patience :)

rwaldron commented 9 years ago

I just found this on another site...

More or less all ESCs have a similar calibration procedure:

  • Power up the ESC while the having maximum forward throttle applied
  • You’ll hear a tone and some beeps and after a while (usually 2 seconds) you’ll hear a confirmation tone and the led will blink a few times with a different color: this indicates that the ESC has measured the wavelenght of max throttle.
  • At this point apply zero throttle (in a fwd/reverse ESC this means full throttle reverse), wait again few seconds for the tones and led to blink: full reverse measured.
  • Then move to central (only for fwd/reverse ESCs) and wait again for the tone and blinks.

Have you tried calibrating like this?

carldanley commented 9 years ago

@rwaldron Thanks for the reminder! Email me your address so I can send my RC car your way.

rwaldron commented 9 years ago

@carldanley let's hold off on that. I have a bidirectional ESC on it's way, so it might be able to solve this without needing your entire RC car :D

rwaldron commented 9 years ago

Just an update: my speed controller arrived, so I can start working on this on my end.

carldanley commented 9 years ago

Awesome, let me know if you need anything. I can also test code on my end as well.

landshark22 commented 9 years ago

Update from us as well. We played with it a bit more after I posted this the other day and we were able to figure out we do have reverse. I have not yet tried the calibration procedure above.

I don't have my notes in front of me, but as far as I remember this is what we came up with for the HobbyKing ESC mentioned previously.

50 was the start/reset point. 49-54 Motor would not spin

Forward: 55-75 was the adjustable speed range moving forward. 75-100 no noticeable increase in speed for us.

Reverse: 48-5 Reverse But... 48-45 is the adjustable range, from 44 to 5 is reverse full speed 4-0 Motor would not spin

Some interesting notes:

if you set a forward value say 60 and set the next value at 35 the motor would stop almost like popping a circuit breaker. at this point no value forward or reverse would spin the motor. We would then need to send the value of 50 to "reset" the ESC and then we were able to enter af FWD or REV value. Of course most people would not be controlling a motor like this, just thought it was an interesting point to note.

EDITED to fix numbers after referring to my notes.

rwaldron commented 9 years ago

Your notes here are really helpful (thank you), they confirm the understanding I've come to have for 3 stage (Forward, Brake, Reverse) brushed motor speed controllers. Specifically: the forward window is greater, with a larger range and speed capability, than the reverse range.

if you set a forward value say 60 and set the next value at 35 the motor would stop almost like popping a circuit breaker. at this point no value forward or reverse would spin the motor.

This unit likely has an internal BEC that's sensing a jump and automattically shutting down. These are commonly built in to protect all components that are connected to the controller.

I've just ordered two more speed controllers to keep testing, they should be here tomorrow.

carldanley commented 9 years ago

@landshark22 do you have some sample code (maybe a gist) of the portion that controls the ESC? I want to test your calculations from my end as well.

rwaldron commented 9 years ago

@carldanley this is useful, if you have a speed controller programmer: http://www.axialracing.com/blog_posts/787000000

I made it into an Arduino C program as well:

#include <Servo.h>

#define MAX 2000
#define MIN 1000
#define NEUTRAL 1500
#define MOTOR_PIN 11

Servo esc;

int aV = 0;
int sV = 0;
int lV = 0;
int step = 0;

void setSpeed(int speed) {
  esc.writeMicroseconds(speed);
}

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

  esc.attach(MOTOR_PIN);
}

void loop() {
  // To reset the process, type a character into the serial monitor and press <enter>
  while (Serial.available()) {
    step = 0;
    aV = 0;
    Serial.read();
    Serial.println("Reset");
  }

  int v = analogRead(A0);

  if (v != aV) {
    aV = v;
    lV = sV;
    sV = map(v, 0, 1023, MIN, MAX);

    if (sV == MAX && step == 0) {
      Serial.println("Hold speed at MAX and turn on Speed Controller");
      setSpeed(sV);
      step = 1;
    }

    if (sV == MIN && step == 1) {
      Serial.println("Hold speed at MIN");
      setSpeed(sV);
      step = 2;
    }

    if (sV == NEUTRAL && step == 2) {
      Serial.println("Hold speed at NEUTRAL");
      setSpeed(sV);
      step = 3;

      delay(2000);
      step = 0;
    }

    if (step == 0) {
      setSpeed(sV);
    }
  }
}

(Hook up a rotary potentiometer to A0)

landshark22 commented 9 years ago

This unit likely has an internal BEC that's sensing a jump and automattically shutting down. These are commonly built in to protect all components that are connected to the controller.

@rwaldron I figured it was something like that.

@carldanley, this is what we've been using and I'll preface this by saying I don't know if it's right, I just now it's been working, I am starting from 0 in coding my daughter is just as green as I am so we struggled for a while to get this to work:

var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {

  var esc = new five.ESC(9);
  range: [ 0, 100 ];

  this.repl.inject({
    esc: esc
  });
});

and we use the following command to adjust speed

esc.speed (60)

ETA: I modified my post above based on my notes I was off quite a bit on some values. You'll notice the reverse range was quite small.

rwaldron commented 9 years ago

Whoa, this is awesome—there is a line of code that does literally nothing, but it's totally valid syntax! Check it out:

range: [ 0, 100 ];

This is effectively a no-op, because range: is parsed as LabelledStatement, whose Statement is just an Expression (ArrayInitializer). The Statement is evaluated and the Array object is initialized, but immediately discarded.

Ok, enough nerding out... You don't actually need to set that range for ESC—[0, 100] is the default :)

var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {

  var esc = new five.ESC(9);

  this.repl.inject({
    esc: esc
  });
});
landshark22 commented 9 years ago

Cool, that's great. We'll try that out. When things started moving we stopped messing with the code :)

A little more info that may or maynot be helpful but worth adding I suppose.

We have the motor/ESC connected to an Arduino Mega, the Mega is connected via USB to a Raspberry Pi 2 running Raspian. We are connected to the Ras Pi 2 via the ethernet connection and sending commands and editing the .js files using Orion also installed on the Pi. So far seems like everything is playing together nicely.

Our ultimate goal is to get this working with a game controller of some sort over the network along with a browser interface. Our project is an Underwater ROV.

rwaldron commented 9 years ago

All information is useful :)

This sounds like an awesome project! I'll report back later today

rwaldron commented 9 years ago

Great news: I was able to figure out bidirectional control today. Additionally, I spent time with ESC, updating it to the controller model and adding support for PCA9685 (that's in review right now)

rwaldron commented 9 years ago

@carldanley I don't think "sport mode" will ever be supportable in any reasonable sense. "Sport Mode – Fwd / Brake / Rev", from what I've learned, this requires a "double tap" of the throttle—1 to brake and then it can be reversed. This isn't meant to be programmed by any code on any platform, this is for use with transmitter + receiver. "Training Mode" which splits the range into 50% forward and 50% reverse is supportable programmatically. "Racing Mode", 100% forward or stopped, is supported by default.

carldanley commented 9 years ago

That is excellent news. For knowledge purposes, are you mentioning that sport mode is only available when a transmitter/receiver is used? Is that some feature that the transmitter makes available to us? Sorry for the confusion.

Also, for the bidirectional support, did you need to modify anything in j5 for this to work OR did you adjust values until it worked like @landshark22 has been mentioning?

rwaldron commented 9 years ago

No, it's available, it's just something you did with your finger, and not with code. Johnny-Five needed some changes, I'll be pushing those soon

rwaldron commented 9 years ago

Here's a bit more detail...


The "Forward, Brake, Reverse" setting on all of the speed controllers that I've looked at in the last couple of days requires a "flick of the trigger finger" because it assumes you're using something like one of these:

So you'd be pushing the throttle Forward; when you want to reverse you need to "flick" the throttle toward Reverse once and let it snap back to neutral, which is Brake. Once the throttle has snapped back to neutral, you can pull the throttle stick/trigger to Reverse the motor.


The "Forward, Reverse" setting assumes the same controllers above, BUT this can also easily be programmed for, as there is no "double tap into reverse" necessary. There is a neutral pulse (the center of the max and min pulse); Forward is neutral -> max (stopped -> full speed) and Reverse is neutral -> min (stopped -> full speed).

Resseguie commented 9 years ago

Just a clarifying remark for those not familiar with these transmitters. The concept of "pushing the throttle forward" applies to the second type that Rick shows. It's physically reversed in the trigger style transmitter where you "pull the trigger" to drive forward and "push the trigger away from you" to brake/reverse. Wanted to make sure we didn't get confused with physical direction of the throttle mechanism and the direction the vehicle drives.

Resseguie commented 9 years ago

(this stuff is hard to describe in just text!)

rwaldron commented 9 years ago

Oh man, while I wrote that I was describing the physical act—as I actually did it in real life—with the the second style controller. Thanks for the additional clarification, because THAT would've been confusing :D

carldanley commented 9 years ago

This makes total sense now; thanks for taking the time to explain it @rwaldron!

@Resseguie - you're absolutely right; just one of those things that's difficult to read through.

landshark22 commented 9 years ago

Ok, great news

bur here's couple of a really stupid newb questions.

  1. How do I check the currently installed version of johnny-five (installed on a Ras Pi 2 running Raspian)

tried:

johnny-five -v

and received a "command not found" error

  1. How do I upgrade to the latest?

I attempted this:

sudo apt-get update 

and then:

sudo apt-get upgrade johnny-five

lots happened just not sure if we got the latest.

Not only are we new to coding also new to Linux.

rwaldron commented 9 years ago

bur here's couple of a really stupid newb questions.

:P no such thing.

johnny-five -v

There is no Johnny-Five binary, if your project has a package.json, then presumably that file has the version installed listed?

sudo apt-get upgrade johnny-five

Johnny-Five isn't a package that's available this way.


The patch for this ESC issue isn't released yet, I'm waiting to try a few more ESCs. Once it is, then you'll be able to update on the Pi with:

npm install johnny-five

Hopefully this helped?

landshark22 commented 9 years ago

It did thanks.

rwaldron commented 9 years ago

Great!