Uno clone, 328 at 16MHz
So I'm trying to build a device that will let me turn on and off a PC monitor with an IR remote. A servo is taped below and behind the button, and a 3D printed linkage taped to the front of the monitor presses the power button when the servo pulls on it.
When I use the code below, it works perfectly, although remote functionality isn't there yet. Pressing a button on pin 4 causes the servo to pull on the linkage and press the power button. At idle, there is no noise or movement from the servo.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
int buttonState = 0;
const int button = 4;
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(button, INPUT);
irrecv.enableIRIn();
irrecv.blink13(true);
}
void loop() {
buttonState = digitalRead(button);
if (buttonState == LOW){
myservo.write(55);
}
else {
myservo.write(90);
}
}
However, if I load the code below, the servo makes noise, as if it is constantly changing position back and forth by fractions of degrees. The circuit has not changed between the two. I've tried putting a cap across the servo's power rails and powering the servo from a separate 9V, but the noise persists. Note that the IR receiver isn't even being used yet. It has only been defined as being on pin 11.
#include <Servo.h>
#include <IRremote.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
int buttonState = 0;
const int button = 4;
const int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(button, INPUT);
irrecv.enableIRIn();
irrecv.blink13(true);
}
void loop() {
buttonState = digitalRead(button);
if (buttonState == LOW){
myservo.write(55);
}
else {
myservo.write(90);
}
}
I've searched, and one of the solutions offered is to detach the servo after I've used it. It feels like such a kludge, though. Are there any other ways of potentially fixing this?
There may be a timer conflict between the servo library and the IR library. You could try the ServoTimer2 library.
Other problems arise from trying to power the servo from the Arduino 5V. If you are, don't -- it will eventually damage the Arduino. Use a separate power supply for the servo and don't forget to connect the grounds.
Please post images in line. Image posting guide
jremington:
There may be a timer conflict between the servo library and the IR library. You could try the ServoTimer2 library.
Other problems arise from trying to power the servo from the Arduino 5V. If you are, don't -- it will eventually damage the Arduino. Use a separate power supply for the servo and don't forget to connect the grounds.
Please post images in line. Image posting guide
Nice idea. Thank you. However, it unfortunately didn't work.
//#include <Servo.h>
#include <ServoTimer2.h>
#include <IRremote.h>
//Servo myservo;
ServoTimer2 myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
int buttonState = 0;
const int button = 4;
const int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
void setup() {
myservo.attach(6); // attaches the servo on pin 6 to the servo object
myservo.write(1500);
pinMode(button, INPUT);
irrecv.enableIRIn();
irrecv.blink13(true);
}
void loop() {
buttonState = digitalRead(button);
if (buttonState == LOW){
myservo.write(1208);
}
else {
myservo.write(1500);
}
}
When run, this code results in pin 6 going low and staying low. Comment out all the IR related lines and then you can see servo-controlling pulses on line 6.
Problem is solved. jremington, you were very much on the right track when it came to shared microcontroller resources between Servo.h and IRremote.h. Using ServoTimer2.h didn't work, but switching back to Servo.h and then using IRLib2.h seems to have done the trick. Servo is no longer making noise at idle, and I'm now able to control the servo with the remote.
#include <Servo.h>
//#include <ServoTimer2.h>
#include "IRLibAll.h"
#define MY_PROTOCOL NEC
#define POWER 0x4B36D32C //Toggle screen on and off
//Servo myservo;
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
int buttonState = 0;
const int button = 4;
uint32_t Previous;
IRrecvPCI myReceiver(2);
IRdecode myDecoder;
void setup() {
myservo.attach(6); // attaches the servo on pin 6 to the servo object
myservo.write(90);
pinMode(button, INPUT);
myReceiver.enableIRIn(); // Start the receiver
}
void loop()
{
if (myReceiver.getResults()) {
myDecoder.decode();
if(myDecoder.protocolNum==MY_PROTOCOL) {
if(myDecoder.value==0xFFFFFFFF)
myDecoder.value=Previous;
switch(myDecoder.value) {
case POWER:
myservo.write(55);
delay(500);
break;
}
myservo.write(90);
Previous=myDecoder.value;
}
myReceiver.enableIRIn();
}
}