Code Monkey home page Code Monkey logo

simple-rssi-antenna-tracker's Introduction

Simple RSSI Antenna Tracker

This tracker uses Quanum RC540R 5.8GHz 40CH Race Band FPV Diversity Receiver which has two video receivers with RSSI output. RSSI is measured with an Arduino's analog inputs, signal strength is compared and tracker head is turned towards stronger signal with servo.

This tracker relies solely on RSSI, no GPS or compass is involved. This means you can track any 5.8GHz signal source to which the receiver is tuned to. No pairing, no telemetry, no configuration, just tune and track.

Pros:

  • It's cheap and simple. You probably already have most of the the parts.
  • no GPS needed
  • no telemetry needed
  • can track any 5.8GHz source

Cons:

  • tracking is relative
  • tracker doesn't really know where the target is
  • may wander off target
  • tracks only in horizontal axis

What will you need

Youtube video

https://www.youtube.com/watch?v=aACTKziuDVE

Timer.h Arduino library

To install Timer library, download the ZIP file here: https://github.com/JChristensen/Timer

How to install libraries https://www.youtube.com/watch?v=Alz-rX6lkEw

simple-rssi-antenna-tracker's People

Contributors

andreiva avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple-rssi-antenna-tracker's Issues

360 servo support

I'm trying to get this tracker software to work with a 360 degrees servo, no luck so far.
the servo only spins faster and faster.

can 360 servo support please be added if possible ?

output the PPM signal to the transmitter

I think if the control board can output the PPM signal to the transmitter.By displaying the channel values on the transmitter panel or in the air osd, it is easier to manually track the position of the aircraft, like the head movement tracking control.

Layout schematic !

Hi. Nice project,
it would be nice to have a schematic. makes more than 1000 words.
Thx.

Cant compile

Tried to compile the sketch, but won't work. Any idea what may be the problem

Greets, Franz

Arduino: 1.8.5 (Windows 8.1), Board: "Arduino Nano, ATmega328P"

Build-Optionen wurden verändert, alles wird neu kompiliert
D:\arduino\tracker\simple-rssi-antenna-tracker\simple-rssi-antenna-tracker.ino: In function 'void setup()':

simple-rssi-antenna-tracker:122: error: no matching function for call to 'Timer::every(int, void (&)())'

   timer.every(50, mainLoop);

                           ^

D:\arduino\tracker\simple-rssi-antenna-tracker\simple-rssi-antenna-tracker.ino:122:27: note: candidates are:

In file included from D:\arduino\tracker\simple-rssi-antenna-tracker\simple-rssi-antenna-tracker.ino:10:0:

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:40:10: note: int8_t Timer::every(long unsigned int, void (*)(void*), void*)

   int8_t every(unsigned long period, void (*callback)(void*), void* context);

          ^

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:40:10: note:   candidate expects 3 arguments, 2 provided

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:41:10: note: int8_t Timer::every(long unsigned int, void (*)(void*), int, void*)

   int8_t every(unsigned long period, void (*callback)(void*), int repeatCount, void* context);

          ^

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:41:10: note:   candidate expects 4 arguments, 2 provided

simple-rssi-antenna-tracker:123: error: no matching function for call to 'Timer::every(int, void (&)())'

   timer.every(5, measureRSSI);

                             ^

D:\arduino\tracker\simple-rssi-antenna-tracker\simple-rssi-antenna-tracker.ino:123:29: note: candidates are:

In file included from D:\arduino\tracker\simple-rssi-antenna-tracker\simple-rssi-antenna-tracker.ino:10:0:

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:40:10: note: int8_t Timer::every(long unsigned int, void (*)(void*), void*)

   int8_t every(unsigned long period, void (*callback)(void*), void* context);

          ^

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:40:10: note:   candidate expects 3 arguments, 2 provided

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:41:10: note: int8_t Timer::every(long unsigned int, void (*)(void*), int, void*)

   int8_t every(unsigned long period, void (*callback)(void*), int repeatCount, void* context);

          ^

C:\Users\Franz\Documents\Arduino\libraries\Timer-2.1/Timer.h:41:10: note:   candidate expects 4 arguments, 2 provided

exit status 1
no matching function for call to 'Timer::every(int, void (&)())'

Servo slot too narrow

Servo slot is too small and will not allow a 9g servo to fit without pinching the wiring. I have modified the servo-body model by importing the file into FreeCAD then exporting to a STEP file and using Fusion 360 to expand the servo slot 1mm each side.
servo-body.zip

code issue

hello Andrei, I got an error when trying to compile this code...
[code]
`//#include <LiquidCrystal.h>

/*
Simple RSSI Antenna Tracker
RELATIVE
*/

#include <Servo.h>
#include <Timer.h>

/*
For testing different curves
All new curves are more precise
and maintain lock better than old RELATIVE

Uncomment one

*/
//#define EXPONENTIAL // OK
//#define RELATIVE // old, don't use
#define SIGMOID // Best
//#define PROPORTIONAL // twitchy

#define SIGMOID_SLOPE 1
#define SIGMOID_OFFSET 4

#if !defined(EXPONENTIAL) ^ !defined(SIGMOID) ^ !defined(PROPORTIONAL) ^ !defined(RELATIVE)
// all good
#else
#error "Please define ONE tracking curve: EXPONENTIAL, SIGMOID, PROPORTIONAL, RELATIVE"
#endif

/*
Pin mapping
You can change these pins, just make sure that
RSSI pins are analog inputs
and servo pin supports PWM
*/
#define LEFT_RSSI_PIN A0 // analog RSSI measurement pin
#define RIGHT_RSSI_PIN A1
#define PAN_SERVO_PIN 13 // Pan servo pin

/*
There is going to be some difference in receivers,
one is going to be less sensitive than the other.
It will result in slight offset when tracker is centered on target

Find value that evens out RSSI
*/
#define RSSI_OFFSET_RIGHT 0
#define RSSI_OFFSET_LEFT 0

/*
MIN and MAX RSSI values corresponding to 0% and 100% from receiver
See serial monitor
*/
#define RSSI_MAX 400
#define RSSI_MIN 120

/*
Safety limits for servo

Find values where servo doesn't buzz at full deflection
*/
#define SERVO_MAX 180
#define SERVO_MIN 0

/*
Servo 'speed' limits
MAX and MIN step in degrees
*/
#define SERVO_MAX_STEP 5
#define SERVO_MIN_STEP 0.09 // prevents windup and servo crawl

/*
Center deadband value!
Prevents tracker from oscillating when target is in the center
When using SIGMOID or EXPONENTIAL you can set this almost to 0
/
#define DEADBAND 5
//int DEADBAND = analogRead(A2)/200; // tolleranza tra dx e sx entro cui non muovere il servo
/

Depending which way around you put your servo
you may have to change direction

either 1 or -1
*/
#define SERVO_DIRECTION 1

#define FIR_SIZE 10
#define LAST FIR_SIZE - 1

uint16_t rssi_left_array[FIR_SIZE];
uint16_t rssi_right_array[FIR_SIZE];

float anglePan = 90;
boolean debug = false;
//LiquidCrystal lcd(12,11,5,4,3,2);

Timer timer;
Servo servoPan;
//----------------------------------------------------------------------------------//

void setup() {
servoPan.attach(PAN_SERVO_PIN);
servoPan.write(90);

// lcd.begin(16,2);
// lcd.setCursor(0,0);
// lcd.print("pos");
// lcd.setCursor(7,0); // pos....deg.......
// lcd.print("deg"); // rssisx....rssidx...
// lcd.setCursor(0,1); //
// lcd.print("rssisx");
// lcd.setCursor(10,1);
// lcd.print("rssidx");

// wipe array
for (int i = 0; i < FIR_SIZE; i++) {
rssi_right_array[i] = 0;
rssi_left_array[i] = 0;
}

Serial.begin(115200);
while (!debug) {
delay(3000);
debug = true;
}

timer.every(50, mainLoop);
timer.every(5, measureRSSI);

}
//---------------------------------------------------------------------------------//
void loop() {

timer.update();

}

//-------------------------------------------------------------------------------------------------//
void mainLoop() {

uint16_t avgLeft = max(avg(rssi_left_array, FIR_SIZE) + RSSI_OFFSET_LEFT, RSSI_MIN);
uint16_t avgRight = max(avg(rssi_right_array, FIR_SIZE) + RSSI_OFFSET_RIGHT, RSSI_MIN);

// If avg RSSI is above 90%, don't move
// if ((avgRight + avgLeft) / 2 > 360) {
// return;
// }

/*
the lower total RSSI is, the lower deadband gets
allows more precise tracking when target is far away
*/
uint8_t dynamicDeadband = (float(avgRight + avgLeft) / 2 - RSSI_MIN) / (RSSI_MAX - RSSI_MIN) * DEADBAND;

// if target is in the middle, don't move
if (abs(avgRight - avgLeft) < dynamicDeadband ) {
return;
}

float ang = 0;

// move towards stronger signal
if (avgRight > avgLeft) {

#if defined(EXPONENTIAL)
float x = float(avgRight - avgLeft);
x = x * x / 500;
ang = x * SERVO_DIRECTION * -1;
#endif

#if defined(RELATIVE)
ang = float(avgRight / avgLeft) * (SERVO_DIRECTION * -1);
#endif

#if defined(SIGMOID)
float x = float(avgRight - avgLeft) / 10;
x = SERVO_MAX_STEP / (1 + exp(-SIGMOID_SLOPE * x + SIGMOID_OFFSET));
ang = x * SERVO_DIRECTION * -1;
#endif

#if defined(PROPORTIONAL)
float x = float(avgRight - avgLeft) / 10;
ang = x * SERVO_DIRECTION * -1;
#endif
}
else {

#if defined(EXPONENTIAL)
float x = float(avgLeft - avgRight);
x = x * x / 500;
ang = x * SERVO_DIRECTION;
#endif

#if defined(RELATIVE)
ang = float(avgLeft / avgRight) * SERVO_DIRECTION;
#endif

#if defined(SIGMOID)
float x = float(avgLeft - avgRight) / 10;
x = SERVO_MAX_STEP / (1 + exp(-SIGMOID_SLOPE * x + SIGMOID_OFFSET));
ang = x * SERVO_DIRECTION;
#endif

#if defined(PROPORTIONAL)
float x = float(avgLeft - avgRight) / 10;
ang = x * SERVO_DIRECTION;
#endif
}

// upper and lower limit for angle step
ang = (abs(ang) > SERVO_MAX_STEP ? SERVO_MAX_STEP * ang / abs(ang) : ang);
ang = (abs(ang) < SERVO_MIN_STEP ? 0 : ang);

// move servo by n degrees
movePanBy(ang);

if (debug) {
// Serial.print("RSSI%: ");
// Serial.print(map(avgLeft, RSSI_MIN, RSSI_MAX, 0, 100));
// Serial.print(", ");
// Serial.print(map(avgRight, RSSI_MIN, RSSI_MAX, 0, 100));

// raw rssi values, use these for RSSI_MIN and RSSI_MAX
Serial.print("Calibration - left: ");
Serial.print(avgLeft);
Serial.print(" right: ");
Serial.print(avgRight);

Serial.print(" servo-angle: ");
Serial.println(anglePan);

}
}

void movePanBy(float angle) {

anglePan += angle;
anglePan = limit(SERVO_MIN, SERVO_MAX, anglePan);
servoPan.write(anglePan);
}

void measureRSSI() {

advanceArray(rssi_left_array, FIR_SIZE);
advanceArray(rssi_right_array, FIR_SIZE);

rssi_left_array[LAST] = analogRead(LEFT_RSSI_PIN);
rssi_right_array[LAST] = analogRead(RIGHT_RSSI_PIN);
}

uint16_t avg(uint16_t samples[], uint8_t n) {

uint32_t summ = 0;
for (uint8_t i = 0; i < n; i++) {
summ += samples[i];
}

return uint16_t(summ / n);
}

void advanceArray(uint16_t *samples, uint8_t n) {

for (uint8_t i = 0; i < n - 1; i++) {
samples[i] = samples[i + 1];
}
}

float limit(float lowerLimit, float upperLimit, float var) {

return min(max(var, lowerLimit), upperLimit);
}
//lcd.setCursor(4, 0);
//lcd.print(anglePan);
//lcd.setCursor(8, 1);
//lcd.print(LEFT_RSSI_PIN);
//lcd.setCursor(13, 1);
//lcd.print(RIGHT_RSSI_PIN);
`


1. the error i got is here follwing. the timer library is installed correctly..:

libraries\Timer\Event.cpp.o (symbol from plugin): In function `Event::Event()':

(.text+0x0): multiple definition of `Event::Event()'

sketch\Event.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Event.cpp.o (symbol from plugin): In function `Event::Event()':

(.text+0x0): multiple definition of `Event::Event()'

sketch\Event.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Event.cpp.o (symbol from plugin): In function `Event::Event()':

(.text+0x0): multiple definition of `Event::update(unsigned long)'

sketch\Event.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Event.cpp.o (symbol from plugin): In function `Event::Event()':

(.text+0x0): multiple definition of `Event::update()'

sketch\Event.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::Timer()'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::Timer()'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::stop(signed char)'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::update(unsigned long)'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::update()'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::findFreeEventIndex()'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::every(unsigned long, void (*)(), int)'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::every(unsigned long, void (*)())'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::after(unsigned long, void (*)())'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::oscillate(unsigned char, unsigned long, unsigned char, int)'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::oscillate(unsigned char, unsigned long, unsigned char)'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::pulse(unsigned char, unsigned long, unsigned char)'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\Timer\Timer.cpp.o (symbol from plugin): In function `Timer::Timer()':

(.text+0x0): multiple definition of `Timer::pulseImmediate(unsigned char, unsigned long, unsigned char)'

sketch\Timer.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1


thanks
best regards
Andrea

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.