Constrain and Map not working?

Hi guys, I've got this simple program that reads a PPM signal from a single channel on a RC receiver and "should" return a value from 0 to 511. The logic seems to work and I am getting a value proportional to the RC transmitter inputs. But the constrain and or map functions are giving me odd results.

Basically it looks for a high pulse and once it finds one it returns the duration in microseconds. The extremes (for int RXSG) are about 910 and 2085. So I'm constraining it to between 1000 and 2000, and then mapping that from 0 to 511.

But I'm getting a range form -47 to like 560. Is it because RXSG is a volatile int? BTW does it even need to be a volatile variable?

Any help is appreciated. Thanks -Tony

BTW, I didn't write this code, I just modified it a fair bit for my purposes.

//Reads PPM signals from one channel out of a RX reciever

int RXCH = 4; //pin 4
volatile int RXSG = 0;
int RXOK = 0;
int PWMSG = 0;

void setup() {
  //Start communication to serial port
  Serial.begin(115200);
  pinMode(RXCH, INPUT); // pin 4 is an input
}

void loop() {
  RXSG = pulseIn(RXCH, HIGH, 50000);                   //read the receiver signal
  if (RXSG == 0) {RXSG = RXOK;} else {RXOK = RXSG;}    //if the signal is good then use it, else use the previous signal
  
    
  constrain (RXSG, 1000, 2000);                           //make sure that the value stays within the disired boundries
  PWMSG = map(RXSG, 1000, 2000, 0, 511);               //substitute the high values to a value between 0 and 511
  
 // Print RX values
  Serial.print(" ||   Pin: ");
  Serial.print(RXCH);
  Serial.print(" / PWMSG: ");
  Serial.print(PWMSG);  // print the value
  Serial.println();
  delay(100);
}

Hi,

RacerX89:
Is it because RXSG is a volatile int? BTW does it even need to be a volatile variable?

No. No.

RXSG = constrain (RXSG, 1000, 2000); //make sure that the value stays within the disired boundries

facepalm

DOH! I'm an idiot. Thanks

Hi, You could just drop the pulsein and use interrupts, there are around 10 posts on my blog from reading a single channel -

http://rcarduino.blogspot.com/2012/01/how-to-read-rc-receiver-with.html

to reading multiple channels -

http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html

to a full RC Robot with code -

http://rcarduino.blogspot.com/2012/05/rc-arduino-robot.html

http://rcarduino.blogspot.com/2012/05/interfacing-rc-channels-to-l293d-motor.html

Duane B

rcarduino.blogspot.com

DuaneB: Hi, You could just drop the pulsein and use interrupts, there are around 10 posts on my blog from reading a single channel -

http://rcarduino.blogspot.com/2012/01/how-to-read-rc-receiver-with.html

to reading multiple channels -

http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html

to a full RC Robot with code -

http://rcarduino.blogspot.com/2012/05/rc-arduino-robot.html

http://rcarduino.blogspot.com/2012/05/interfacing-rc-channels-to-l293d-motor.html

Duane B

rcarduino.blogspot.com

Cheers mate!!! Your first example code worked perfectly! I only skimmed it briefly but I think I understand it.

Yeah my next step would probably have been to try and utilize interrupts for this process.

I'm gutting an old FM RC radio I have to wirelessly control a stepper motor that will adjust the manual zoom dial on a Canon 7D DSLR camera while it's mounted on a crane or glide cam. Since stepper motors can have a very high resolution (200 ticks per rotation) having the code not wait around for pulsein may make the movement of the motor smoother and faster. My plan is to map the resolution of the PPM signal to the number of ticks required for however many turns of the motor I need, and use some simple logic to move the motor in the appropriate direction while the two values are different and stop once they are the same.

It shouldn't be too difficult. Thanks again!!!

-Tony