I have been trying to read and understand a code . It all started with my ambition to built a quadcopter . I researched alot and found this channel in utube "Joop Brokking". He had a series of videos where he taught ppl how to built a drone from arduino ...with little bit of code explanation and making the whole code available.
But i just felt bad to copy d code and decided to understand each line of it...
And as expected many confusions and questions arose ...giving me a headache..
The first confusion...
Some variables were defined without assigning them any pin and without declaring them as input..( example... volatile int receiver_input_channel_1;)
And here comes d amazing thing ....we can still read the values from those variables...
And many more questions...
With hope atleast a single person. Reads this and helps me.
Please note ...
Its a quadcopter setup code.
it works fine when compiled.
compatible with arduino uno.
*The receiver of the rc transmitter are connected to digital pin 8,9,10 and 11 in d arduino uno
I went everywhere to find d ans.... reddit,google (multiple times )
Read d code fr 3 days...bt still could not figure out.
Heres ma last hope ....
#include <Wire.h> //Include the Wire.h library so we can communicate with the gyro
#include <EEPROM.h> //Include the EEPROM.h library so we can store information onto the EEPROM
//Declaring Global Variables
byte last_channel_1, last_channel_2, last_channel_3, last_channel_4;
byte lowByte, highByte, type, gyro_address, error, clockspeed_ok;
byte channel_1_assign, channel_2_assign, channel_3_assign, channel_4_assign;
byte roll_axis, pitch_axis, yaw_axis;
byte receiver_check_byte, gyro_check_byte;
volatile int receiver_input_channel_1, receiver_input_channel_2, receiver_input_channel_3, receiver_input_channel_4;
int center_channel_1, center_channel_2, center_channel_3, center_channel_4;
int high_channel_1, high_channel_2, high_channel_3, high_channel_4;
int low_channel_1, low_channel_2, low_channel_3, low_channel_4;
int address, cal_int;
unsigned long timer, timer_1, timer_2, timer_3, timer_4, current_time;
float gyro_pitch, gyro_roll, gyro_yaw;
float gyro_roll_cal, gyro_pitch_cal, gyro_yaw_cal;
//Setup routine
void setup(){
pinMode(12, OUTPUT);
//Arduino (Atmega) pins default to inputs, so they don't need to be explicitly declared as inputs
PCICR |= (1 << PCIE0); // set PCIE0 to enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); // set PCINT0 (digital input 8) to trigger an interrupt on state change
PCMSK0 |= (1 << PCINT1); // set PCINT1 (digital input 9)to trigger an interrupt on state change
PCMSK0 |= (1 << PCINT2); // set PCINT2 (digital input 10)to trigger an interrupt on state change
PCMSK0 |= (1 << PCINT3); // set PCINT3 (digital input 11)to trigger an interrupt on state change
Wire.begin(); //Start the I2C as master
Serial.begin(57600); //Start the serial connetion @ 57600bps
delay(250); //Give the gyro time to start
}
//Main program
void loop(){
//Show the YMFC-3D V2 intro
intro();
Serial.println(F(""));
Serial.println(F("==================================================="));
Serial.println(F("System check"));
Serial.println(F("==================================================="));
delay(1000);
Serial.println(F("Checking I2C clock speed."));
delay(1000);
TWBR = 12; //Set the I2C clock speed to 400kHz.
#if F_CPU == 16000000L //If the clock speed is 16MHz include the next code line when compiling
clockspeed_ok = 1; //Set clockspeed_ok to 1
#endif //End of if statement
if(TWBR == 12 && clockspeed_ok){
Serial.println(F("I2C clock speed is correctly set to 400kHz."));
}
else{
Serial.println(F("I2C clock speed is not set to 400kHz. (ERROR 8)"));
error = 1;
}
if(error == 0){
Serial.println(F(""));
Serial.println(F("==================================================="));
Serial.println(F("Transmitter setup"));
Serial.println(F("==================================================="));
delay(1000);
Serial.print(F("Checking for valid receiver signals."));
//Wait 10 seconds until all receiver inputs are valid
wait_for_receiver();
Serial.println(F(""));
}
//Quit the program in case of an error
if(error == 0){
delay(2000);
Serial.println(F("Place all sticks and subtrims in the center position within 10 seconds."));
for(int i = 9;i > 0;i--){
delay(1000);
Serial.print(i);
Serial.print(" ");
}
Serial.println(" ");
//Store the central stick positions
center_channel_1 = receiver_input_channel_1;
center_channel_2 = receiver_input_channel_2;
center_channel_3 = receiver_input_channel_3;
center_channel_4 = receiver_input_channel_4;
Serial.println(F(""));
Serial.println(F("Center positions stored."));
Serial.print(F("Digital input 08 = "));
Serial.println(receiver_input_channel_1);
Serial.print(F("Digital input 09 = "));
Serial.println(receiver_input_channel_2);
Serial.print(F("Digital input 10 = "));
Serial.println(receiver_input_channel_3);
Serial.print(F("Digital input 11 = "));
Serial.println(receiver_input_channel_4);
Serial.println(F(""));
Serial.println(F(""));
}
if(error == 0){
Serial.println(F("Move the throttle stick to full throttle and back to center"));
//Check for throttle movement
check_receiver_inputs(1);
Serial.print(F("Throttle is connected to digital input "));
Serial.println((channel_3_assign & 0b00000111) + 7);
if(channel_3_assign & 0b10000000)Serial.println(F("Channel inverted = yes"));
else Serial.println(F("Channel inverted = no"));
wait_sticks_zero();
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Move the roll stick to simulate left wing up and back to center"));
//Check for throttle movement
check_receiver_inputs(2);
Serial.print(F("Roll is connected to digital input "));
Serial.println((channel_1_assign & 0b00000111) + 7);
if(channel_1_assign & 0b10000000)Serial.println(F("Channel inverted = yes"));
else Serial.println(F("Channel inverted = no"));
wait_sticks_zero();
}
if(error == 0){
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Move the pitch stick to simulate nose up and back to center"));
//Check for throttle movement
check_receiver_inputs(3);
Serial.print(F("Pitch is connected to digital input "));
Serial.println((channel_2_assign & 0b00000111) + 7);
if(channel_2_assign & 0b10000000)Serial.println(F("Channel inverted = yes"));
else Serial.println(F("Channel inverted = no"));
wait_sticks_zero();
}
if(error == 0){
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Move the yaw stick to simulate nose right and back to center"));
//Check for throttle movement
check_receiver_inputs(4);
Serial.print(F("Yaw is connected to digital input "));
Serial.println((channel_4_assign & 0b00000111) + 7);
if(channel_4_assign & 0b10000000)Serial.println(F("Channel inverted = yes"));
else Serial.println(F("Channel inverted = no"));
wait_sticks_zero();
}
if(error == 0){
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Gently move all the sticks simultaneously to their extends"));
Serial.println(F("When ready put the sticks back in their center positions"));
//Register the min and max values of the receiver channels
register_min_max();
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("High, low and center values found during setup"));
Serial.print(F("Digital input 08 values:"));
Serial.print(low_channel_1);
Serial.print(F(" - "));
Serial.print(center_channel_1);
Serial.print(F(" - "));
Serial.println(high_channel_1);
Serial.print(F("Digital input 09 values:"));
Serial.print(low_channel_2);
Serial.print(F(" - "));
Serial.print(center_channel_2);
Serial.print(F(" - "));
Serial.println(high_channel_2);
Serial.print(F("Digital input 10 values:"));
Serial.print(low_channel_3);
Serial.print(F(" - "));
Serial.print(center_channel_3);
Serial.print(F(" - "));
Serial.println(high_channel_3);
Serial.print(F("Digital input 11 values:"));
Serial.print(low_channel_4);
Serial.print(F(" - "));
Serial.print(center_channel_4);
Serial.print(F(" - "));
Serial.println(high_channel_4);
As this and several other variables are declared as volatile I would guess that they are used in an Interrupt Service Routine (an ISR) but as you have not posted all of the code it is impossible to say
robinsharmas22:
Some variables were defined without assigning them any pin and without declaring them as input.
It is quite common to define a variable without giving it a value. The business of defining a variable just sets aside memory for it. You can put the value in that memory later.
The definition of INPUT or OUTPUT is never done when a variable is created to hold a pin number. It is done with the pinMode() function and usually in setup()
Seems like i cant really express my problem..
Please get to this link
As i cant post d entire code please take this trouble for me..
Get to d u would get a zip file then get to the setup code.
Yes i agree u but the problem is, even one of the variable is not assigned to any pin in d entire code , but u are still receiving inputs via input devices (in my case a rc transmitter and receiver )
And i was really amazed after that.
I really dont know whats going on
robinsharmas22:
Seems like i cant really express my problem..
If English isn't your first language, maybe there's help to be had in the International section of the forum.
If the code didn't have quite so many superfluous comments, maybe it could be posted here
Wire.write(0x6B); // want to write to the PWR_MGMT_1 register (6B hex)
If the guy had named the constant, we wouldn't need the stupid comment. Grrrr.
if(Wire.read() != 0x08){ //Check if the value is 0x08This kind of coding is infuriating, and NOT what you want to be learning from.
The expression is obviously testing a value, so the comment is superfluous, but it doesn't explain what "0x08" MEANS.
To understand this code you'd need to understand the libraries and registers it uses - its not the place to start learning to read code, its far too complex for that. And you need to learn to write code first, for instance you clearly don't understand what a variable is yet - these concepts are vital to assimilate first.
PCICR |= (1 << PCIE0); // set PCIE0 to enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); // set PCINT0 (digital input 8) to trigger an interrupt on state change
PCMSK0 |= (1 << PCINT1); // set PCINT1 (digital input 9)to trigger an interrupt on state change
PCMSK0 |= (1 << PCINT2); // set PCINT2 (digital input 10)to trigger an interrupt on state change
PCMSK0 |= (1 << PCINT3); // set PCINT3 (digital input 11)to trigger an interrupt on state change
These lines are setting up Pin Change Interrupts for the four input pins. The Interrupt Service Routines are elesewhere in the code. Those routines are called whenever the corresponding input pin changes state from LOW to HIGH or HIGH to LOW. I expect the ISR's are calculating how long the HIGH pulses are because that is what the joysticks on the transmitter control. Typically the pulses will be 1000 to 2000 microseconds, just like the pulses that control a hobby servo. I expect the pulse widths are updated in a set of global variables as new pulses arrive. The rest of the code just reads the globals to get the current position of the transmitter joysticks.
You do yourself a disservice by using "d" and "u" - saving yourself a few milliseconds here and there.
It makes it harder for people to read. By saving yourself a few seconds total, at best, you have taxed an entire community, the sum total of which tax probably amounts to many minutes of wasted time.
I have formed the opinion that you are too lazy to succeed with this. The website you linked is full of information, lovely stuff, has its own Q&A section, &c.
Spend some of that time you saved here - use it on the website or talk with your good friend google.
You really need to start learning C / C++. As has been suggested, you might want to start with something a wee bit less complicated than a quadcopter flight control system.
You also should google a bit on the whole quadcopter thing - Arduino-based builds are not that popular. Many of us enthusiasts do quite well with other flight control software, and for the most part resign ourselves to the fact that often we have to just think of it as magic coming out of a black box.