Sunday, 15 January 2017

Forward and Reverse in BLDC ESC

Last post (here) we looked at the ESC control in cars, with and without brakes. Here, I provide a sample code that managed to run the car autonomously (meaning: it ran without any Tx / Rx).

#include<Servo.h>
Servo esc; // Call the ESC "esc"
void setup()
{
  esc.attach(9);
/*
As you can see - I am not arming the ESC here. For some reason, the ESC is now on a persistently armed mode now. Upon powering, the ESC automatically arms. Given sparse documentation for the ESC, I am not examining this weird behavior changes in this ESC. However, if your ESC refuses to arm, then I would suggest the code shown in post_1 be used.
*/
//Again - this is useful only during the testing part. For autonomous running, it is pointless.
  int i=0;
  Serial.begin(9600); }

void loop()
{
  int i=0;
  // Start at Servo Degree 70 and go till just above neutral. 
  // Note, Neutral is at 94 for this ESC.
  // This will run it in one direction.
  for(i=70;i<95;i++)
  {
    esc.write(i);
    delay(200);
  }
//Run for 2 seconds at moderately high speed (70).
  esc.write(70); delay(2000);
// Apply Brakes for 40 millisecs.
  esc.write(100); delay(40);
// Apply throttle in opposite direction for 2 seconds.
  esc.write(110); delay(2000);
// Bring down throttle to neutral.
  for(i=110;i>90;i--)
  {
    esc.write(i);
    delay(200);
  }
// Apply brakes again - to change directions for 40 millisecs.
  esc.write(70); delay(40);
}

This code has not been rigorously tested at all. For example, there is no reason why I used 40 millisecs instead of, say, 35. All I have noticed is that at the pulse frequency (50Hz / 20 millisecs) this code doesn't work. So, in all likelihood, 21ms could also work. Also - I don't know what will happen if I bring the run throttle (70 and 110) closer to neutral (say,
85 and 100). In some cases, the ESC behavior abruptly changes, and the direction shifting doesn't happen (it stops running in one of the directions).

However, this code has allowed the RC car to move forward and in reverse without any external input at all. (time for a drink).

Given below is a photo of the car I had used for this purpose - it is a Traxxas / TT rip-off rally frame. The big (1/10) frame has plenty of room / power for carrying the Arduino board, a 7200 mAh NiMH battery for the car, a 10000mAh USB power bank (used to power the Arduino board) and everything else in between. I have not provided the connection drawing, because it is - at this point - trivial.



I intend to slap a SONAR on it and see if it can run around and not bump into obstacles (or walls). At that point, I will post a video :-)

Till then - ciao.

k

Saturday, 7 January 2017

Understanding ESC Response

In part 1 (here) - we saw how to arm the ESC. This is an essential part of getting your machine to work; irrespective of whether it is a rover or a quadrotor. The ESCs vary in their response post arming - for instance, a quadrotor ESC will not have forward and reverse motions programmed, and hence would only go from 0 - max_speed. This will correspond (usually) to PWM widths of 700 - 2200 microseconds. The overall frequency of signal pulsing is 50Hz (I have not personally tested this, but this assumption seems to work OK for two no-name ESCs). However, for cars - their neutral position is not the zero stick position (700 uS pulse / 0º pulse in Servo library), but the middle position (91º Servo position for this particular servo), though I suspect it will vary a few angles between different pieces of the same non-standard servo. Arming the servo is something that the code from the previous blog does reproducibly, and now am fairly confident that it works.

As mentioned in the previous blog, I have been having issues with getting the rotor spinning in forward and in reverse directions. It would do either, but not both. Now, a simplistic view of how we expect a Rover (car) ESC to work is given below; without a concept of brakes. The motor turns in one direction (say, forward) if the signal is above the Neutral point - and then in the other direction (reverse) if the signal is below neutral point. Without a brake (bringing it to a stop), we have to allow the forward motion to first stop (roll to a stop) before reversing. For the sake of simplicity, we will call the signal below neutral as negative, and the signal above neutral as positive. A simple state machine describing this behavior is also shown below.





However, sudden reversal in directions - especially in high speed models (these cars can run in excess of 20kmph) can cause severe wear and tear of the gear assembly. So, this simple model of switching between one direction to other with a simple switch in signal, while attractive, is not very practical. To overcome the limitations of the Car ESCs often have this concept of a brake. A brake is usually applied by a sending a brief pulse of the opposite magnitude; and then sending pulses that correspond to the specific direction in which we need the machine to move (figure below), where the ΔFlash Pulse is the pulse given in the opposite direction to activate the brake. 

Once the brake is applied, the machine is essentially at a neutral state and can move in either direction as the state machine below depicts. The colored arrows (green and red) show the relative change of direction of the pulse provided to apply the brake.


So in theory, if the car is running in forward direction, one has to apply the brake (briefly push the throttle in opposite direction) and then choose to move in either direction (again apply the throttle in the desired direction). Sounds very simple - but didn't work very well. For instance, the ESC would completely ignore the signals given in the opposite direction (say reverse, if the brake was applied while moving forward), but heed to signals that correspond to starting state.

In order to make sure this hypothesis about brake is correct, I intercepted the Tx signal and retransmitted through the Rx (circuit image below the plot), and plotted the pulse width as a function of time. (Figure below). In summary, this theory of braking and changing directions worked - but with a caveat (more on that later). To end this post - something interesting happened during the test described above - when I changed the directions too fast, and too many times - the ESC refused to respond - this is the point beyond about 27.5 seconds (275 on the X-axis).


There seems to be an inbuilt mechanism in the ESC to protect itself and the motor (and the car) from crazy driving. Unfortunately, given that this ESC has very little or no documentation, I am left guessing all of this.

Addendum: Circuit for intercepting Rx signal and re-transmitting to ESC

Friday, 6 January 2017

ArduRover_ArmESC

I find this question often in the internet - and I also see it go unanswered. Here is a stepwise guide to arm the Brushless ESC using Arduino. The usual disclaimer applies: 1) this is a general guide to know your arming point - not a specific answer; 2) this may kill your arduino / your ESC / your motor or your computer - am not responsible.

Having gotten them out of the way:

Code: [Select]

#include <Servo.h>

Servo motor;

void setup ()
{
  motor.attach(9); 
  Serial.begin(9600);
  int i = 0;

  //Give some time before you start anything like switching on your ESC / Motor

  Serial.print("Arming Test Starts in ");
  for(i =10; i > 0; i--)
  {
     Serial.print(i);
     Serial.print(".. ");
  }

  Serial.println();

// Watch for the tone when the ESC gets armed

  for(i = 50; i < 130; i++)
  {
     motor.write(i);
     Serial.println("i");
     delay(500);
  }
}

void loop()
{
}

When I run this on my ESC, it first gives 10sec to setup / switch on all the stuff. When you switch on your ESC, you will hear a double beep (note this tone). Now the second loop after the delay starts - where it sends one degree worth of pulse every 500 millisecs to the ESC. I have intentionally made a wide range (50 - 130), whereas your ESC will probably arm very close to neutral.

When the signal to the ESC reaches 87 - 93, pay attention - the ESC will let out another beep. This is different from the one you heard when switching it on. 

There is a bit of experimentation needed here to pinpoint the exact arming position. For my ESC, now - all I do is the following, to arm it. 

Note 1: My ESC arms at a signal of "91". For your ESC, it may be 90 or 92.

Note 2: The delay is crucial. I have gone down till 200 millisecs and still got it working. Try pushing the limit, and post as reply if you can get it.

Once the ESC has been armed, then it is a simple case of treating the angle as the run signal to the ESC. For example - see the code below
Code: [Select]

void loop()
{
  motor.write(105); delay(1000);
  motor.write(91); delay(2000);
}


will repeatedly run the motor for 1 second, and brake it for 2 seconds. Now, once the ESC is armed - the signal code "91" is merely treated as a Servo angle signal and will not repeatedly arm the ESC (until you switch the power off and on again).

I am still trying to get the forward and reverse turns on my motor reliably - it happens sporadically. I will post a second post once I have got it down pat.