Servos, Sketches, remote control, libraries

This is the sketch I've been working on: (unsuccessfully)

#include <IRLibAll.h>
    #include <Servo.h> 
    #define MY_PROTOCOL NEC
    #define RIGHT_ARROW   0xffaa5 //Move 135 clockwise
    #define LEFT_ARROW    0xff10ef //Move 45 counterclockwise
    #define SELECT_BUTTON 0xff38c7 //Center the servo at 90
    #define UP_ARROW      0xff18e7 //Move 90 counterclockwise
    #define DOWN_ARROW    0xff4ab5 //Move 90 cockwise
    IRrecv myReceiver(2); //pin number for the receiver
    IRdecode myDecoder;
     
    Servo myServo;  // create servo object to control a servo 
    
int16_t pos;         // variable to store the servo position
uint32_t Previous;//handles NEC repeat codes

void setup() {
  // put your setup code here, to run once:
myServo.attach(9);      // attaches the servo on pin 9 to the servo object 
      pos = 90;               // start at midpoint 90 degrees
      myServo.write(pos);     // Set initial position
      myReceiver.enableIRIn(); // Start the receiver
}

void loop() {
  // put your main code here, to run repeatedly:
  if (myReceiver.getResults()) {
           myDecoder.decode();
           if(myDecoder.protocolNum==MY_PROTOCOL) {
             if(myDecoder.value==0xFFFFFFFF)
               myDecoder.value=Previous;
               switch(myDecoder.value) {
                case LEFT_ARROW:    pos=45; break;
                case RIGHT_ARROW:   pos=135; break;
                case SELECT_BUTTON: pos=90; break;
                case UP_ARROW:      pos=0; break;
                case DOWN_ARROW:    pos=180; break;

}
  myServo.write(pos); // tell servo to go to position in variable 'pos' 
             Previous=myDecoder.value;
           }
           myReceiver.enableIRIn();
        }
}

to re-cap; I'm new to remote control and having trouble with this.

See the two attachments.(or pics above)

I'm trying to get the IR receiver to work with the hex codes I got off the serial monitor.

This is meant to be a STANDALONE unit.

The above sketch looks like it would work - but it doesn't.

The sevo works, the Arduino works, the IR receiver works AND the transmitter.

I am just trying to get the servo to move with 5 buttons on the transmitter. Center, right 45 degrees, right 90 degrees, left 45 degrees and left 90 degrees.

The way it stands right now, the sketch verifies and compiles, and it uploads to the UNO board with no errors.

But then when you push a button on the transmitter, the servo moves a few degrees, and that's it, nothing else except a low hum.

It was suggested I hook it back up via USB and then see what I get on the serial monitor, I did, pushing buttons got nothing at all.

It was also suggested I try the ServoTimer2 library. (conflicts with the timers?)
I got that and then installed it successfully.
Here it is:

   #include <ServoTimer2.h> 
    #define MY_PROTOCOL NEC
    #define RIGHT_ARROW   0xffaa5 //Move 135 clockwise
    #define LEFT_ARROW    0xff10ef //Move 45 counterclockwise
    #define SELECT_BUTTON 0xff38c7 //Center the servo at 90
    #define UP_ARROW      0xff18e7 //Move 90 counterclockwise
    #define DOWN_ARROW    0xff4ab5 //Move 90 cockwise
    IRrecv myReceiver(2); //pin number for the receiver
    IRdecode myDecoder;
     
    Servo myServo;  // create servo object to control a servo 
    
int16_t pos;         // variable to store the servo position
uint32_t Previous;//handles NEC repeat codes

void setup() {
  // put your setup code here, to run once:
myServo.attach(9);      // attaches the servo on pin 9 to the servo object 
      pos = 90;               // start at midpoint 90 degrees
      myServo.write(pos);     // Set initial position
      myReceiver.enableIRIn(); // Start the receiver
}

void loop() {
  // put your main code here, to run repeatedly:
  if (myReceiver.getResults()) {
           myDecoder.decode();
           if(myDecoder.protocolNum==MY_PROTOCOL) {
             if(myDecoder.value==0xFFFFFFFF)
               myDecoder.value=Previous;
               switch(myDecoder.value) {
                case LEFT_ARROW:    pos=45; break;
                case RIGHT_ARROW:   pos=135; break;
                case SELECT_BUTTON: pos=90; break;
                case UP_ARROW:      pos=0; break;
                case DOWN_ARROW:    pos=180; break;

}
  myServo.write(pos); // tell servo to go to position in variable 'pos' 
             Previous=myDecoder.value;
           }
           myReceiver.enableIRIn();
        }
}

Not quite sure how to change the code to accomodate that. Take the 2 existing libraries out of the sketch, and put in the new one? That's what I did (see above)
Otherwise I left the sketch alone, just the ServoTimer2 at the top of the code.

However this time, it did not verify and compile.

I got --- 'IR receiver does not name a type' error

Servo myServo;

doesn't do that?

This is turning out to be a game of "Stump the Band", er programmers.
I have a feeling if I had tried to upload the sketch to the board, I would have gotten even more errors.

The ServoTimer2 seems to be realtively new - not much info on it. If that is even the reason why this doesn't work.

Any more ideas?

here is the other attachement

The text in your Original Post is an unreadable jumble of ideas. See how much easier it is with a bit of white-space between the ideas.

to re-cap; I'm new to remote control and having trouble with this.

See the two attachments.

I'm trying to get the IR receiver to work with the hex codes I got off the serial monitor.
This is meant to be a STANDALONE unit.

The above sketch looks like it would work - but it doesn't.

The sevo works, the Arduino works, the IR receiver works AND the transmitter.

I am just trying to get the servo to move with 5 buttons on the transmitter. Center, right 45 degrees, right 90 degrees, left 45 degrees and left 90 degrees.

The way it stands right now, the sketch verifies and compiles, and it uploads to the UNO board with no errors.

But then when you push a button on the transmitter, the servo moves a few degrees, and that's it, nothing else except a low hum.

It was suggested I hook it back up via USB and then see what I get on the serial monitor, I did, pushing buttons got nothing at all.

It was also suggested I try the ServoTimer2 library. (conflicts with the timers?)
I got that and then installed it successfully.
Not quite sure how to change the code to accomodate that. Take the 2 existing libraries out of the sketch, and put in the new one? I tried that.

Otherwise I left the sketch alone, just the ServoTimer2 at the top of the code.
However this time, it did not verify and compile.
I got --- 'IR receiver does not name a type' tghe line
Servo myServo;
doesn't do that?

This is turning out to be a game of "Stump the Band", er programmers.

I have a feeling if I had tried to upload the sketch to the board, I would have gotten even more errors. The ServoTimer2 seems to be realtively new - not much info on it. If that is even the reason why this doesn't work.

Any more ideas?

ALSO... Please display your image(s) in your post(s) so we can see it(them) without downloading it(them). See this Simple Image Guide

...R

You have posted one short program which, you say, compiles but does not move the servo correctly.

You say you have another program with the ServoTimer2 library - but you have not posted that, so how can we know what you did.

Also, you mention previous advice - if you have had another Thread in this Forum please post a link to it so we don't repeat advice you have already been given.

...R

The previous thread just disappeared; so I put this one up - same problem.

ardnew21:
The previous thread just disappeared; so I put this one up - same problem.

Do you mean this one ?

Earlier I went to considerable trouble to edit your Original Post to make it readable and you then screwed up the chronology by replacing the original text with my text so that my comment seemed pointless

Now you have completely screwed up the chronology by replacing the whole of your modified Original Post with some other stuff. New material should ALWAYS go in a new Reply so we can read the Thread from top to bottom and so we don't have to re-read older posts.

If you want more help from me please reinstate the Original Post to how it was yesterday and put all that new stuff in your next Reply.

...R

ardnew21:
Not quite sure how to change the code to accomodate that. Take the 2 existing libraries out of the sketch, and put in the new one? That's what I did (see above)
Otherwise I left the sketch alone, just the ServoTimer2 at the top of the code.

However this time, it did not verify and compile.

I got --- 'IR receiver does not name a type' error

Why would you take out the IRLib2 library because you want to replace one Servo library with another?!? That is why "IRrecv" does not name a type. PUT THE IRLibAll LIBRARY BACK IN.

ardnew21:
I am just trying to get the servo to move with 5 buttons on the transmitter. Center, right 45 degrees, right 90 degrees, left 45 degrees and left 90 degrees.

The way it stands right now, the sketch verifies and compiles, and it uploads to the UNO board with no errors.

But then when you push a button on the transmitter, the servo moves a few degrees, and that's it, nothing else except a low hum.

Any more ideas?

If you upload File->Examples->Servo->Sweep without changing any of your hardware, does the servo sweep back and forth 180 degrees? If not, you have a hardware problem and no amount of poking at the sketch will fix it.

ardnew21:
This is the sketch I’ve been working on: (unsuccessfully)

#include <IRLibAll.h>

#include <Servo.h>
   #define MY_PROTOCOL NEC
   
void loop() {
 // put your main code here, to run repeatedly:
 if (myReceiver.getResults()) {
          myDecoder.decode();
          if(myDecoder.protocolNum==MY_PROTOCOL) {
            if(myDecoder.value==0xFFFFFFFF)
              myDecoder.value=Previous;
              switch(myDecoder.value) {




Any more ideas?

I think there may be a problem because you ignore the result from myDecoder.decode(). The example sketch ‘servo’ from the IRLib2 library doesn’t interpret the result if the decode fails. You may be setting the servo position hundreds of times per second.
‘servo’ sketch:

/* servo.ino Example sketch for IRLib2
 *  Illustrate how to now to control a servo using IR signals.
 */
#include <IRLibDecodeBase.h> // First include the decode base
#include <IRLib_P02_Sony.h>  // Include only the protocol you are using


IRdecodeSony myDecoder; // Now declare an instance of that decoder.


#include <Servo.h> 
/* Note: Servo library uses TIMER1. The default timer for IRLibRecv 
 *  on Arduino Uno is TIMER2 so there is no conflict. However a 
 *  default timer on Arduino Leonardo is TIMER1 so you Have the choice 
 *  of either will have to switch to IRLibRecvPCI or IRLibRecvLoop
 *  to avoid the conflict. Alternatively you can modify the timer used 
 *  to use TIMER3 or TIMER4 as specified in IRLibHardware.h. Also you 
 *  will need to modify the input being used.
 */


#include <IRLibRecv.h> 
IRrecv myReceiver(2); //pin number for the receiver


Servo myServo;  // create servo object to control a servo 
int16_t pos;         // variable to store the servo position 
int16_t speed;       // Number of degrees to move each time a left/right button is pressed
 
void setup() { 
  myServo.attach(9);      // attaches the servo on pin 9 to the servo object 
  pos = 90;               // start at midpoint 90 degrees
  speed = 3;              // servo moves 3 degrees each time left/right is pushed
  myServo.write(pos);     // Set initial position
  myReceiver.enableIRIn(); // Start the receiver
} 
 
// You will have to set these values depending on the protocol
// and remote codes that you are using. These are from my Sony DVD/VCR
#define MYPROTOCOL SONY
#define RIGHT_ARROW   0x86bca //Move several clockwise
#define LEFT_ARROW    0x46bca //Move servo counterclockwise
#define SELECT_BUTTON 0xd0bca //Center the servo
#define UP_ARROW      0x42bca //Increased number of degrees servo moves
#define DOWN_ARROW    0xc2bca //Decrease number of degrees servo moves
#define BUTTON_0 0x90bca  //Pushing buttons 0-9 moves to fix positions
#define BUTTON_1 0x00bca  // each 20 degrees greater
#define BUTTON_2 0x80bca
#define BUTTON_3 0x40bca
#define BUTTON_4 0xc0bca
#define BUTTON_5 0x20bca
#define BUTTON_6 0xa0bca
#define BUTTON_7 0x60bca
#define BUTTON_8 0xe0bca
#define BUTTON_9 0x10bca


void loop() { 
  if (myReceiver.getResults()) {
    if(myDecoder.decode()) {
      switch(myDecoder.value) {
        case LEFT_ARROW:    pos=min(180,pos+speed); break;
        case RIGHT_ARROW:   pos=max(0,pos-speed); break;
        case SELECT_BUTTON: pos=90; break;
        case UP_ARROW:      speed=min(10, speed+1); break;
        case DOWN_ARROW:    speed=max(1, speed-1); break;
        case BUTTON_0:      pos=0*20; break;
        case BUTTON_1:      pos=1*20; break;
        case BUTTON_2:      pos=2*20; break;
        case BUTTON_3:      pos=3*20; break;
        case BUTTON_4:      pos=4*20; break;
        case BUTTON_5:      pos=5*20; break;
        case BUTTON_6:      pos=6*20; break;
        case BUTTON_7:      pos=7*20; break;
        case BUTTON_8:      pos=8*20; break;
        case BUTTON_9:      pos=9*20; break;
      }
      myServo.write(pos); // tell servo to go to position in variable 'pos' 
    }
    myReceiver.enableIRIn();
  }
}

Of course you would change the includes to include the NEC protocol instead of Sony:

#include <IRLib_P01_NEC.h>

Thanks for your suggestions, I'll try the recent ones.
I had seen that example sketch, in fact I was working off of it.

'You may be setting the servo position hundreds of times per second.'

You think that might be the cause of the low 'mechanical hum' on the server (but the servo doesn't move')???

Note to Robin2 ----
So you think I should just re-do the whole thing and just make it a comparison between the 2 sketches (that might make it a lot more clear). along with the pics embeded in the post.

I was trying to please 3 different people all at the same time - so it got screwed up. I have no idea why the original post disappeared from my inbox (posts), but you were able to find it.

OK, I tried the little servo-sweep sketch, and the servo did just waht it was supposed to do. But I tried something similar 2 weeks ago, and the servo worked then too. So the hardware works. And to repeat, I got the hex codes using a sketch - and in that case, the IR receiver/transmitter did exactly what it was supposed to do too. Point the transmitter at the receiver, press buttons (light goes on), get a hex code with each button press, i.e. that works too.

Now, the servo.ino sketch (just as another test)

#include <IRLibDecodeBase.h> // First include the decode base
#include <IRLib_P01_NEC.h>  // Include only the protocol you are using
IRdecodeNEC myDecoder; // Now declare an instance of that decoder.
#include <Servo.h> 
#include <IRLibRecv.h>
IRrecv myReceiver(11); //pin number for the receiver

Servo myServo;  // create servo object to control a servo 
int16_t pos;         // variable to store the servo position 
int16_t speed;       // Number of degrees to move each time a left/right button is pressed

void setup() {
  // put your setup code here, to run once:
  myServo.attach(9);      // attaches the servo on pin 9 to the servo object 
  pos = 90;               // start at midpoint 90 degrees
  speed = 3;              // servo moves 3 degrees each time left/right is pushed
  myServo.write(pos);     // Set initial position
  myReceiver.enableIRIn(); // Start the receiver
  #define MYPROTOCOL NEC
#define RIGHT_ARROW   0xffaa5 //Move several clockwise
#define LEFT_ARROW    0xff10ef //Move servo counterclockwise
#define SELECT_BUTTON 0xff38c7 //Center the servo
#define UP_ARROW      0xff18e7 //Increased number of degrees servo moves
#define DOWN_ARROW    0xff4ab5 //Decrease number of degrees servo moves
} 


void loop() {
  // put your main code here, to run repeatedly:
 if (myReceiver.getResults()) {
    if(myDecoder.decode()) {
      switch(myDecoder.value) {
        case LEFT_ARROW:    pos=min(180,pos+speed); break;
        case RIGHT_ARROW:   pos=max(0,pos-speed); break;
        case SELECT_BUTTON: pos=90; break;
        case UP_ARROW:      speed=min(10, speed+1); break;
        case DOWN_ARROW:    speed=max(1, speed-1); break;
            myServo.write(pos); // tell servo to go to position in variable 'pos' 
    }
    myReceiver.enableIRIn();
  }
 }

}

Now the only thing different— I used only 5 buttons (which is what I’m after) and I used Pin 11 on the IR,
It verified and compiled, uploaded to the Uno.
But…
The result is slightly different, but it STILL does not work.
The servo arm moves about 3 degrees (by itself). but then just sits there, no mechanical hum this time, but a very slight constant shake. Pressing anyone of the 5 buttons on the transmitter causes the light on the receiver to go on (with each button press), but does nothing to the servo arm (no movement).
That is also what happens on what I was trying to do 2 days ago; so unless I miss my guess - have a very simialr problem with more than one sketch. ???

also, .

#include <Servo.h>
/* Note: Servo library uses TIMER1. The default timer for IRLibRecv

  • on Arduino Uno is TIMER2 so there is no conflict.

That says there is no conflict on the Uno as far as Timers go - is that right?

ardnew21:
#include <Servo.h>
/* Note: Servo library uses TIMER1. The default timer for IRLibRecv

  • on Arduino Uno is TIMER2 so there is no conflict.

That says there is no conflict on the Uno as far as Timers go - is that right?

I believe that is right.
I would be interested in seeing the results for your five buttons when you use the File->Examples->IRLib2->dump example. You should be able to copy and paste from the Serial Monitor window.

I'm not sure I can copy and paste from the serial monitor - doesn't seem to work (Linux vs. windows?) I'm using Linux.
But I double and triple checked the hex codes. Wrote them down.

How about if I place the 2 sketches together in another post/reply- might be easier to follow.

Like I said, I find it very odd that I get the exact same mechanical movement (shake) from the servo with each sketch (the shaking arm). Could it be that neither sketch addresses the 'speed' code lines??? The code hasn't got the correct speed settings?? Therefore the servo arm just 'shakes'. It's trying to move? but can't.

Note: Your key values are 20 bits long so you should make them unsigned long constants:

#define RIGHT_ARROW   0xffaa5UL //Move several clockwise
#define LEFT_ARROW    0xff10efUL //Move servo counterclockwise
#define SELECT_BUTTON 0xff38c7UL //Center the servo
#define UP_ARROW      0xff18e7UL //Increased number of degrees servo moves
#define DOWN_ARROW    0xff4ab5UL //Decrease number of degrees servo moves

OK, some progress??? At least got some movement by pushing the buttons on the remote transmitter.
Here’s the code (with your suggestion.

#include <Servo.h> 
#include <IRLibAll.h>
 #define MY_PROTOCOL NEC
    #define RIGHT_ARROW   0xffaa5UL //Move 135 clockwise
    #define LEFT_ARROW    0xff10efUL //Move 45 counterclockwise
    #define SELECT_BUTTON 0xff38c7UL //Center the servo at 90
    #define UP_ARROW      0xff18e7UL //Move 90 counterclockwise
    #define DOWN_ARROW    0xff4ab5UL //Move 90 cockwise
    IRrecv myReceiver(11); //pin number for the receiver
    IRdecode myDecoder;
     
    Servo myServo;  // create servo object to control a servo 
    
int16_t pos;         // variable to store the servo position
uint32_t Previous;//handles NEC repeat codes

void setup() {
  // put your setup code here, to run once:
myServo.attach(9);      // attaches the servo on pin 9 to the servo object 
      pos = 90;               // start at midpoint 90 degrees
      myServo.write(pos);     // Set initial position
      myReceiver.enableIRIn(); // Start the receiver
}
void loop() {
  // put your main code here, to run repeatedly:
    if (myReceiver.getResults()) {
           myDecoder.decode();
           if(myDecoder.protocolNum==MY_PROTOCOL) {
             if(myDecoder.value==0xFFFFFFFF)
               myDecoder.value=Previous;
               switch(myDecoder.value) {
                case LEFT_ARROW:    pos=45; break;
                case RIGHT_ARROW:   pos=135; break;
                case SELECT_BUTTON: pos=90; break;
                case UP_ARROW:      pos=0; break;
                case DOWN_ARROW:    pos=180; break;
}

  myServo.write(pos); // tell servo to go to position in variable 'pos' 
             Previous=myDecoder.value;
           }
           myReceiver.enableIRIn();
        }
}

Tried this on 2 identical servos - getting the same result on both.
What I get are completely random movements, i.e.WRONG.

for example, push the LEFT_Arrow button and instead of getting a 45 degree turn, get a 90 degree one. Push the OK (SELECT_BUTTON), and get a 90 degree turn.
Try maybe 10 button presses and you might get the right movement matched with the right button - but with only 5 buttons - random chance of getting a right movement.

Either way, trying to move a robot like this will not work.

!!!

I don't like the idea of forcing a different value into myDecoder.value because it's difficult to be certain when the IR thingy is going to change it back. It might be cleaner to use a separate variable like

             if(myDecoder.value==0xFFFFFFFF)
               currentVal = Previous;
             else 
                currentVal = myDecoder.value;
             switch(currentVal) {

Can't you also put a Serial.print() or two in to tell you exactly what codes you are actually seeing? From the sound of it these are not the same as the codes you think you are sending.

Steve

See reply #8. Your are STILL ignoring the value returned by "myDecoder.decode()".

I tried one more thing, making it just 3 buttons; like this:

#include <Servo.h> 
#include <IRLibAll.h>
#include <IRLibDecodeBase.h> // First include the decode base
#include <IRLib_P01_NEC.h>  // Include only the protocol you are using
#include <IRLibRecv.h>
 #define MY_PROTOCOL NEC

#define RIGHT_ARROW   0xffaa5UL //Move 180 clockwise
    #define LEFT_ARROW    0xff10efUL //Move 0 counterclockwise
    #define SELECT_BUTTON 0xff38c7UL //Center the servo at 90
    
 IRrecv myReceiver(11); //pin number for the receiver
    IRdecodeNEC myDecoder; // Now declare an instance of that decoder.
     
    Servo myServo;  // create servo object to control a servo 
    
int16_t pos;         // variable to store the servo position
uint32_t Previous;//handles NEC repeat codes


    
void setup() {
  // put your setup code here, to run once:
myServo.attach(9);      // attaches the servo on pin 9 to the servo object 
      pos = 90;               // start at midpoint 90 degrees
      myServo.write(pos);     // Set initial position
      myReceiver.enableIRIn(); // Start the receiver
}

void loop() {
  // put your main code here, to run repeatedly:
   if (myReceiver.getResults()) {
           myDecoder.decode();
           if(myDecoder.protocolNum==MY_PROTOCOL) {
             if(myDecoder.value==0xFFFFFFFF)
               myDecoder.value=Previous;
               switch(myDecoder.value) {
                case LEFT_ARROW:    pos=0; break;
                case RIGHT_ARROW:   pos=180; break;
                case SELECT_BUTTON: pos=90; break;
              
}
 myServo.write(pos); // tell servo to go to position in variable 'pos' 
             Previous=myDecoder.value;
           }
           myReceiver.enableIRIn();
        }
}

Nope, same thing - pretty unreliable.

So I think tis either the code or the cheapo IR transmitter/receiver.

Now, I just used this to see it work (it didn’t). I know I need something with more range anyway. This is maybe a meter or so. I’m going to need maybe 20 - 30 meters.

Anyone know of another alternative to my present IR transmitter/receiver???

RF modules? WiFi??? Please give me some examples.

I need something readilty available - no Amazon, adafruit, etc.

As to the code,

Anyone know of a python version of these sketches? Can they be found here on Arduino? Or somewhere else.
I know a little python, but c++ I used that maybe 10 years ago, don’t remember it.

And your are STILL still ignoring the returned value of myDecoder.decode(), as pointed out in Reply #8 and Reply #16.

Just change

   if (myReceiver.getResults()) {
           myDecoder.decode();

to   if (myReceiver.getResults() && myDecoder.decode()) {

Hang on, I'll try that. Got bogged down with other things.