Control APM 2.8 w/ Ardunio issue (Replace receiver)

Dad here, trying to help daughter for science project.

Update 1 So I did something different, I plugged in the usb from PC while battery was plugged in so I could see the ardunio control the motor functions in MP. (Theory) - and it worked. So I think my updated question - is there some sort of power I need to apply to input side that I may not be getting when I have just the ppm plugged in w/USB. I assumed the RX was being fed from APM since it worked via battery or usb. But when I replace RX with ardunio with only ppm cable, it seems to not listen anymore (APM).

Update 2 - So I tried something new. I connected the ground from the input side to the ground on the ardunio. My thinking it might have been grounding via USB. Sure enough, it started working. So basically have Ardunio connected via battery (seperate for now), and pin 13 for ppm and ground back to ardunio from negative on input rail.

So it works - now trying to move from Uno to Micro Ardunio

-Original post below

USB + Ardunio and No Battery - Commands reach apm
Ardunio + Battery - Commands appear to not reach APM
Only pin 13 from Ardunio to PPM Pin is installed in both cases.

Basically wants quad copter to (on power on - connecting batter), go up 1 foot (tethered) and then land.

So far built 450 clone, with apm 2.8 and 3.2.1 firmware. Successfully hooked up remote and receiver to power up motors. [however cant use for project - more on this]. Figured out needed to put left joystick in lower right corner before being able to run motors for 5 sec. (newbie).

Plan is to send ppm signals to APM via pin 13. Current remote communicates via ppm (flysky fs16x).

Hooked up ardunio, ran mission planner and can confirm APM is getting ppm signal from ardunio, joystick bars move for setup as told to do by ardunio. However, when turning on quad copter, and having pin 13 attached to 13 (same as test via MP), the motors wont run (have battery plugged in).

I thought maybe it was wanting the same command via ppm the joystick sends for 5 sec first (is there a way to turn this off). So I sent the same command via ppm to the APM. Nothing.

I can unplug battery, plug in usb, launch mp and confirm the ardunio is sending the correct commands, but nothing from motor. I can remove ardunio, plug in remote, all works as expected.

What am I missing? Code below:

#define CHANNEL_NUMBER 8 //set the number of chanels
#define CHANNEL_DEFAULT_VALUE 1500 //set the default servo value
#define FRAME_LENGTH 22500 //set the PPM frame length in microseconds (1ms = 1000µs)
#define PULSE_LENGTH 300 //set the pulse length
#define onState 1 //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 13 //set PPM signal output pin on the arduino

/this array holds the servo values for the ppm signal
change theese values in your code (usually servo values move between 1000 and 2000)

int start = 1;

void setup(){

//initiallize default ppm values
for(int i=0; i<CHANNEL_NUMBER; i++){

pinMode(sigPin, OUTPUT);

digitalWrite(sigPin, !onState); //set the PPM signal pin to the default state (off)

TCCR1A = 0; // set entire TCCR1 register to 0
TCCR1B = 0;

OCR1A = 100; // compare match register, change this
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // 8 prescaler: 0,5 microseconds at 16mhz
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt

// arm
// 2 - throttle 990
// 3 - yaw 1986

ppm[2] = 900;
ppm[3] = 1986;

while (start < 6000){


void loop(){

Here modify ppm array and set any channel to value between 1000 and 2000.
Timer running in the background will take care of the rest and automatically
generate PPM signal on output pin using values in ppm array

/* 2 - throttle
3 - yaw
1 - pitch
4 - radio 5
5 - radio 6
6 - radio 7

ppm[2] = 1500;
ppm[3] = 1500;


ISR(TIMER1_COMPA_vect){ //leave this alone
static boolean state = true;

TCNT1 = 0;

if (state) { //start pulse
digitalWrite(sigPin, onState);
state = false;
} else{ //end pulse and calculate when to start the next pulse
static byte cur_chan_numb;
static unsigned int calc_rest;

digitalWrite(sigPin, !onState);
state = true;

if(cur_chan_numb >= CHANNEL_NUMBER){
  cur_chan_numb = 0;
  calc_rest = calc_rest + PULSE_LENGTH;// 
  OCR1A = (FRAME_LENGTH - calc_rest) * 2;
  calc_rest = 0;
  OCR1A = (ppm[cur_chan_numb] - PULSE_LENGTH) * 2;
  calc_rest = calc_rest + ppm[cur_chan_numb];

}Preformatted text

1 Like