Error compiling for board Arduino/Genuino Uno

I copied the code to read multiple RC receiver channels from the link below

The programmer does mention that it was reconfigured to run on a Leonardo board because it has more interrupt pins than a Uno. I only need to read 2 channels. I made two modifications. First I changed the interrupt pins from 8 & 9 to 2 & 3. I also commented out any line that was referencing the third, AUX, channel.

When I compile the code I get this error “Error compiling for board Arduino/Genuino Uno” I’m not sure what tells it that it’s not a Uno or what to change so that it will run on a Uno. Which is currently the only Arduino I have to play with.

I’ve attached the code and thanks for all help

John

Multiple_Channels.ino (6.98 KB)

(deleted)

Right you are spycatcher, I didn't realize that I could scroll that message. As it turns out I am missing a library that the sketch needs to run. The library name is PinChangeInt.h. The author says that one of the links in the code will get me to that but I haven't found it yet. I'll keep looking.

Thanks for pointing the way John

Since you are using pins 2 and 3 (external interrupts) there is really no need for pin change interrupts (unless you plan to add channels).

Try commenting the #include <PinChangeInt.h>

Change

 PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE); 
  PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE);

To

 attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE); 
  attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE);

Or follow this link to get the library and instructions on installation.

OK groundfungus, commenting out the #include<PinChangeInt.h> line and removing PCintPort worked. I can now compile it. If I didn’t leave my receiver cable at home I could test it, boss isn’t here today.

I did find the link to the library you sent. I downloaded the zip file. In the directions it states to import the library. I didn’t see Import in “Sketch/Include Library” but there is a “Add .ZIP Library” So I used that to load in the ZIP file I had just downloaded. The Library now shows in my list but instead of being named PinChangeint.h it shows as PinChangeInterrupt.h. I assumed this was the new and improved version that’s mention in the link. So I included it and commented out the #include<PinChangeInt.h> line.

Now I get another error that says that PCintPort not declared and that one of the functions calcThrottle is also not declared. I do find the function but not PCintPort. Should that have been declared in the library?

This is a bit beyond me as far as some of this code but I’m trying to understand how all this works.
Thanks for your help
John

Post the code as it is now and the the full text of the error(s), please.

And before you do please read the "how to use the forum" stickies to see how to format and post code and error messages.

Look at the example code in the library to see the usage of PCintPort.

OK, lets see if this works. Let me know if I did this correctly. I had to break this up into 2 post, it exceeded the limit

here's the error

Arduino: 1.6.12 (Windows 7), Board: "Arduino/Genuino Uno"

\\usbosf01\home$\usbosjola\Arduino\Multiple_Channels _Mod\Multiple_Channels_Mod\Multiple_Channels_Mod.ino: In function 'void setup()':

Multiple_Channels_Mod:83: error: 'PCintPort' has not been declared

   PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE); 

   ^

Multiple_Channels_Mod:83: error: 'calcThrottle' was not declared in this scope

   PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE); 

                                               ^

Multiple_Channels_Mod:84: error: 'PCintPort' has not been declared

   PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE); 

   ^

Multiple_Channels_Mod:84: error: 'calcSteering' was not declared in this scope

   PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE); 

                                               ^

\\usbosf01\home$\usbosjola\Arduino\Multiple_Channels _Mod\Multiple_Channels_Mod\Multiple_Channels_Mod.ino: In function 'void loop()':

Multiple_Channels_Mod:183: error: a function-definition is not allowed here before '{' token

 {

 ^

Multiple_Channels_Mod:210: error: expected '}' at end of input

 }

 ^

exit status 1
'PCintPort' has not been declared

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Sorry, I had to wait 5 minutes before sending the second post. Here’s the code

#include <PinChangeInterrupt.h>
#include <PinChangeInterruptBoards.h>
#include <PinChangeInterruptPins.h>
#include <PinChangeInterruptSettings.h>

// MultiChannels
//
// rcarduino.blogspot.com
//
// A simple approach for reading three RC Channels using pin change interrupts
//
// See related posts - 
// http://rcarduino.blogspot.co.uk/2012/01/how-to-read-rc-receiver-with.html
// http://rcarduino.blogspot.co.uk/2012/03/need-more-interrupts-to-read-more.html
// http://rcarduino.blogspot.co.uk/2012/01/can-i-control-more-than-x-servos-with.html
//
// rcarduino.blogspot.com
//

// include the pinchangeint library - see the links in the related topics section above for details
// #include <PinChangeInt.h>

#include <Servo.h>

// Assign your channel in pins
#define THROTTLE_IN_PIN 2 // was 8
#define STEERING_IN_PIN 3 // was 9
// #define AUX_IN_PIN 10

// Assign your channel out pins
#define THROTTLE_OUT_PIN 5
#define STEERING_OUT_PIN 6
// #define AUX_OUT_PIN 7

// Servo objects generate the signals expected by Electronic Speed Controllers and Servos
// We will use the objects to output the signals we read in
// this example code provides a straight pass through of the signal with no custom processing
Servo servoThrottle;
Servo servoSteering;
// Servo servoAux;

// These bit flags are set in bUpdateFlagsShared to indicate which
// channels have new signals
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
// #define AUX_FLAG 4

// holds the update flags defined above
volatile uint8_t bUpdateFlagsShared;

// shared variables are updated by the ISR and read by loop.
// In loop we immediatley take local copies so that the ISR can keep ownership of the 
// shared ones. To access these in loop
// we first turn interrupts off with noInterrupts
// we take a copy to use in loop and the turn interrupts back on
// as quickly as possible, this ensures that we are always able to receive new signals
volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
// volatile uint16_t unAuxInShared;

// These are used to record the rising edge of a pulse in the calcInput functions
// They do not need to be volatile as they are only used in the ISR. If we wanted
// to refer to these in loop and the ISR then they would need to be declared volatile
uint32_t ulThrottleStart;
uint32_t ulSteeringStart;
// uint32_t ulAuxStart;

void setup()
{
  Serial.begin(9600);
  
  Serial.println("multiChannels");

  // attach servo objects, these will generate the correct 
  // pulses for driving Electronic speed controllers, servos or other devices
  // designed to interface directly with RC Receivers  
  servoThrottle.attach(THROTTLE_OUT_PIN);
  servoSteering.attach(STEERING_OUT_PIN);
 // servoAux.attach(AUX_OUT_PIN);

  // using the PinChangeInt library, attach the interrupts
  // used to read the channels
  PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE); 
  PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE); 
//  PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE); 
}

void loop()
{
  // create local variables to hold a local copies of the channel inputs
  // these are declared static so that thier values will be retained 
  // between calls to loop.
  static uint16_t unThrottleIn;
  static uint16_t unSteeringIn;
 // static uint16_t unAuxIn;
  // local copy of update flags
  static uint8_t bUpdateFlags;

  // check shared update flags to see if any channels have a new signal
  if(bUpdateFlagsShared)
  {
    noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables

    // take a local copy of which channels were updated in case we need to use this in the rest of loop
    bUpdateFlags = bUpdateFlagsShared;
    
    // in the current code, the shared values are always populated
    // so we could copy them without testing the flags
    // however in the future this could change, so lets
    // only copy when the flags tell us we can.
    
    if(bUpdateFlags & THROTTLE_FLAG)
    {
      unThrottleIn = unThrottleInShared;
    }
    
    if(bUpdateFlags & STEERING_FLAG)
    {
      unSteeringIn = unSteeringInShared;
    }
    
 //   if(bUpdateFlags & AUX_FLAG)
 //   {
 //     unAuxIn = unAuxInShared;
 //   }
     
    // clear shared copy of updated flags as we have already taken the updates
    // we still have a local copy if we need to use it in bUpdateFlags
    bUpdateFlagsShared = 0;
    
    interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on
    // as soon as interrupts are back on, we can no longer use the shared copies, the interrupt
    // service routines own these and could update them at any time. During the update, the 
    // shared copies may contain junk. Luckily we have our local copies to work with :-)
  }
  
  // do any processing from here onwards
  // only use the local values unAuxIn, unThrottleIn and unSteeringIn, the shared
  // variables unAuxInShared, unThrottleInShared, unSteeringInShared are always owned by 
  // the interrupt routines and should not be used in loop
  
  // the following code provides simple pass through 
  // this is a good initial test, the Arduino will pass through
  // receiver input as if the Arduino is not there.
  // This should be used to confirm the circuit and power
  // before attempting any custom processing in a project.
  
  // we are checking to see if the channel value has changed, this is indicated  
  // by the flags. For the simple pass through we don't really need this check,
  // but for a more complex project where a new signal requires significant processing
  // this allows us to only calculate new values when we have new inputs, rather than
  // on every cycle.
  if(bUpdateFlags & THROTTLE_FLAG)
  {
    if(servoThrottle.readMicroseconds() != unThrottleIn)
    {
      servoThrottle.writeMicroseconds(unThrottleIn);
    }
  }
  
  if(bUpdateFlags & STEERING_FLAG)
  {
    if(servoSteering.readMicroseconds() != unSteeringIn)
    {
      servoSteering.writeMicroseconds(unSteeringIn);
    }
  }
  
/*  if(bUpdateFlags & AUX_FLAG)
  {
    if(servoAux.readMicroseconds() != unAuxIn)
    {
      servoAux.writeMicroseconds(unAuxIn);
    }
  }
  
  bUpdateFlags = 0;
}

*/
// simple interrupt service routine
void calcThrottle()
{
  // if the pin is high, its a rising edge of the signal pulse, so lets record its value
  if(digitalRead(THROTTLE_IN_PIN) == HIGH)
  { 
    ulThrottleStart = micros();
  }
  else
  {
    // else it must be a falling edge, so lets get the time and subtract the time of the rising edge
    // this gives use the time between the rising and falling edges i.e. the pulse duration.
    unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
    // use set the throttle flag to indicate that a new throttle signal has been received
    bUpdateFlagsShared |= THROTTLE_FLAG;
  }
}

void calcSteering()
{
  if(digitalRead(STEERING_IN_PIN) == HIGH)
  { 
    ulSteeringStart = micros();
  }
  else
  {
    unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);
    bUpdateFlagsShared |= STEERING_FLAG;
  }
}

/* void calcAux()
{
  if(digitalRead(AUX_IN_PIN) == HIGH)
  { 
    ulAuxStart = micros();
  }
  else
  {
    unAuxInShared = (uint16_t)(micros() - ulAuxStart);
    bUpdateFlagsShared |= AUX_FLAG;
  }
} */
Multiple_Channels_Mod:183: error: a function-definition is not allowed here before '{' token

 {

This is caused by a missing } to close the loop() function. That also affects the definition of the 2 ISR functions.

      servoSteering.writeMicroseconds(unSteeringIn);
    }
  }
}      // this } was missing

I followed the link in your code and downloaded the latest library (pinchangeint-v2.19beta.zip). I don't think we are looking at the same library.

Using the library downloaded from the link (see above), this code compiles with one warning (which I ignore for now) under IDE ver. 1.6.7.

#include <PinChangeInt.h>
//#include <PinChangeInterruptBoards.h>
//#include <PinChangeInterruptPins.h>
//#include <PinChangeInterruptSettings.h>

// MultiChannels
//
// rcarduino.blogspot.com
//
// A simple approach for reading three RC Channels using pin change interrupts
//
// See related posts -
// http://rcarduino.blogspot.co.uk/2012/01/how-to-read-rc-receiver-with.html
// http://rcarduino.blogspot.co.uk/2012/03/need-more-interrupts-to-read-more.html
// http://rcarduino.blogspot.co.uk/2012/01/can-i-control-more-than-x-servos-with.html
//
// rcarduino.blogspot.com
//

// include the pinchangeint library - see the links in the related topics section above for details
// #include <PinChangeInt.h>

#include <Servo.h>

// Assign your channel in pins
#define THROTTLE_IN_PIN 2 // was 8
#define STEERING_IN_PIN 3 // was 9
// #define AUX_IN_PIN 10

// Assign your channel out pins
#define THROTTLE_OUT_PIN 5
#define STEERING_OUT_PIN 6
// #define AUX_OUT_PIN 7

// Servo objects generate the signals expected by Electronic Speed Controllers and Servos
// We will use the objects to output the signals we read in
// this example code provides a straight pass through of the signal with no custom processing
Servo servoThrottle;
Servo servoSteering;
// Servo servoAux;

// These bit flags are set in bUpdateFlagsShared to indicate which
// channels have new signals
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
// #define AUX_FLAG 4

// holds the update flags defined above
volatile uint8_t bUpdateFlagsShared;

// shared variables are updated by the ISR and read by loop.
// In loop we immediatley take local copies so that the ISR can keep ownership of the
// shared ones. To access these in loop
// we first turn interrupts off with noInterrupts
// we take a copy to use in loop and the turn interrupts back on
// as quickly as possible, this ensures that we are always able to receive new signals
volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
// volatile uint16_t unAuxInShared;

// These are used to record the rising edge of a pulse in the calcInput functions
// They do not need to be volatile as they are only used in the ISR. If we wanted
// to refer to these in loop and the ISR then they would need to be declared volatile
uint32_t ulThrottleStart;
uint32_t ulSteeringStart;
// uint32_t ulAuxStart;

void setup()
{
  Serial.begin(9600);

  Serial.println("multiChannels");

  // attach servo objects, these will generate the correct
  // pulses for driving Electronic speed controllers, servos or other devices
  // designed to interface directly with RC Receivers
  servoThrottle.attach(THROTTLE_OUT_PIN);
  servoSteering.attach(STEERING_OUT_PIN);
  // servoAux.attach(AUX_OUT_PIN);

  // using the PinChangeInt library, attach the interrupts
  // used to read the channels
  PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle, CHANGE);
  PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering, CHANGE);
  //  PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE);
}

void loop()
{
  // create local variables to hold a local copies of the channel inputs
  // these are declared static so that thier values will be retained
  // between calls to loop.
  static uint16_t unThrottleIn;
  static uint16_t unSteeringIn;
  // static uint16_t unAuxIn;
  // local copy of update flags
  static uint8_t bUpdateFlags;

  // check shared update flags to see if any channels have a new signal
  if (bUpdateFlagsShared)
  {
    noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables

    // take a local copy of which channels were updated in case we need to use this in the rest of loop
    bUpdateFlags = bUpdateFlagsShared;

    // in the current code, the shared values are always populated
    // so we could copy them without testing the flags
    // however in the future this could change, so lets
    // only copy when the flags tell us we can.

    if (bUpdateFlags & THROTTLE_FLAG)
    {
      unThrottleIn = unThrottleInShared;
    }

    if (bUpdateFlags & STEERING_FLAG)
    {
      unSteeringIn = unSteeringInShared;
    }

    //   if(bUpdateFlags & AUX_FLAG)
    //   {
    //     unAuxIn = unAuxInShared;
    //   }

    // clear shared copy of updated flags as we have already taken the updates
    // we still have a local copy if we need to use it in bUpdateFlags
    bUpdateFlagsShared = 0;

    interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on
    // as soon as interrupts are back on, we can no longer use the shared copies, the interrupt
    // service routines own these and could update them at any time. During the update, the
    // shared copies may contain junk. Luckily we have our local copies to work with :-)
  }

  // do any processing from here onwards
  // only use the local values unAuxIn, unThrottleIn and unSteeringIn, the shared
  // variables unAuxInShared, unThrottleInShared, unSteeringInShared are always owned by
  // the interrupt routines and should not be used in loop

  // the following code provides simple pass through
  // this is a good initial test, the Arduino will pass through
  // receiver input as if the Arduino is not there.
  // This should be used to confirm the circuit and power
  // before attempting any custom processing in a project.

  // we are checking to see if the channel value has changed, this is indicated
  // by the flags. For the simple pass through we don't really need this check,
  // but for a more complex project where a new signal requires significant processing
  // this allows us to only calculate new values when we have new inputs, rather than
  // on every cycle.
  if (bUpdateFlags & THROTTLE_FLAG)
  {
    if (servoThrottle.readMicroseconds() != unThrottleIn)
    {
      servoThrottle.writeMicroseconds(unThrottleIn);
    }
  }

  if (bUpdateFlags & STEERING_FLAG)
  {
    if (servoSteering.readMicroseconds() != unSteeringIn)
    {
      servoSteering.writeMicroseconds(unSteeringIn);
    }
  }
}
/*  if(bUpdateFlags & AUX_FLAG)
  {
    if(servoAux.readMicroseconds() != unAuxIn)
    {
      servoAux.writeMicroseconds(unAuxIn);
    }
  }

  bUpdateFlags = 0;
  }

*/
// simple interrupt service routine
void calcThrottle()
{
  // if the pin is high, its a rising edge of the signal pulse, so lets record its value
  if (digitalRead(THROTTLE_IN_PIN) == HIGH)
  {
    ulThrottleStart = micros();
  }
  else
  {
    // else it must be a falling edge, so lets get the time and subtract the time of the rising edge
    // this gives use the time between the rising and falling edges i.e. the pulse duration.
    unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
    // use set the throttle flag to indicate that a new throttle signal has been received
    bUpdateFlagsShared |= THROTTLE_FLAG;
  }
}

void calcSteering()
{
  if (digitalRead(STEERING_IN_PIN) == HIGH)
  {
    ulSteeringStart = micros();
  }
  else
  {
    unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);
    bUpdateFlagsShared |= STEERING_FLAG;
  }
}

/* void calcAux()
  {
  if(digitalRead(AUX_IN_PIN) == HIGH)
  {
    ulAuxStart = micros();
  }
  else
  {
    unAuxInShared = (uint16_t)(micros() - ulAuxStart);
    bUpdateFlagsShared |= AUX_FLAG;
  }
  } */

You were right, again. I was not downloading the correct file. After I went to the link there is a notice that he had moved the project to GitHub, I went there and downloaded the zip file, the wrong one. I did find the file you referenced.

Maybe I’m loading it in wrong but I copied the zip file, I think the right one this time, to the library folder in Arduino. Then in my sketch I go to Sketch/Include Library/Add .ZIP File. I drill to the zip file but I get a error saying this

Arduino: 1.6.12 (Windows 7), Board: "Arduino/Genuino Uno"

Specified folder/zip file does not contain a valid library

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I’ve also attached the zip file

Do I select the actual zip file?

Thank you so much for your help and patience
John

pinchangeint-v2.19beta.zip (43.5 KB)

Sorry, I am used to just copying libraries to my libraries folder. I don't use the installer in the newer IDE versions. Go into your library folder and remove the old pin change interrupt library ( or cut and paste somewhere if you want to save it) and the zip file. Close any copy of the IDE that may be running. Go into to the zip file and copy the pinChangeInt folder and paste it into your libraries folder. The IDE should see and include it.

Bingo, there it is! I think with me messing around with the code I created some of my own errors. So I deleted the whole thing, went back to the website where I got it to begin with and made a fresh copy. Now with the PinChangeInt library it complied just fine.

Now I have to do my homework and try to understand everything that's going on in here. It's one thing to copy someone else's code, make a couple of tweaks and use it, but I like to understand what it's doing as well.

This has been a great learning experience for me, I really appreciate you helping me out.

Thanks again John