Arduino Code Troubleshooting - VEX Transmitter / Receiver

I'm trying to read the signals sent from the VEX transmitter to the VEX receiver through my Arduino Mega. I started with this code and then made some modifications to visualize the outputs.

1) The issue I'm having is that the LED keeps flashing randomly in every position of the joystick (default, moving upwards, or moving downwards). There is a delay at the beginning of the code that seems to affect how fast the LED will blink (still random, but quicker if the delay is smaller). Some sources recommend to use a 10K pull-up, other say 22K. I'm running a 100K potentiometer, but changing it doesn't seem to affect the blinking (unless it is at 0Ω).

2) I'm also trying to map the input of the controller to a range usable to do the analog.Write (PWM) to the LED, but the transmitter range and the analog.Write range are different and the map() function does not work with decimal numbers. Any suggestions as to how can I do the mapping better?

Thanks,

Erick

PS: Below is what I'm currently running on the Arduino and a video of the random flashing issue.

/*

 * Arduino sketch to test communicating with the

 * Vex Robotics receiver.

 * 

 * Pinout (from Vex Receiver to Arduino):

 *   * Vcc -> 5v

 *   * Gnd -> Gnd

 *   * Signal -> Pin2 (Interrupt 0)

 *   * [unknown]

 * 

 * (Pin order on Vex Receiver is right to left

 * when looking at front of connector.)

 * 

 * I also added a 4.1k resistor from Vcc to Signal.

 *

 * Author: Joseph Monti <[email protected]>

 * Copyright Joseph Monti 2013

 */

 

const int INT_NUM = 0;

 

const int NUM_CHANNELS = 6;

const int MIN_IN_PULSE_WIDTH = 750;

const int MAX_IN_PULSE_WIDTH = 2250;

const int SYNC_GAP_LEN = 3000;

const int INITIALIZE_CYCLES = 5;

 

const int STATE_PENDING = 0;

const int STATE_INITIALIZING = 1;

const int STATE_READY = 2;

 

volatile unsigned long last_micros;

volatile int initializedCount;

volatile int state;

volatile int channel;

volatile int pulses[NUM_CHANNELS];

 

const long DEBUG_DELAY = 50;

long nextDebug;

 

int ledPin = 11;

 

void setup( ) {

  Serial.begin(19200);

 

  last_micros = micros();

  initializedCount = 0;

  state = STATE_PENDING;

  channel = 0;

 

  attachInterrupt( INT_NUM, receiver_interrupt, RISING );

 

  nextDebug = millis();

}

 

void loop() {

  if ( millis() >= nextDebug ) {

    switch ( state ) {

      case STATE_PENDING:

        Serial.print("PENDING: ");

        break;

      case STATE_INITIALIZING:

        Serial.print("INITING: ");

        break;

      case STATE_READY:

        Serial.print("READY:   ");

        break;

      default:

        Serial.print("UNKNOWN: ");

        break;

    }

    for ( int i = 0; i < NUM_CHANNELS; i++ ) {

      Serial.print( getValue( i ) );

      Serial.print( "  " );

    }

 

    Serial.println();

 

    if( pulses[2] <=0 ) {

      digitalWrite(ledPin,LOW); //in the middle (default) position or below, the LED should be OFF (LOW) 

    }

    else {

      analogWrite(ledPin,pulses[2]); //if the joystick is move upwards, then the LED brightess will vary according to the VEX transmitter input

    }

    nextDebug = millis() + DEBUG_DELAY;

  }

}

 

void receiver_interrupt( ) {

  unsigned long current_micros = micros();

  unsigned long gap = current_micros - last_micros;

 

  if ( gap >= SYNC_GAP_LEN ) {

    if ( state == STATE_READY ) {

      if ( channel != NUM_CHANNELS ) {

        state = STATE_INITIALIZING;

      }

    } else if ( state == STATE_INITIALIZING ) {

      initializedCount++;

      if ( initializedCount >= INITIALIZE_CYCLES ) {

        state = STATE_READY;

      }

    } else {

      state = STATE_INITIALIZING;

      initializedCount = 0;

    }

    channel = 0;

  } else if ( channel < NUM_CHANNELS ) {

    if ( gap >= MIN_IN_PULSE_WIDTH && gap <= MAX_IN_PULSE_WIDTH ) {

      pulses[channel] = gap;

      channel++;

    } else if ( state == STATE_READY ) {

      state = STATE_INITIALIZING;

      channel = 0;

    }

  }

 

  last_micros = current_micros;

}

 

int getState() { 

  return state;

}

 

int getValue( int c ) {

  if ( state == STATE_READY ) {

    //return (pulses[c]);

    pulses[c]=map(pulses[c],1096,1940,-255,220); //trying to map the transmitter input to the analog output of the LED on pin 11

    return (pulses[c]);

  } else {

    return -1;

  }

}

https://www.youtube.com/watch?v=f5eCi0UXbrw

Just a quick scan of your code.

I have not yet used interrupts, but, everything I have heard/read says the interrupt routine should be as minimal as possible. Your interrupt routine is “massive”. You might be missing interrupts by doing so much calculating inside the interrupt.

Off Topic:
I would move a bit of your code around with respect to the getValue().

 int getValue( int c ) {
  if ( state == STATE_READY ) {
    //return (pulses[c]);
    pulses[c]=map(pulses[c],1096,1940,-255,220); //trying to map the transmitter input to the analog output of the LED on pin 11
    return (pulses[c]);
  } else {
    return -1;
  }
}

would get rewritten to:

int getValue( int c ) {
  pulses[c]=map(pulses[c], 1096, 1940, -255, 220);
  return (pulses[c]);
}

and, I would move the if statement to:

if ( state == STATE_READY ) {
  for (int i = 0; i < NUM_CHANNELS; i++) {
    Serial.print( getValue(i));
    Serial.print(" ");
  }
}

Mind you. This is all just my opinion. 

Interrupts / Changes

1) Almost everything in the code was done by someone else, I just added some basic stuff to do some testing. Since the original author was kind enough to share his code, I though I would be better off starting from that since my programming knowledge is pretty basic. I will read/search more info about your suggestion regarding the interrupts. Thanks.

2) Why would you change the code? What difference does it make to do the <if> in the void loop() versus doing it in the function? 

Re: code placement

It boils down to my anal retentive nature based on “best” programming practices, and, you don’t see a bunch of “garbage” -1’s showing up when the state != ready.