How to have an Arduino wait until it receives data from a Receiver ?

Hi there!

I want arduino to wait until it receives 1800 us pulse from my receiver. Anyone can suggest me the logic for that? which loop should I use?
I am programming for my Quadcopter flight controller and want to calibrate my ESC when program starts. I want to do it when I signal from my transmitter.
thanks

Have you seen https://www.arduino.cc/en/Reference/PulseIn

I want to do it when I signal from my transmitter.

EXACTLY how are you reading that signal? What, exactly, changes when you start sending "a signal"?

#define CH1_int 0     // Channel 1 interrupt # 
#define CH1_pin 2     // Respective channel Hardware interrupt pin number

#define CH2_int 1     // Channel 2 interrupt # 
#define CH2_pin 3     // Respective channel Hardware interrupt pin number

#define CH3_int 4     // Channel 3 interrupt # 
#define CH3_pin 19     // Respective channel Hardware interrupt pin number

#define CH4_int 5     // Channel 4 interrupt # 
#define CH4_pin 18    // Respective channel Hardware interrupt pin number
#define CH5_pin 23
#define CH6_pin 25

#define valid_pulse_limit 2000 // [uS] Valid output high pulse time limit for RC controller
#define max_high_time 1895 // [uS] Maximum expected high time
#define min_high_time 1090 // [uS] Minimum expected high time
 

unsigned long t=0;
int counter;
void init_rc_rx();
//void read_rc_rx();  

volatile unsigned long CH1_t=0, CH1_delta=0, CH2_t=0, CH2_delta=0, CH3_t=0, CH3_delta=0, CH4_t=0, CH4_delta=0 ;
float CH1,CH2,CH3,CH4;
float CH5=0,CH6=0;// pulseIn channels for accessory 
unsigned long CH5_delta=0,CH6_delta=0;

// Interrupt ISRs

void CH1_int_ISR()
{
  
  if ((micros()-CH1_t) < valid_pulse_limit){
    CH1_delta = micros()-CH1_t;
  }
  CH1_t = micros();
}

void CH2_int_ISR()
{
  
  if ((micros()-CH2_t) < valid_pulse_limit){
    CH2_delta = micros()-CH2_t;
  }
  CH2_t = micros();
}

void CH3_int_ISR()
{
  
  if ((micros()-CH3_t) < valid_pulse_limit){
    CH3_delta = micros()-CH3_t;
  }
  CH3_t = micros();
}

void CH4_int_ISR()
{
  
  if ((micros()-CH4_t) < valid_pulse_limit){
    CH4_delta = micros()-CH4_t;
  }
  CH4_t = micros();
  
}

// Initialization\\

void init_rc_rx(){
  
  Serial.print("Channel 1 connected to pin number....\t");
  Serial.println(CH1_pin);
  Serial.print("Channel 2 connected to pin number....\t");
  Serial.println(CH2_pin);
  Serial.print("Channel 3 connected to pin number....\t");
  Serial.println(CH3_pin);
  Serial.print("Channel 4 connected to pin number....\t");
  Serial.println(CH4_pin);
  Serial.print("Channel 5 connected to pin number....\t");
  Serial.println(CH5_pin);
  Serial.print("Channel 6 connected to pin number....\t");
  Serial.println(CH6_pin);
  //MAKING PINS INPUT//
  pinMode(CH1_pin, INPUT);
  pinMode(CH2_pin, INPUT);
  pinMode(CH3_pin, INPUT);
  pinMode(CH4_pin, INPUT);
  pinMode(CH5_pin, INPUT);
  pinMode(CH6_pin, INPUT);
  //ENABLING INTERRUPTS//
  attachInterrupt(CH1_int, CH1_int_ISR, CHANGE);
  attachInterrupt(CH2_int, CH2_int_ISR, CHANGE);
  attachInterrupt(CH3_int, CH3_int_ISR, CHANGE);
  attachInterrupt(CH4_int, CH4_int_ISR, CHANGE);
}

//void read_rc_rx(){
//  CH1 = ((float)CH1_delta-(float)min_high_time)*100/(max_high_time-min_high_time);
//  CH2 = ((float)CH2_delta-(float)min_high_time)*100/(max_high_time-min_high_time);
//  CH3 = ((float)CH3_delta-(float)min_high_time)*100/(max_high_time-min_high_time);
//  CH4 = ((float)CH4_delta-(float)min_high_time)*100/(max_high_time-min_high_time);
//  CH5 = ((float)CH5_delta-(float)min_high_time)*100/(max_high_time-min_high_time);
//  CH6 = ((float)CH6_delta-(float)min_high_time)*100/(max_high_time-min_high_time);
//}


void setup()
{
  Serial.begin(115200); // Initlizing serial port before calling init_rc_rx() function 
  init_rc_rx();
 
   
}

void loop()
{ 
 // t = micros()/1000;
  
 
  counter++;
  if(counter == 25 || counter == 75)
  {
    CH5_delta = pulseIn(CH5_pin, HIGH,20000); //CH5 value by using pulseIn
    
  }
  if( counter == 100)
  {
    CH6_delta = pulseIn(CH6_pin, HIGH,20000); //CH6 value by using pulseIn
     
    counter = 0;
  }
  
  
   //read_rc_rx();        // CH1, CH2, CH3 and CH4 float variables will be calculated with this function is called
  
  Serial.print(CH1_delta);
  Serial.print("\t");
  Serial.print(CH2_delta);
  Serial.print("\t");
  Serial.print(CH3_delta);
  Serial.print("\t");
  Serial.print(CH4_delta); 
  Serial.print("\t");
  Serial.print(CH5_delta);
  Serial.print("\t");
  Serial.print(CH6_delta); 
  Serial.println("\t");
  

  
}

this is how I am reading my signals. I want to trigger calibration of all esc when arduino receives 1900us pulse on channel 4

LarryD:
Have you seen https://www.arduino.cc/en/Reference/PulseIn

yes. I have seen that. but this is not I actually desire. I want to trigger my all code when arduino receives 1900us signal from channel 4. pulseIn will not hold the execution of rest of code for me.

yes. I have seen that. but this is not I actually desire. I want to trigger my all code when arduino receives 1900us signal from channel 4. pulseIn will not hold the execution of rest of code for me.

If you are able to send a 1900 us pulse, why is max_high_time set to 1895?

Which channel is the 1900us pulse going to arrive on?

Of course pulseIn() BY ITSELF won't wait. YOU have to write code to end setup() when the appropriate length pulse arrives on the appropriate channel.

By the way, mixing interrupts and pulseIn() seems pointless. Which ONE do you want to use?

I said 1900us in rounded figures. and the purpose of mixing interrupts and pulseIn is to use all 6 channels. I am using Arduino Mega 2560 btw. which have 6 interrupts. 2 of 'em being used by MPU6050 as SDA and SCL pins.I am left with 4 interrupts, which I am using for 4 channels. Rest of 2 channels are being read by PulseIn which I will use for triggering my camera module or something like that. Right now I just want to make arduino wait until it receives a high pulse on particular channel. I want to do it by internal interrupts if it is possible

What you describe does not sound hard but maybe I have misunderstood.
Just stay in a while loop in setup() until the condition you are looking for occurs. Where is the problem ?

How do you intend to calibrate all 4 ESCs ?

I am calibrating my ESC with the short code I have written.

#include <Servo.h>

#define MAX_SIGNAL 2100
#define MIN_SIGNAL 900

#define esc1 5//front right
#define esc2 6//back right 
#define esc3 7//front left 
#define esc4 8//back left

Servo firstESC,secESC,thirdESC,forthESC;

void setup() {
  Serial.begin(115200);
  Serial.println("Program begin...");
  Serial.println("This program will calibrate the ESC.");

  firstESC.attach(esc1);
  secESC.attach(esc2);
  thirdESC.attach(esc3);
  forthESC.attach(esc4);

  Serial.println("Now writing maximum output.");
  Serial.println("Turn on power source, then wait 2 seconds and press any key.");
  firstESC.writeMicroseconds(MAX_SIGNAL);
  secESC.writeMicroseconds(MAX_SIGNAL);
  thirdESC.writeMicroseconds(MAX_SIGNAL);
  forthESC.writeMicroseconds(MAX_SIGNAL);

  // Wait for input
  while (!Serial.available());
  Serial.read();

  // Send min output
  Serial.println("Sending minimum output");
  firstESC.writeMicroseconds(MIN_SIGNAL);
  secESC.writeMicroseconds(MIN_SIGNAL);
  thirdESC.writeMicroseconds(MIN_SIGNAL);
  forthESC.writeMicroseconds(MIN_SIGNAL);

}

void loop() {  

}

Yes its not that difficult as you said but I am unable to find proper logic for that condition.
Talking about while loop, according to my understandings, it keeps executing a code inside it until a specific condition is not true. I want to run this code when I press the button from my transmitter or you can say when arduino receives a signal of 1895us on channel 4. I want to run my code for once.

Talking about while loop, according to my understandings, it keeps executing a code inside it until a specific condition is not true.

Or until the specified condition is true. So, what IS the condition that should cause the while loop to end?

while(someValue < someThreshold)
{
   // Do nothing but check again

   someValue = ???;
}

This code would spin while someValue, however it is defined, is less than someThreshold (presumably 1900 in your case). Each time through the loop, it will get a new value for someValue, by whatever method you define.

When the while loop ends, because someValue is greater than, or equal, someThreshold, calibrate the ESC and then let setup() end, so loop() can begin.

thankyou PaulS for your help.
I have made a logic something like that and it really works. :slight_smile:

 while (CH4_delta < 1800)
   {
     //do nothing
     Serial.println("Waiting...");
   }

the mistake I have been making was

 while (CH4_delta > 1800)

Thanks again PaulS. you are awesome!