I've been making my own quadcopter flight controller using Arduino Mega. This is the sample code I wrote in order to test the esc timers and motors:
byte channelcount_1, channelcount_2, channelcount_3, channelcount_4;
int receiverinput_channel_1, receiverinput_channel_2, receiverinput_channel_3, receiverinput_channel_4, start;
unsigned long channel_timer_1, channel_timer_2, channel_timer_3, channel_timer_4, current_time, esc_looptimer;
unsigned long zero_timer, timer_1, timer_2, timer_3, timer_4;
void setup() {
// put your setup code here, to run once:
DDRC |= B11110000; //Setting digital pins 30,31,32,33 as output
DDRB |= B10000000;; //Setting LED Pin 13 as output
//Enabling Pin Change Interrupts
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT0); //Channel 3 PIN 52
PCMSK0 |= (1 << PCINT1); //Channel 4 PIN 53
PCMSK0 |= (1 << PCINT2); //Channel 2 PIN 51
PCMSK0 |= (1 << PCINT3); //Channel 1 PIN 50
//Wait till receiver is connected
while (receiverinput_channel_3 < 990 || receiverinput_channel_3 > 1020 || receiverinput_channel_4 < 1400) {
start++;
PORTC |= B11110000;
delayMicroseconds(1000); // 1000us pulse for esc
PORTC &= B00001111;
delay(3); //Wait 3 ms for next loop
if (start == 125) { // every 125 loops i.e. 500ms
digitalWrite(13, !(digitalRead(13))); //Change LED status
start = 0; //Loop again
}
}
start = 0;
digitalWrite(13, LOW); //Turn off LED pin 13
zero_timer = micros();
}
void loop() {
// put your main code here, to run repeatedly:
while (zero_timer + 4000 > micros());
zero_timer = micros();
PORTC |= B11110000;
channel_timer_1 = receiverinput_channel_3 + zero_timer; //Time calculation for pin 33
channel_timer_2 = receiverinput_channel_3 + zero_timer; //Time calculation for pin 32
channel_timer_3 = receiverinput_channel_3 + zero_timer; //Time calculation for pin 31
channel_timer_4 = receiverinput_channel_3 + zero_timer; //Time calculation for pin 30
while (PORTC >= 16) //Execute till pins 33,32,31,30 are set low
{
esc_looptimer = micros();
if (esc_looptimer >= channel_timer_1)PORTC &= B11101111; //When delay time expires, pin 33 is set low
if (esc_looptimer >= channel_timer_2)PORTC &= B11011111; //When delay time expires, pin 32 is set low
if (esc_looptimer >= channel_timer_3)PORTC &= B10111111; //When delay time expires, pin 31 is set low
if (esc_looptimer >= channel_timer_4)PORTC &= B01111111; //When delay time expires, pin 30 is set low
}
}
//Interrupt Routine PCI0 for Receiver
ISR(PCINT0_vect)
{
current_time = micros();
//Channel 1
if (PINB & B00001000)
{
if (channelcount_1 == 0 )
{
channelcount_1 = 1;
channel_timer_1 = current_time;
}
}
else if (channelcount_1 == 1 )
{
channelcount_1 = 0;
receiverinput_channel_1 = current_time - channel_timer_1;
}
//Channel 2
if (PINB & B00000100)
{
if (channelcount_2 == 0 )
{
channelcount_2 = 1;
channel_timer_2 = current_time;
}
}
else if (channelcount_2 == 1)
{
channelcount_2 = 0;
receiverinput_channel_2 = current_time - channel_timer_2;
}
//Channel 3
if (PINB & B00000010)
{
if (channelcount_3 == 0 && PINB & B00000010)
{
channelcount_3 = 1;
channel_timer_3 = current_time;
}
}
else if (channelcount_3 == 1)
{
channelcount_3 = 0;
receiverinput_channel_3 = current_time - channel_timer_3;
}
//Channel 4
if (PINB & B00000001) {
if (channelcount_4 == 0 )
{
channelcount_4 = 1;
channel_timer_4 = current_time;
}
}
else if (channelcount_4 == 1)
{
channelcount_4 = 0;
receiverinput_channel_4 = current_time - channel_timer_4;
}
}
However, my issue here is that the bldc motors i'm using don't work smoothly when connected to the Arduino. They erratically stop and even change direction of rotation at the same throttle input. I've tested them by connecting them directly to the transmitter and they work fine there with perfect rotation and speed. Can someone please help me out and tell me where I might be going wrong?
EDIT: I do realize posting the entire Arduino code might be overkill, but I've been trying to solve this problem for three days (as of 22nd June,16) and I really do hope someone can point out any improvements/corrections in my code.