Hello folks.
In my small project I am trying to control with buttons a servo wireless using the cheap 433MHz transmitter/receiver and the VirtualWire Library. I have one atmega 328p MUC and one arduino UNO smd . The setup is like this:
Servo is connected to UNO in which before I decide to go wireless i was using two buttons and interrupts to control the servo.
Now the buttons are on the atmega chip plus the transmitter and the servo on the Uno plus the receiver.
Problems and Quastions:
I would like to use the virtualwire to control my “external” interrupts but using software only. I have the code running but correct. It is very slow( probably to many comands in the loop) and once i press the button and the receiver get the msg and activates the interrupt it goes for ever.
and last, the signal is very noisy and some times the servo moves without me pressing the button. any way to clean the signal? cheers. Tas
my Code:
Transmitter:
#include <VirtualWire.h>
void setup()
{
// Serial.begin(9600); // Debugging only
// Serial.println("setup");
// Initialise the IO and ISR
// vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_set_tx_pin(3);
pinMode(8, INPUT);
pinMode(9, INPUT);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
}
void loop()
{
char *msg;
if(digitalRead(8) == LOW){
char *msg = "5";
digitalWrite(13, true); // Flash a light to show transmitting
vw_send((uint8_t *)msg, strlen(msg));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13, false);}
if(digitalRead(9) == LOW){
char *msg = "6";
digitalWrite(13, true); // Flash a light to show transmitting
vw_send((uint8_t *)msg, strlen(msg));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13, false);}
}
Receiver ( the hard part) :~ :
#include <ServoTimer2.h>
#include <EEPROM.h>
#include <util/delay.h>
#include <VirtualWire.h>
ServoTimer2 myservo;
/* CHANGE ME */
// Servo limit - These number will change depending on how you installed your servo
// Set MANUAL_MODE = 1, connect a potentiometer to pin 3 and open the serial monitor
// Move to the lowest and highest gear to set these variables
int SERVO_STOP_LOW = 2100;
int SERVO_STOP_HIGH = 740;
#define MANUAL_MODE 1
// variable to read the value from the analog pin
int val;
int potpin = 3;
//int servo_power_pin = 6;
int led_pin = 10;
// Current servo position
int currentPos = 1000;
int currentPosAddr = 0;
// Number of positions to move when a button is pused
int servo_step_size =100 ;
// Flag set in the interrupt to signal a gear change
bool pendingShift = true;
void setup()
{ //pinMode(4, INPUT);
vw_setup(2000); // Bits per sec
vw_set_rx_pin(4);
vw_rx_start(); // Start the receiver PLL running
//pinMode(servo_power_pin, OUTPUT);
pinMode(led_pin, OUTPUT);
pinMode(11, OUTPUT);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
//digitalWrite(servo_power_pin, LOW);
attachInterrupt(0, shiftUp, FALLING);
attachInterrupt(1, shiftDown, FALLING);
// Remember last position
currentPos = EEPROM.read(currentPosAddr);
}
void shiftUp()
{
if ( pendingShift == true ) return;
// wait for button to stop bouncing
delay(50);
currentPos -= servo_step_size;
if ( currentPos < SERVO_STOP_HIGH)
currentPos = SERVO_STOP_HIGH;
pendingShift = true;
Serial.println("Shift up ");
Serial.println(currentPos);
}
void shiftDown()
{
if ( pendingShift == true ) return;
// wait for button to stop bouncing
delay(50);
currentPos += servo_step_size;
if ( currentPos > SERVO_STOP_LOW)
currentPos = SERVO_STOP_LOW;
pendingShift = true;
Serial.println("Shift down ");
Serial.println(currentPos);
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
Serial.print("Got: ");
//Serial.print(buf);
//Serial.print(buflen);
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i]);
if(buf[i] == '5'){digitalWrite(2, LOW);
delay(10);
//digitalWrite(2, HIGH);
digitalWrite(11, HIGH);}
if(buf[i] == '6'){digitalWrite(3, LOW);
delay(10);
//digitalWrite(3,HIGH);
digitalWrite(11, LOW);}
}
Serial.println("");
digitalWrite(13, false);
}
//digitalWrite(2, HIGH);
//digitalWrite(3, HIGH);
#if MANUAL_MODE
if ( pendingShift )
{
Serial.println("ON");
digitalWrite(led_pin, HIGH);
// digitalWrite(servo_power_pin, HIGH);
_delay_ms(15);
myservo.write(currentPos);
// Save last know position
EEPROM.write(currentPosAddr, currentPos);
// wait for servo to finish
_delay_ms(200);
Serial.println(currentPos);
digitalWrite(led_pin, LOW);
// digitalWrite(servo_power_pin, LOW);
pendingShift = false;
}
#else
// This code controls the servo with a POT
// To use it change MANUAL_MODE 1
digitalWrite(servo_power_pin, HIGH);
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
Serial.println(val);
delay(15); // waits for the servo to get there
#endif
}