Hello all!
I'm working on a project -- as the title suggests, it is an rf-operated blimp. We've gotten the hardware sorted out, but I'm experiencing a problem with the transmission between the remote and the receiver. (Just to clarify -- One way communication from a remote to the receiver on the gondola of the blimp.)
My problem is that there is a lag in the communication. As you can imagine, this delay (of about 2 or more seconds) impedes to function of any remote control device. However I'm not sure what to do about it. Sometimes the communication works mildly fine -- The lag is still noticeable, but blimp control would be operable. However, often it will just drop completely, and then spontaneously start working again.
The basic gondola setup is as follows:
One Arduino UNO powered by a 9v battery,
a single servo that is attached to a turning axel,
on which there are two regular high-speed, low torque motors.
On the remote, I have:
a single Arduino with
four push buttons and a potentiometer.
The remote makes a string of numbers depending on the status of the forms of input (buttons and potentiometer), and transmits it to the receiver, which translates the string and moves accordingly.
Like I said, it works, and when the reception is consistent, the delay is less noticeable. However, the connection is constantly dropping with no change or movement of the two parts. That is, each of the receiver and transmitter just sit stationary, the gondola not attached to anything.
I've experimented with antennas, and having a piece of wire propped for both ends makes matters worse -- There's basically no interface at all.
I'm pretty sure this is a hardware problem, but I'll post my code anyway.
/* Blimp Transmitter
* Features remote control of the blimp gondola via 4 buttons a potentiometer over
* VirtualwWire.
* Created 9 / 7 / 12
*/
#include <VirtualWire.h>
char *createControlString(int potentiometer, int left, int right) {
char *tmp = "000000";
char *pottmp = "0000";
char *mtmp = "0";
itoa(left, mtmp, 10);
tmp[0] = mtmp[0];
itoa(right, mtmp, 10);
tmp[1] = mtmp[0];
// Conversion from potentiometer reading to servo ms value
potentiometer = (1.8 * potentiometer) + 544;
// Convert potentiometer value to a string
itoa(potentiometer, pottmp, 10);
if (potentiometer >= 1000) {
for (int i = 0; i < strlen(pottmp); i++)
tmp[i + 2] = pottmp[i];
}
else if (potentiometer >= 100) {
tmp[2] = '0';
for (int i = 0; i < strlen(pottmp); i++)
tmp[i + 3] = pottmp[i];
}
else if (potentiometer >= 10) {
tmp[2] = '0';
tmp[3] = '0';
for (int i = 0; i < strlen(pottmp); i++)
tmp[i + 4] = pottmp[i];
}
else if (potentiometer >= 0) {
tmp[2] = '0';
tmp[3] = '0';
tmp[4] = '0';
for (int i = 0; i < strlen(pottmp); i++)
tmp[i + 5] = pottmp[i];
}
return tmp;
}
void setup()
{
// I/O Setup
Serial.begin(9600);
pinMode(2, INPUT); // Button 4
pinMode(3, INPUT); // Button 3
pinMode(7, INPUT); // Button 2
pinMode(8, INPUT); // Button 1
pinMode(13, OUTPUT); // LED
// VirtualWire Setup
vw_setup(2000);
vw_set_ptt_inverted(true);
vw_set_tx_pin(11);
}
void loop()
{
// Initialize and get readings
int potval;
int b[4];
b[0] = digitalRead(8);
b[1] = digitalRead(7);
b[2] = digitalRead(3);
b[3] = digitalRead(2);
potval = analogRead(A0);
int motorleft, motorright;
// Left Motor switches
if (!b[0] && !b[1])
motorleft = 0; // Don't move left motor
else if (b[0] && !b[1])
motorleft = 1; // Move left motor forward
else if (!b[0]&& b[1])
motorleft = 2; // Move left motor backward
else if (b[0] && b[1])
motorleft = 0; // Don't move motor
// Right Motor Switches
if (!b[2] && !b[3])
motorright = 0;
else if (b[2] && !b[3])
motorright = 1;
else if (!b[2]&& b[3])
motorright = 2;
else if (b[2] && b[3])
motorright = 0;
// Print readings
/*for (int i = 0; i < 4; i++) {
Serial.print("Button ");
Serial.print(i);
Serial.print(": ");
Serial.print(b[i]);
Serial.println();
}*/
// print motor settings
Serial.print("Left: ");
Serial.print(motorleft);
Serial.print(" Right: ");
Serial.print(motorright);
Serial.println();
// Print potentiomoter reading
Serial.print("Potentometer: ");
Serial.print(potval);
Serial.println();
// Main delay
delay(200);
// Create control string
char *info = createControlString(potval, motorleft, motorright);
Serial.println(info);
// Transmit info
digitalWrite(13, true); // Flash light to show we're transmitting
vw_send((uint8_t *) info, strlen(info)); // Send message
vw_wait_tx(); // Wait until message is sent
digitalWrite(13, false);
}
/* Blimp transmitter code
* ServoTimer2 is used to work with the virtualwire library.
*/
#include <VirtualWire.h>
#include <ServoTimer2.h>
ServoTimer2 angleServo;
void setup() {
Serial.begin(9600);
// Declare pins 7 through nine as output
for (int i = 2; i < 6; i++)
pinMode(i, OUTPUT);
// Virtualwire Setup
vw_set_ptt_inverted(true);
vw_setup(2000); // Bits per second
vw_set_rx_pin(11); // Designate the pin the receiver's data pin
vw_rx_start(); // Start the receiver PLL running
// Servo
angleServo.attach(10);
}
void loop() {
// These two variables are used in the reception process
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
char *controlString = "000000";
//int *control[3] = {0, 0, 0000};
int leftmotor, rightmotor, servopos;
if (vw_get_message(buf, &buflen))
{
//Serial.print("Got: ");
/*for (int i = 0; i < buflen; i++) {
Serial.print(buf[i]);
Serial.print(" ");
}*/
Serial.println();
leftmotor = int(buf[0]) - '0';
rightmotor = int(buf[1]) - '0';
servopos = ((int(buf[2]) - '0') * 1000) + ((int(buf[3]) - '0') * 100) + ((int(buf[4]) - '0') * 10) + (int(buf[5]) - '0');
/*Serial.print("Left: ");
Serial.print(leftmotor);
Serial.println();
Serial.print("Right: ");
Serial.print(rightmotor);
Serial.println();
Serial.print("Servo: ");
Serial.print(servopos);
Serial.println();*/
if (leftmotor == 0) {
digitalWrite(2, false);
digitalWrite(3, false);
}
else if (leftmotor == 1) {
digitalWrite(2, true);
digitalWrite(3, false);
}
else if (leftmotor == 2) {
digitalWrite(2, false);
digitalWrite(3, true);
}
if (rightmotor == 0) {
digitalWrite(4, false);
digitalWrite(5, false);
}
else if (rightmotor == 1) {
digitalWrite(4, true);
digitalWrite(5, false);
}
else if (rightmotor == 2) {
digitalWrite(4, false);
digitalWrite(5, true);
}
//Serial.print(servopos);
Serial.println(servopos);
angleServo.write(servopos);
}
}
Feel free to ask questions; I'll gladly clarify.
I fresh out of ideas what to do about this. The RF modules I'm using are the basic transmitter/receivers you can get from Sparkfun. They are each operating on the Arduino's 5V pin. Perhaps I should connect them straight to the 9V battery?
Thanks for your time!