I built a drone with Arduino UNO. I calibrated the IMU(MPU6050) using arduino software. I used NRF module as Reciever. And i have tested the reciever too, and it is working pretty well. And the motors are 1000kv BLDC motors. And the main issue is my drone is not arming finally... Can anyone help me to come up with this issue..?
The reciever code:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
////////////////////// PPM CONFIGURATION//////////////////////////
#define channel_number 6 //set the number of channels
#define sigPin 2 //set PPM signal output pin on the arduino
#define PPM_FrLen 27000 //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 400 //set the pulse length
//////////////////////////////////////////////////////////////////
int ppm[channel_number];
const uint64_t pipeIn = 0xE8E8F0F0E1LL;
RF24 radio(7, 10);
// The sizeof this struct should not exceed 32 bytes
struct MyData {
byte throttle;
byte yaw;
byte pitch;
byte roll;
byte AUX1;
byte AUX2;
};
MyData data;
void resetData()
{
// 'safe' values to use when no radio input is detected
data.throttle = 0;
data.yaw = 127;
data.pitch = 127;
data.roll = 127;
data.AUX1 = 0;
data.AUX2= 0;
setPPMValuesFromData();
}
void setPPMValuesFromData()
{
ppm[0] = map(data.throttle, 0, 255, 1000, 2000);
ppm[1] = map(data.yaw, 0, 255, 1000, 2000);
ppm[2] = map(data.pitch, 0, 255, 1000, 2000);
ppm[3] = map(data.roll, 0, 255, 1000, 2000);
ppm[4] = map(data.AUX1, 0, 1, 1000, 2000);
ppm[5] = map(data.AUX2, 0, 1, 1000, 2000);
}
/**************************************************/
void setupPPM() {
pinMode(sigPin, OUTPUT);
digitalWrite(sigPin, 0); //set the PPM signal pin to the default state (off)
cli();
TCCR1A = 0; // set entire TCCR1 register to 0
TCCR1B = 0;
OCR1A = 100; // compare match register (not very important, sets the timeout for the first interrupt)
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // 8 prescaler: 0,5 microseconds at 16mhz
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();
}
void setup()
{
resetData();
setupPPM();
// Set up radio module
radio.begin();
radio.setDataRate(RF24_250KBPS); // Both endpoints must have this set the same
radio.setAutoAck(false);
radio.openReadingPipe(1,pipeIn);
radio.startListening();
}
/**************************************************/
unsigned long lastRecvTime = 0;
void recvData()
{
while ( radio.available() ) {
radio.read(&data, sizeof(MyData));
lastRecvTime = millis();
}
}
/**************************************************/
void loop()
{
recvData();
unsigned long now = millis();
if ( now - lastRecvTime > 1000 ) {
// signal lost?
resetData();
}
setPPMValuesFromData();
}
/**************************************************/
//#error Delete this line befor you cahnge the value (clockMultiplier) below
#define clockMultiplier 2 // set this to 2 if you are using a 16MHz arduino, leave as 1 for an 8MHz arduino
ISR(TIMER1_COMPA_vect){
static boolean state = true;
TCNT1 = 0;
if ( state ) {
//end pulse
PORTD = PORTD & ~B00000100; // turn pin 2 off. Could also use: digitalWrite(sigPin,0)
OCR1A = PPM_PulseLen * clockMultiplier;
state = false;
}
else {
//start pulse
static byte cur_chan_numb;
static unsigned int calc_rest;
PORTD = PORTD | B00000100; // turn pin 2 on. Could also use: digitalWrite(sigPin,1)
state = true;
if(cur_chan_numb >= channel_number) {
cur_chan_numb = 0;
calc_rest += PPM_PulseLen;
OCR1A = (PPM_FrLen - calc_rest) * clockMultiplier;
calc_rest = 0;
}
else {
OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * clockMultiplier;
calc_rest += ppm[cur_chan_numb];
cur_chan_numb++;
}
}
}
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
/*Create a unique pipe out. The receiver has to
wear the same unique code*/
const uint64_t pipeOut = 0xE8E8F0F0E1LL; //IMPORTANT: The same as in the receiver
RF24 radio(7, 10); // select CSN pin
// The sizeof this struct should not exceed 32 bytes
// This gives us up to 32 8 bits channals
struct MyData {
byte throttle;
byte yaw;
byte pitch;
byte roll;
byte AUX1;
byte AUX2;
};
MyData data;
void resetData()
{
//This are the start values of each channal
// Throttle is 0 in order to stop the motors
//127 is the middle value of the 10ADC.
data.throttle = 0;
data.yaw = 127;
data.pitch = 127;
data.roll = 127;
data.AUX1 = 0;
data.AUX2 = 0;
}
void setup()
{
//Start everything up
radio.begin();
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipeOut);
resetData();
}
/**************************************************/
// Returns a corrected value for a joystick position that takes into account
// the values of the outer extents and the middle of the joystick range.
int mapJoystickValues(int val, int lower, int middle, int upper, bool reverse)
{
val = constrain(val, lower, upper);
if ( val < middle )
val = map(val, lower, middle, 0, 128);
else
val = map(val, middle, upper, 128, 255);
return ( reverse ? 255 - val : val );
}
void loop()
{
// The calibration numbers used here should be measured
// for your joysticks till they send the correct values.
data.throttle = mapJoystickValues( analogRead(A0), 13, 524, 1015, true );
data.yaw = mapJoystickValues( analogRead(A1), 1, 505, 1020, true );
data.pitch = mapJoystickValues( analogRead(A2), 12, 544, 1021, true );
data.roll = mapJoystickValues( analogRead(A3), 34, 522, 1020, true );
data.AUX1 = digitalRead(4); //The 2 toggle switches
data.AUX2 = digitalRead(5);
radio.write(&data, sizeof(MyData));
}
Thanks for posting the diagrams. Generally, people do not prefer Fritzinf, since it is hard to tell which pins are connected to which wire.
For example, there is no pinout for the receiver nRF. I can't tell for sure by looking at the diagram. I googled the pinout.
I don't see where your sigPin is connected to the receiver Uno.
To arm the drone,I need to hold the left side joystick and take it to the bottom left position and hold it there for one or two seconds.I have to make sure to take it to the exact correct position. but i have tried for number of times and different positions too, but the motors had no movement.
I have done the reciever test to confirm good connection between the transmitter and receiver and the test is successful. At the Arming position throttle is at minimum (0) and yaw is also at minimum (0)
Flight control software makes it hard to arm for good reason.
Have you enabled or examined any feedback the FC might be giving you as to why it won't arm?
Google
my quadcopter won't arm
and see the company you have in your misery and possible conditions that you might not realize aren't being attained.
Like level, motionless, good response from your IMU and so forth.
I hope you have yet to put propellers on… google and see what some ppl have done to their arms and faces messing with stuff what ain't ready for prime time.
Do not go in and code around the stuff that is in there keeping you from arming!
Thanks for the reply. I have googled many times and i cant find the solution. What could be the possible mistake i have done in the FC. Can i do something in the Multiwii GUI.
You should be able to see that the controls you are moving on the transmitter are making the expected changes in the inputs of the Flight Controller. Is that all working?
I can only suggest getting intimately familiar with all the code so you can find and ponder about all the criteria and factors that go into the FC decision to allow arming.
I assume you haven't left anything obvious overlooked.
You could try something a bit more usual for quadcopters these days and that is configuring it to arm and disarm by a switch on an additional channel from your TX.
Switch arming and disarming is preferred to stick arming anyway - believe me when I tell you being able to reliably disarm nearly instant w/o some gesture that has to be just right is a very comforting circumstance.
So the Flight Controller is not reacting at all to the commands from the transmitter?!? THAT will keep the FC from arming (or doing anything else). Find some way to check the output of the receiver. Are the pulses even getting to the FC?
In the GUI, the accelometer is showing the pulse and I have also done the ACC Calibration. All the values are fluctuating except the transmitter values ie; yaw, throttle, pitch,roll.
so you should step back,
to make just the data-transmission work.
by the way:
the professional way of developping such a system is doing it step by step
you seem to have done it not that way. If you would your datatransmission would work
in more general
why do more and more users take a drone as their first project?
This is the kings-class of softwaredevelopping requiring highest responsiveness, using PID-Algorithms etc.
If you want to have fun flying a DIY-drone. Buy a ready to calibrate flightcontroller. There will be enough work for calibrating it.
Are you able to fly a non-self-stab ilising quadrocopter?
if you want to have fun with a DIY-remoteley controlled vehicel take a car or a boat. But not flying.