Saturday, August 3, 2013

Part 3: ESC and Motor (wiring and code)

List of parts to blog:
Part 1: Quadcopter Design
Part 2: Integrating rc Transmitter and Receiver with Arduino
Part 3: ESC and motors (wiring and code)
Part 4: Sensors (reading in raw data and applying calibration)
Part 5: IMU - Kalman Filter Orientation Estimator
Part 6: Discussion on Arduino Boards
Part 7: Designing a shield for the Due
Part 8: Control Laws!!!!!


Part 3: ESC and Motor (wiring and code)
Detailed in this section is flashing the ESC's, wiring them up, and sending commands from the Arduino to control the motors.

Part 3A: Flashing ESCs
Okay so in the video in Part 2, you can hear the high pitch noise from the motor. Yah thats annoying so to get rid of that you have to run the ESC at a higher rate. A guy by the name of SimonK has done this for us. He also has optimized the programming for quadcopters. His firmware is the standard for qaudcopters. Read about it here: http://www.rcgroups.com/forums/showthread.php?t=1513678

For the ESC's that I have I found a very nice page that details step by step on how to flash them:
http://www.rchacker.com/diy/simonk-esc-firmware-flashing
Following these steps from start to finish it took me maybe 45 minutes. Worked great. Now my motors spin nice and quiet and awesome.
Essentially what you do is you first have to buy an AVR programmer to connect your computer to the ESC via USB to the MOSI, MISO, etc pins on the ESC to reprogram the chip. Then use some software from here:
http://lazyzero.de/en/modellbau/kkmulticopterflashtool
which then flashes the ESC with the SimonK software.

Part 3B: Wiring ESC and Motors
Wiring for motors is simple.3 plugs on motor, 3 similar plugs on ESC  (or in my case no plugs and I had to buy and solder some bullet plugs onto the wires). Just make sure the middle plug from the ESC goes into middle cable of motor. The outer wires can be swaped. If you put the left one into right most on motor, the motor will spin on way. Do opposite and motor spins the other way.
Connect battery red and black to the ESC red and black wires (i soldered mine to the base plate of my frame and added some plugs).
Then the ESC has a servo plug (red brown orange cable. plug the brown into the ground on the arduino so that they have a common ground. Then the orange wire needs to be connected to a digital pin on the arduino:




Part 3C: Arduino Code for ESC and Motors
Okay so the ESC is looking for a signal exactly like the signal from the receiver, a PPM. So we need to send a pulse out the is x microseconds long where x is 1000 to 2000, with 1000 essentially being a 0 and 2000 meaning spin motor at full speed. Here is the code to do this, luckily Arduino has a library called servo that writes these pulses for us very easily.

The following code is integrated with the receiver code from the previous section, so now the throttle on the transmitter should control all four motors
====================================================================
#include <Servo.h> //standard arduino library to send signals to ESC


#define THROTTLE_PIN 53

#define MOTOR_1_PIN 36
#define MOTOR_2_PIN 38
#define MOTOR_3_PIN 40
#define MOTOR_4_PIN 42

//Receiver variables
volatile boolean bNewSignal_throttle = false; 
volatile unsigned long ulStartPeriod_throttle = 0;
volatile int throttle_pos_v = 1000;
static int throttle_pos = 1000;

// Motor Vars: FR = front right, FL = front left, BR = back right...
int motor_fr_cmd = 1000;
int motor_fl_cmd = 1000;
int motor_br_cmd = 1000;
int motor_bl_cmd = 1000;
Servo motor_FR;
Servo motor_FL;
Servo motor_BR;
Servo motor_BL;

void setup() {

 // Receiver interrupt routines
 attachInterrupt(THROTTLE_PIN,ISR_throttle,CHANGE)

  //Motor Servos
  motor_FR.attach(MOTOR_1_PIN);
  motor_FL.attach(MOTOR_2_PIN);
  motor_BR.attach(MOTOR_3_PIN);
  motor_BL.attach(MOTOR_4_PIN);
}

void loop() {

 noInterrupts();
  if(bNewSignal_throttle)
  {
    throttle_pos = throttle_pos_v;
    bNewSignal_throttle = false;
  }
 interrupts();

  // Send commands to ESCs
  motor_FR.writeMicroseconds(throttle_pos);
  motor_FL.writeMicroseconds(throttle_pos);
  motor_BR.writeMicroseconds(throttle_pos);
  motor_BL.writeMicroseconds(throttle_pos);

 delay(5);
}


// Interrupt Routines
void ISR_throttle() {
  if(digitalRead(THROTTLE_PIN) == HIGH) //means it went 0 to 1
    ulStartPeriod_throttle = micros();
  else // it went from 0 to 1, thus end of pulse
  {
    if(ulStartPeriod_throttle && (bNewSignal_throttle == false))
    {
      throttle_pos_v = (int)(micros() - ulStartPeriod_throttle);
      ulStartPeriod_throttle = 0;
      bNewSignal_throttle = true;
}  }}
====================================================================


No comments:

Post a Comment