Super Simple Sound Doppler Peiler

Hardware en software.
Bericht
Auteur
Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#556 Bericht door Dopp »

Hallo Allemaal,

Nog een plaatje van mijn SuperSimpleArduinoDoppler
maar nu met luidspreker + schakelaar dat was toch wel handig..


Oh Goos die python lib pygame

die kan ik niet vinden hier op mijn windows pc met Python 3.43

Ik ben nog steeds bezig met leren allerlei dingen in Python...
Bijlagen
SuperSimpleArduinoDoppler<br />met speaker !
SuperSimpleArduinoDoppler
met speaker !
ArduinoDopplerSpeaker.jpg (33.57 KiB) 6229 keer bekeken
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#557 Bericht door Dopp »

Hallo Allemaal,


Er komt binnenkort een nieuwe versie SoundDoppler en Mymapping op de site van PI4WAG

In Mymapping zit in de huidige versie een paar onvolkomen heidjes
als je Averaging inschakelt (Menu F8)
dus groene bug rond de pelorus via de Arduino Agrelo terminal input.

Wat verbeterd is is als je geen GPS hebt en drukt op Draw button dat dan de Averaged bug getekend wordt
op de kaart ipv de momentele peiling van de Arduino doppler.

Lijkt me ook handig voor andere Agrelo dopplers via rs232
die geen averaging hebben.

Een goede instelling is ca 7 a 15 sec voor max average timing.


Ondertussen ook druk bezig met test versie schrijven van een Pelorus onder Python...
voor de arduino doppler.

Zag ook Autonome Arduino Doppler V40 op de site van PA8W staan
En heel mooie uitleg over multipath en de cirkel is rond. :idea:
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#558 Bericht door Dopp »

Hallo Allemaal,


Brr zat nog een fout in de arduino code wat beftreft
CW en CCW die heb ik in deze versie gefixed

Vandaag ook een Cal knop in de arduino terminal in MyMapping 1.56.exe gemaakt
om de arduino doppler met een druk op knop tijdens ontvangs
te zetten op Norh of Front of car.

Omdat de scanner best wel hard moet staan is een audio pre-amp misschien op zijn plaats

Ik dacht een een op ampje er voor zetten ua741 oid

Maar later bedacht ik me en heeft z'n opampje niet genoeg spanning
met de 5 Volt van arduino regelaar.
Bijlagen
Arduino2.txt
CW/CCW gefixed Arduino code
(20.66 KiB) 247 keer gedownload
Probeersel<br />Pre amp voor ArduinoDoppler
Probeersel
Pre amp voor ArduinoDoppler
PreAmpArduinoDoppler.GIF (8.69 KiB) 6161 keer bekeken
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#559 Bericht door Dopp »

Hallo Allemaal,

Er staat ondetrtusen versie SoundDoppler149hAll.zip op de site van PI4WAG

Met Mymapping 1.56 en en arduino.ino de SuperSimpleArduinoDoppler

In de Arduino terminal kun je nu ook instellen AV

dwz uitmiddelen in de arduino software (Max 3 secondes)

Of je kunt uitmiddelen in MyMapping1.56


Bezig ben ik met een elapsed time squelch open timer te maken voor
in MyMapping die dus de tijd dat de squelch open is aan geeft in secondes.
in het Pelorus display.

Oh voor de opamp in de audio keten voor de arduino kun je denk ik beter een ca3140

nemen dan een 741 of 1558 opamp. (lower voltage needed)
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#560 Bericht door Dopp »

Hallo Allemaal,

Tsja nog effe een plaatje waar beide type antenne systemen op staan

Dus de classic 4 mono of 4 dipolen doppler array mode FM

En de plaat antenne (4 richtingen) mode AM
Bijlagen
Doppler peil antenne array<br />types
Doppler peil antenne array
types
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Goos
Berichten: 338
Lid geworden op: 16 nov 2011, 20:45
Roepletters: pa0sir

Re: Super Simple Sound Doppler Peiler

#561 Bericht door Goos »

Gisteren Python op de laptop gezet
Kwam er achter dat bij de voorbeelden ook een klok zat
Eigenlijk al kant en klaar, alleen de uren- en minutenwijzer eruit gesloopt.
En de netwerkregels er in gezet. Ging in de eerste keer goed ook via 127.0.0.1
zou ook moeten kunnen via COM/USB.
Bij elkaar een half uurtje werk.

gr
Goos
Peilen is het omgekeerde van een antennediagram opmeten.
pa0sir

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#562 Bericht door Dopp »

Hallo Allemaal,


Nog twee you tubes SHTF

SHTF Intro to Radio Direction Finder part2

https://www.youtube.com/watch?v=mLR9yFi ... detailpage

https://www.youtube.com/watch?v=bCWVNGU ... detailpage

Balint256 round the car walking
https://www.youtube.com/watch?v=sGKDssz ... detailpage

Have fun watching
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#563 Bericht door Dopp »

Hallo Allemaal,


Ben bezig om ook een elevatie scherm te maken in MyMapping1.57
voor de SuperSimpleArduinoDoppler

De arduino doppler geeft nu
naast het Agrelo protocol dus bv %123
extra tussen brackets weer bv [12]

Dat getal geeft de doppler toon Amplitude aan.

Dit is dus compatible ook met gewoon agrelo protocol

Met de slider naast de elevatie kwart circel stel je dus in op 0 graden
als je een station hoort wat laag boven de grond zit.

Als de elevatie hoger wordt wordt immers de dopplertoon amplitude minder.

Deze data wordt gebruikt om de elevatie weer te geven.


Heb nog een probleempje gevonden in de arduino uno software:

Als je met een plaat antenne peilt de richting om te schakelen
van CW naar CCW.
Dat werkt nu nog niet.

Daar moet ik voor een oplossing zoeken ook in de Arduino doppler software.
Bijlagen
MyMapping<br /><br />With Arduino Terminal, Pelorus<br />and Elevation.
MyMapping

With Arduino Terminal, Pelorus
and Elevation.
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#564 Bericht door Dopp »

Hallo Allemaal,


Brr hi Arduino perikelen.


Ik vond nog een bug in de laatst released code

Dit betreft multipath detecting in de Average function in mijn sketch

en een error in CW/CCW laten lopen met een plaat antenne via de
max232 op het arduino shield.

Maar nu werkt ook met de plaat antenne ant1 ant2 ant3 ant4 test

met de SuperSimpleArduinoDoppler


Leuk ontwerp trouwens van PA2GLA in de electron van aug 2015 blz 322
De arduino sketch van Jan PA2GLA staat daar.

Maar de software sketch in de arduino doppler die moet nog (veel) beter worden.

Maar leuk dat meerdere mensen mee denken en doen....

Ook leuk dat er een Arduino cursus avond is gstart in het Gooi.

Hoe meer mensen mee doen en ook aan de slag gaan des te leuker.
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#565 Bericht door Dopp »

Hallo Allemaal,

Leuk en intressant uitleg filmpje

Radio Direction Finding - Jeric Dabu

https://www.youtube.com/watch?v=tJ1JWNw ... detailpage
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
pa8w
Berichten: 948
Lid geworden op: 22 dec 2011, 21:30
Roepletters: PA8W
Locatie: Beuningen
Contacteer:

Re: Super Simple Sound Doppler Peiler

#566 Bericht door pa8w »

Leuk filmpje,
Hij heeft de opdruk "geleend" van m'n V3.2 doppler ... ;)

groet,
Wil.
Let op: website verhuisd naar: http://www.paluidsprekers.nl/pa8w/index.html

Gebruikersavatar
Dopp
Berichten: 1242
Lid geworden op: 08 mei 2011, 18:03
Roepletters: PA3BNX

Re: Super Simple Sound Doppler Peiler

#567 Bericht door Dopp »

Hallo Allemaal,

Ben bezig met een draaispoel meter aan te sluiten
op de arduino doppler ..

Die krijgt dan een schaal van 180-270- 0-90-180 graden
(er betaan geen draaispoel metertjes die een uitslag hoek hebben van 360 graden ?)

Een meter dus met serie weerstandjezodat ie bij 5V volle schaal volledig uitslaat op pin 6 van de arduino.


In de arduino sketch heb ik al een parameter gemaakt om de refpa3bnx pin 6 arduino
dus te kunnen omschakelen.

boolean bAnalogPelorus=false; //Pin for refpin as Pelorus meter

Deze boolean op true zetten en ik hoop dat dat het dan werkt.


Als ik van de week tijd heb ga ik dat testen

Code: Selecteer alles



/*
  ((C))PA3BNX SuperSimpleArduinoDoppler/RDF
  Trying to create a SuperSimpleArduinoDoppler on Arduino Uno R3 
  Arduino Uno REV 3 Sketch + (With dopplertone amplitude averaged)
  Look at http://www.pi4wag.nl/projecten/doppler-peiler-radio-direction-finder
  
  ========================================================================================
  Why because there are so many laptops with just mono mic inputs
  This can eliminate the external USB stereo input Soundcard with MyMapping.exe software
  ========================================================================================
  For this there is a special Arduino Com/USB input in program MyMapping to show the Agrelo(%bbb<cr><lf>) headings on maps
  No adjustments on the arduino shield it self except Referency audio output for soundcard.
  All adjustments like Frequency, CW/CCW and Calibrate-offset through Serial Port
  Doppler frequency 500-700-900 Hz 
  Antenna test 1,2,3,4 Wait 3 seconds then restart scanning 
  Remote CMD's  ANT1 ANT2 ANT3 ANT4 OFF CW CCW LOW MID HIGH (bbb Calibrate) AV
  AV does switch averaging off/on but it does always start up in Average On mode
  In the Arduino IDE Serial monitor you can input cmd's easy with a z like ANT1z,  CCWz, 335z or AVz
  Led on pin13 is Squelch
  @12-04-2015
  @08-06-2015
  @26-06-2015 Bug fixed CW/CCW
  @01-07-2015 Average bug fixed?
  @22-07-2015 Doppler tone Amplitude &ddd [T]
  @27-07-2015 CW/CCW for AM plate antenna
  @02-08-2015 MultiPath bug Fixed
  Not quite ready yet but working!
  Arrays are zero based !!!!
  Explaining functions Arduino pins:
  antPins[4] Connect to antenna switcher pins
  refpa3bnx Connect to audio lowpass filter for soundcard referency input 
  kPins[4] Connect to kwadrant C's 4u7
  kPinAnalog Connect to sum point of 4 cap's
  max232Pin[2] for Am Plate Whatson Watt DF through max232 external chip + and - 12 V
  It stores Calibrate, Freq, CW/CCW and EEPROM !
  
  frequency <> startTimer values 
  500 131
  700 167
  900 187
  1200 203
  1500 214
  2000 225
  2500 231
  
  Byte= 0>255
  Int=  -32768>32767 Int = 2 bytes
 */

#include <EEPROM.h>

//EEPROM Adresses
//Max 512 Adress bytes
const byte ID=100; //Eeprom ID  always on adress 0
const int cFreq=1; //1 byte 
const int cCW=2;   //1 byte
const int cCal=3;  //2 bytes


 //String Serial params
 String inputString="";             //Received serial string 
 
 //Boolean
 boolean bStringComplete=false;     //Complete '\n' rxed serial string  
 volatile boolean bNoAntScan=false; //Do not change antPins while testing one antenna 
 boolean bAverage = true;           //Default Average
 boolean bMultiPathAverage=false;   //Multipath heading found in received headings from Averaged

//Const Integer
//Must be modified to right pin number arduino and arduino shield hardware
//Antenna Control Pins & refpa3bnx //Never use pins 0 and 1 because the UART must also function 
//So I started with pin nbr 2  
byte antPin[4]={2,3,4,5};           //Set antenna control pins (Not const because it can be CCW/CW) 
const byte max232Pin[2]={7,8};      //Set Max232Pin vor AM plate antenna
const byte refpa3bnx=6;             //Pin for Referency frequency output to soundcard or pelorus meter ?
boolean bAnalogPelorus=false;       //Pin for refpin as Pelorus meter

//Integer
byte mLOW=0;                        //Reverse max232Pins for CW/CCW AM plate antenna
byte mHIGH=1;

//Kwadrant Capicity switches & analog SCF read pin
const byte kPin[4]={9,10,11,12};    //4 pins caps 4u7 
const byte kPinAnalog=0;            //A0 read voltage across one 4u7 cap pin A0 to A5
const int cOffset=511;              // .5 * 1023 caps offset  

//Squelch Signals
const byte cSqlclosed=0;
const byte cSqlclosed2open=1;
const byte cSqlOpenflutter=2;
const byte cSqlopen2closed=3;
const byte cSqloverflow=4;          //Capicitors are full

//NoDegreesMaxMinValues
const int cNodegrees=999;           //Squelch No Signal or cSqlopen2closed Clear avDegrees and set avDegrees to cNodegrees 
const int cReset=888;               //Clear Average and and put last avDegrees back in Average
const int cMaxTime=12;              //15 Sec/cMainLoopDelay Max time 60 * .250 = 15 Sec   30 * .5 Sec =15 sec    75 * .200 = 15 sec 12 * .250 = 3 Sec
const int cMainLoopDelay=250;       //How fast the main loop runs in mSec 500mSec
const int cMinAudioAmplitude=15;    //There is enough signal to SinCosDetect
const int cMaxSymmetric=175;        //Max Sym in MultiPathSCF 
const byte cMaxFlutterCount=3;      //Max keep loop rounds open after sql closing //Function Squelch Range 1 to 5 orso ?
 
//Float const
const float rad1=180/PI;            //57.295827
 
//Integer
//Array with the 4 kwandrant analog cap tensions These can be -511 to +511 
byte StartTimer=131; //500 Hz by default // 131, 167 and 187 500, 700 and 900 Hz
byte sqlstatus=cSqlclosed; 
int Corg[4]={0,0,0,0};             //Direct cap values filled in ISR
int Cap[4]={0,0,0,0};              //+ and - values from analog read -511>0>511
int Calibrate=0;                   //Calibrate degrees default 0-360


//Maybe use refpa3bnx pin also to connect a Pelorus meter as indicator
void AnalogPelorus(int d)
{
  if (bAnalogPelorus==false){return;}
  //Range 0 to 255 
  //What to do if d==cNodegrees ?
  if (d == cNodegrees) {return;}
  int x= (255 * Cali(LimitDegrees360(d+180))/360);
  //Analoge PWM pins Arduino Uno Rev3 3, 5, 6, 9, 10, and 11. 
  analogWrite(refpa3bnx,x);
}  


//------------ISR Main Interrupt //This runs always--------------------
ISR(TIMER2_OVF_vect)
{
 TCNT2=StartTimer; //Preload timer every time the ISR runs
 //Set the pins Todo further
 
 volatile static int c;
  
 if (bNoAntScan==false){ 
   
 if (c==4){
  c=0;
 }  
 
 //All switching Pin Settings getting here
 
 Corg[c]=analogRead(kPinAnalog)-cOffset;
 
 switch (c){
 case 0:
  digitalWrite(antPin[0],HIGH);
  digitalWrite(antPin[3],LOW);
  digitalWrite(kPin[0],LOW);
  digitalWrite(kPin[3],HIGH);
  if (bAnalogPelorus==false){digitalWrite(refpa3bnx,HIGH);}
  digitalWrite(max232Pin[0],mLOW);
  digitalWrite(max232Pin[1],mLOW);
  break;
 case 1:
  digitalWrite(antPin[1],HIGH);
  digitalWrite(antPin[0],LOW);
  digitalWrite(kPin[1],LOW);
  digitalWrite(kPin[0],HIGH);
  digitalWrite(max232Pin[0],mHIGH);
  digitalWrite(max232Pin[1],mLOW);
  break;
 case 2:
  digitalWrite(antPin[2],HIGH);
  digitalWrite(antPin[1],LOW); 
  digitalWrite(kPin[2],LOW);
  digitalWrite(kPin[1],HIGH);
  if (bAnalogPelorus==false){digitalWrite(refpa3bnx,LOW);}
  digitalWrite(max232Pin[0],mLOW);
  digitalWrite(max232Pin[1],mHIGH);
  break;
 case 3:
  digitalWrite(antPin[3],HIGH);
  digitalWrite(antPin[2],LOW);
  digitalWrite(kPin[3],LOW);
  digitalWrite(kPin[2],HIGH);
  digitalWrite(max232Pin[0],mHIGH);
  digitalWrite(max232Pin[1],mHIGH);
  break;
 }
  c++;
 } 
 } //Last bracket ISR-OVF

//Set ISR StartTimer
void ISRset(int f)
{
//Hint How to calc StartTime value 
//Arduino doesn't like float calcs with small numbers hi 
//t=1/freq
//x=256/16000000
//StartTime = 256-(t/x)
//----------------------  
  
//Standard values 500, 700 and 900 Hz  
// 131, 167 and 187
switch (f){
case 500:
 StartTimer=131;
 break;
case 700:
 StartTimer=167; 
 break;
case 900:
 StartTimer=187;
 break;
}  
EEPROM.write(cFreq,StartTimer);
Serial.print(f);
Serial.println(F(" Hz"));
}

void SetAllPins(){
  
}//Last Bracket SetAllPins  

//---------Functions now-------------------

//Listen/Test on each antenna separate for about 3 sec's
void AntTest(byte a){
 bNoAntScan=true;

 byte i; 
 //Switch all Low
 for (i=0;i<4;i++)
 {
  digitalWrite(antPin[i],LOW);  
 }

 if (a==255) 
 {
  //Leave all Ant Low
  Serial.println(F("Start All Ant Low"));
  }
 else if (a<4)
 {
  //Switch one Doppler antenna High
  Serial.print(F("Start Ant Test "));
  Serial.println(a+1);
  digitalWrite(antPin[a],HIGH);
 }


//Plate antenna direction
 switch(a)
 {
 case 0:
 digitalWrite(max232Pin[0],mLOW);
 digitalWrite(max232Pin[1],mLOW);
 break;
 case 1:
 digitalWrite(max232Pin[0],mHIGH);
 digitalWrite(max232Pin[1],mLOW);
 break;
 case 2:
 digitalWrite(max232Pin[0],mLOW);
 digitalWrite(max232Pin[1],mHIGH);
 break;
 case 3:
 digitalWrite(max232Pin[0],mHIGH);
 digitalWrite(max232Pin[1],mHIGH);
 break;
 }
  delay(3000);  //3 Seconds
 //Switch doppler antenna again to Low
 if (a<4)
 {
 digitalWrite(antPin[a],LOW);
 }
 bNoAntScan=false;
}

//---------------Empty the 4 capicitors by discharging to 1/2 U------
//This function leaves all kPin[] = HIGH
void EmptyCaps(){
 
 byte i;  
   for (i=0;i<4;i++)
 {
  digitalWrite(kPin[i],LOW);
 }  
 delay(1000);
 for (i=0;i<4;i++)
 {
  digitalWrite(kPin[i],HIGH);
 }  
}  


//-------------Squelch-----------------------
byte Squelch(){
//Return the sqlstatus
//Try Find a full cap   
 static byte flutterCount;
 int x=0;  //Max
 int x1=0; //Min
 int z=0;

 
 //Find cap with highest voltage/tension top-top value
 //Biggest value = cOffset (511)
 for(byte i=0;i<4;i++)
 {
   z=(Cap[i]);   
   if (z>x)
   {
     x=z;//Max
   }  
 
   if (z<x)
   {
    x1=z;//Min 
   }    
  }
 //Do not use functions in abs()
 z=abs(x)+abs(x1);
 x=z/2;
     
 //See if there is a Full Cap 
 //cOffset = Biggest value

 if (x>=cOffset)
 {
  return cSqloverflow;
 //Caps are full so need discharged
 }
 else if (x>=cMinAudioAmplitude)
 {
   flutterCount=0; //Reset
   AverageTone(x);//Average Doppler Amplitude
   return cSqlclosed2open; //Squelch Open
 }
 else if (x<cMinAudioAmplitude && flutterCount < cMaxFlutterCount )
 {
   flutterCount+=1;
   if (flutterCount==cMaxFlutterCount){ return cSqlopen2closed;}; //Closed 
   if (flutterCount<cMaxFlutterCount){return cSqlOpenflutter;};   //Keep flutter open
 }
 else  
 {
   flutterCount=-1;
   return cSqlclosed;
 }
}//Last Bracket Squelch

//----Detect Multipath in SCF Caps
boolean MultiPathDetectSCF(){
//Calc average of 4 kwadrants
//If to large asymetric value return true
//Can it do also the Quality 1-9 ?
int x;
for (int i=0;i<4;i++){
  x+=Cap[i];
}
//150 of max 510 is the MultiPath level ? 
if (abs(x)>cMaxSymmetric){  
return true;
}
else
{
return false;
}
}

//Calibrate  So add Calibrate offset to degrees
int Cali(int d){
 return LimitDegrees360(Calibrate+d);
}

//Return Agrelo formatted string % and always 3 digits
String Format3Degrees(int d){
  String str;
  int digits[3];
  int reminder;  
  digits[0]=d/100;
  reminder=d%100;
  digits[1]=reminder/10;
  reminder=reminder%10;
  digits[2]=reminder;
  str+='%';
  str+=digits[0]; 
  str+=digits[1];
  str+=digits[2];
  return str;
}

//Limit Degrees 0 to 360 degrees
int LimitDegrees360(int d){
  //Limit degrees 0 to 360 here
  //If 999 then return 999
  if (d==cNodegrees)
  {
  return d;
  }
  else 
   {
   int x;
   x = d%360;
   if (x<0)
   {
   x+=360;  
   return x;
   }  
   }
}

//--Average
int Average(int d){
  //If d = 999 (cNoDegrees) then reset average and return last avDegrees witch is 999
  //If d = 888 (cReset) then Reset all and put last avDegrees back in arrays
  
  //Always return avDegrees and Set bMultiPath
  
  //Integer
  static int sum[4]={0,0,0,0};        //Sum of counts for each kwadrant
  static int c[4]={0,0,0,0};          //Cap tension/voltage in each kwadrant
  static int avDegrees=cNodegrees;    //Averaged degrees
  int xx[4]={0,0,0,0};                //Adjacent kwadrants counts
  int z=0;                            //Most adjacent headings
  int z1=0;                           //Other two kwandants headings Multipath 
  int y=0;                            //Index where the most headings are 
  
  //Reset/clear and return cNodegrees or last avDegrees
  
 //01-06-2015 No Averaging
 if (bAverage==false){return d;}

 switch (d){
 case cNodegrees:
  //Reset and Clear
  for (byte i=0;i<4;i++)
  { 
   sum[i]=0;
   c[i]=0;
  }
  bMultiPathAverage = false;
  avDegrees=cNodegrees;
  return avDegrees; //Exit now
 case cReset: //Reset and fill with avDegrees
   //Reset
   for (byte i=0;i<4;i++)
  { 
   sum[i]=0;
   c[i]=0;
  } 
   //Fill with last avDegrees
   d=avDegrees;//Put last degrees in again 
  }
         
  if (d>=0 && d<90){
  sum[0]+=d;
  c[0]++;
  } 
  if (d>=90 && d<180){
   sum[1]+=d;
   c[1]++;
  }
  if (d>=180 && d<270){
  sum[2]+=d;
  c[2]++;
  }
  if (d>=270 && d<=360){
  sum[3]+=d;
  c[3]++;
  }
 
 //No degrees found so exit function
  if (c[0]+c[1]+c[2]+c[3]==0)
  {
    bMultiPathAverage=false;
    avDegrees=cNodegrees;
    return avDegrees;
  }  
  
  //Find 2 adjacent kwadrants with hold most heading counts
     
  //Count all adjacents kwadrants
  xx[0]=c[0]+c[1];
  xx[1]=c[1]+c[2];
  xx[2]=c[2]+c[3];
  xx[3]=c[3]+c[0];
  
  //Find out in witch two kwadrants the most headings are
  for (byte i=0;i<4;i++){
    if (xx[i]>z){
    z=xx[i]; //Most adjacent Headings counts 
    y=i;     //Witch 2 adjacent Array Index from xx[1]
  }
 }

//Check for multipath kwadrants
switch(z){
case 0:
 z1=2;
 break;
case 1:
 z1=3;
 break;
case 2:
 z1=0; 
 break;
case 3:
 z1=1;
 break;
}

if (xx[z]==xx[z1])
{
 bMultiPathAverage=true;
}
else
{
 bMultiPathAverage=false;
}

//Average the 2 most counts kwadrants
switch(y){
case  0:
 avDegrees=(sum[0]+sum[1])/xx[y];
 break;
case 1:
 avDegrees=(sum[1]+sum[2])/xx[y];
 break;
case 2:
 avDegrees=(sum[2]+sum[3])/xx[y];
 break;
case 3:
  if (c[3]==0 && c[1]>0)
  {
   avDegrees=sum[1]/c[1];
  }
  else if (c[1]==0 && c[3]>0)
  {
   avDegrees=sum[3]/c[3];
  }
  else if (c[3]>0 && c[1]>0)
  {
   avDegrees=LimitDegrees360(((sum[3]/c[3])+((sum[0]/c[0])+360)/2));
  }

 break;
 }  
  return avDegrees;
} //Last Bracket Average

//--------------ToDo-----Doppler tone Amplitude--23-07-2015
//---Called  from Fn Squelch and Sub Loop
int AverageTone(int d)
{
static int AvTone=cNodegrees;
static int sum=0;
static int count=0;

if (d==cNodegrees)
{
AvTone=0;
sum=0; 
count=0;
return 0;
}  
else if (d==cReset)
{
sum=AvTone;
count=1;
return AvTone;
}  

sum +=d;
count +=1; 
AvTone=sum/count;

return AvTone; 
  
}//----------

//--SinCosDetector Find the degrees from the 4 Cap[] tensions
int SinCosDetector(){
  int SinSum; 
  int CosSum; 
  int effe;
   
  //In Cap[] is the tension value of 1 of the 4 C'S
 
  SinSum=Cap[0]-Cap[2];  
  CosSum=Cap[1]-Cap[3];

  if (SinSum==0 && CosSum==0){
  return cNodegrees;//No Signal
  }
  else
  {
  //Serial.println(atan2(SinSum,CosSum)*rad1); //Added 90 degrees so it's the same as zerocrossdetection
   return LimitDegrees360((atan2(SinSum,CosSum)*rad1)+90);
  } 
 }

//=============SerialRx Event=========================== 
void serialEvent() {
  while (Serial.available()) {
    //get the new byte:
    char inChar=(char)Serial.read();
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar=='z'||inChar=='\r'||inChar=='\n'||inputString.length() > 4 ){
      bStringComplete=true;
     }
     else
     {
      //add it to the inputString:
      inputString+=inChar;
     } 
  }
}
//=======================================================

//=========================================
boolean CheckOnlyNbr(String str){
//Check for only numbers 0 to 9 and -(asc 45) in the string 

//48=0 57=9
 for (unsigned j=0;j<str.length();j++){
   byte x=str.charAt(j);
   if ((x<48)||(x>57))
  {
   return false; 
  }
}
 return true;
}
  
//========================================
//------------------------------------Main Functions-----------------------------------------

//SetUp 
void setup() 
{
   Serial.begin(9600);                             // Opens serial port, sets data rate to 9600 bps
   Serial.println(F("((C))PA3BNX Arduino RDF"));
   
   if (bAnalogPelorus==false){Serial.println(F("Pin6 Ref freq"));}
   else {Serial.println(F("Pin6 Pelorus"));}
   
   //Led 13 Off No power consuming
   pinMode(13,OUTPUT);//SquelchLed
   digitalWrite(13,LOW);
   pinMode(refpa3bnx,OUTPUT);
   if (bAnalogPelorus==false){digitalWrite(refpa3bnx,0);}
   pinMode(max232Pin[0],OUTPUT);
   pinMode(max232Pin[1],OUTPUT);
   digitalWrite(max232Pin[0],LOW);
   digitalWrite(max232Pin[1],LOW);
   for (byte i=0;i<4;i++)
   {
     pinMode(antPin[i],OUTPUT); 
     pinMode(kPin[i] ,OUTPUT);
     digitalWrite(antPin[i],LOW);                  //antPin LOW = OFF
     //digitalWrite(kPin[i],LOW);                 //Set Cap pins to low so the can charge to 1/2U
   }
    EmptyCaps(); //1 sec charge to 1/2 U

   //EEprom values: StartTimer, CW and Calibrate 
   if (EEPROM.read(0)==ID)
   {
   StartTimer=EEPROM.read(cFreq);
   if(  EEPROM.read(cCW)>0)
   { 
   byte swap;
   swap=antPin[3];
   antPin[3]=antPin[1];
   antPin[1]=swap; 
   mLOW=1;
   mHIGH=0;
   }
   byte hi=EEPROM.read(cCal);
   byte lo=EEPROM.read(cCal+1);
   Calibrate=word(hi,lo);
   if (Calibrate<0 || Calibrate>360){Calibrate=0;}
    }
   else
   {
   //Default EEPROM now 
    EEPROM.write(0,ID);
    EEPROM.write(cFreq,StartTimer);
    EEPROM.write(cCW,0);
    EEPROM.write(cCal,0);
    EEPROM.write(cCal+1,0);
   }
 
   //Info on Screen
   Serial.print(F("Calibrate="));
   Serial.println(Calibrate);
   switch (StartTimer){
   case 131:
   Serial.print(F("500"));
   break;
   case 167:
   Serial.print(F("700"));
   break;
   case 187:
   Serial.print(F("900"));
   }
   Serial.println(F(" Hz"));
   if (EEPROM.read(cCW)==0){
    Serial.println(F("CW"));
    }
    else
    {
     Serial.println(F("CCW"));
    }
   //End Info on Screen
   
   Serial.println(F("%999"));  //Squelch always closed at start just before starting the loop  
 
   
   //Initial Setup Timer2 
   noInterrupts();
   TCCR2A=0;
   TCCR2B=0;
   TCNT2 = StartTimer;   //Begin value in timer count register
   TCCR2B |= (1<<CS22);  //Prescaler  256
   TIMSK2 = _BV(TOIE2);  //IRQ by overflow 0xFF -> 0x00  
   interrupts();   
}

//Main Loop
void loop(){
  // ToDo
  // GetCapValues
  // Squelch status
  // OverFlow Reset the 4 kwadrant capicitors EmptyCaps
  // Calibrate routine (add an degrees offset)
  // SinCosDetector 
  // Send (averaged) and calibrated degrees out through the serialport
  // Receive remote serial cmd's like CW/CCW ANT1,2,3,4 CW CCW LOW MID HIGH and Degrees  
  
   //Local variables
   boolean bSCF;                             //MuliPath SCF 
   byte swap; 
   int x1;                                   //SinCosDegrees 0-360
   static int x2=cNodegrees;                 //Averaged Degrees can be 999
   static int x3=cNodegrees;                 //Keep old degrees value so reduce Serial output
   static int tMaxTime=0;                    //Max Average count before reset   
 
   noInterrupts();
    //GetCapValues so the are not changed from here 
    Cap[0]=Corg[3];
    Cap[1]=Corg[2];
    Cap[2]=Corg[1];
    Cap[3]=Corg[0];
   interrupts();
           
   sqlstatus=Squelch();      //Squelch status check uses Cap[] values
  
  //Now Just Serial event and delay
  
  if (sqlstatus==cSqlOpenflutter)
  {
    //Serial.print("Flutter");
    tMaxTime+=1;
    goto further; 
  }  
    
  if (sqlstatus==cSqlclosed)
   {
    tMaxTime=0; 
   }
   else
   {
    tMaxTime+=1;             //Total loops to compared against cMaxTime
   }
    
  if (sqlstatus==cSqloverflow)
   {
     bNoAntScan=true;
     EmptyCaps();//Leaves all kPins HIGH 
     bNoAntScan=false;
     x3=cNodegrees;
   } 
 else 
  {
   //Relaxed sending degrees to serialport and Pelorus
   //static byte x3 = cNodegrees; //Keep old value so reduce serial and Pelorus output
   
   //Never add a MultiPath SCF value to Average 
   //Get Average degrees
   if (sqlstatus==cSqlclosed2open)
   {
    bSCF=MultiPathDetectSCF();
    if (bSCF==false)
    {
     x1=SinCosDetector();
     x2=Average(x1);
     //x2=x1;
    }
   }
   //Squelch closed 
   if (sqlstatus==cSqlopen2closed)
   {
    //Always Squelch Closed and Reset Average
    if (x3!=cNodegrees)
    {
    digitalWrite(13,LOW);//SquelchLed
    Serial.println(Format3Degrees(cNodegrees)); //Squelch Closed %999
    AnalogPelorus(cNodegrees);
    Average(cNodegrees); //Reset and set avDegrees to cNodegrees
    AverageTone(cNodegrees);//Reset doppler tone amplitude
    } 
    tMaxTime=0;
    x3=cNodegrees;
   }   
    //Squelch open
    else if (sqlstatus==cSqlclosed2open)
  { 
   //Show actuel degrees from average
   digitalWrite(13,HIGH);//SquelchLed
   if (bMultiPathAverage==false)
   { 
    //Never show twice the same average degrees
    if (x3!=x2)
   {
    //Never show cNodegrees here
    if (x2!=cNodegrees){
    Serial.print(Format3Degrees(Cali(x2)));//Show actuel degrees from average
    Serial.print(F(" [")); 
    Serial.print(AverageTone(cReset));//Show actuel Doppler tone amplitude 
    Serial.println(F("]"));
    AnalogPelorus(x2); 
   }                        
   }
   x3=x2;//Backup old degrees value
   }
  }
 } //Last Bracket Degrees   
 

further:

//Try to read Calibration, CW/CCW, AntTest, Timing(LMH), Calibrate Parameters 
//000<cr> <lf> from MyMapping.exe as calibrate cmd 

serialEvent();          //Call SerialEvent once in a while

if (bStringComplete==true){  
    //Swap 90 and 270 degrees pins  
 if (inputString=="CW" )
   { 
    Serial.println(inputString); 
    if (EEPROM.read(cCW)==1)
    {
    swap=antPin[1];
    antPin[1]=antPin[3];
    antPin[3]=swap;
    mLOW=1;
    mHIGH=0;
    //How switch max232pins?
    EEPROM.write(cCW,0); 
    Average(cNodegrees);
    tMaxTime=0;
    }
  }
  else if (inputString=="CCW" )
  {
    Serial.println(inputString); 
    if (EEPROM.read(cCW)==0)
    {
    swap=antPin[3];
    antPin[3]=antPin[1];
    antPin[1]=swap;
    mLOW=0;
    mHIGH=1;
    //How switch max232pins?
    EEPROM.write(cCW,1);
    Average(cNodegrees);
    tMaxTime=0;
    }
   }
  else if (inputString=="ANT1")
  {
  AntTest(0);
  } 
  else if (inputString=="ANT2")
  {
  AntTest(1);
  }
  else if (inputString=="ANT3")
  {
  AntTest(2);
  }
  else if (inputString=="ANT4")
  {
  AntTest(3);
  }
  else if (inputString=="OFF")
  {
   AntTest(255);
  } 
  else if (inputString=="LOW")
  {
     ISRset(500);
    //ToDo ISR 500 Hz
  }  
  else if(inputString=="MID")
  { 
   ISRset(700); 
  //ToDo ISR 700 Hz
  }
  else if (inputString=="HIGH")
  {
    ISRset(900);
    //ToDo ISR 900 Hz
  }  
  //Test input Averaging on/off
  else if (inputString=="AV")
  {
   if (bAverage==false)
   {Serial.println(F("Average"));
     bAverage=true;
     Average(cNodegrees);
   }
   else
   {
    Serial.println(F("No Average"));
    bAverage=false;
    bMultiPathAverage=false;
   }
   }  
  else //Now just numbers
  {
  //Try Calibrate offset
  if (CheckOnlyNbr(inputString)==true)
  { 
    //------------------
    int x;
    x=inputString.toInt();
    if (x>=0 && x<=360)
    { 
    Calibrate=x;
    x3=cNodegrees; //Next round always output degrees 
    byte hi = highByte(Calibrate);
    byte lo = lowByte(Calibrate);
    EEPROM.write(cCal,hi);
    EEPROM.write(cCal+1,lo);
    Serial.print(F("Calibrate="));
    Serial.print(Calibrate);
    //Also show the CW/CCW 21-07-2015
    if (EEPROM.read(cCW)==0){
    Serial.println(F(" CW"));}
    else{
    Serial.println(F(" CCW"));}
     //------------------
    }
   }  
  }
   //Now clear inputString because all done 
   inputString="";
   bStringComplete=false;
}

//Do always every loop 
//Reset
if(tMaxTime>=cMaxTime)
 { 
 tMaxTime=0; 
  if (sqlstatus==cSqlclosed2open)
  {
    Average(cReset); //Clear and Reset avDegrees with last value
    AverageTone(cReset);//Clear and Reset Doppler Amplitude Elevation
  }
 }

//Wait 250 a 1000 mSec for next try ? fast enough I think
delay(cMainLoopDelay);


} //End of sketch Last bracket of Loop
 
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Goos
Berichten: 338
Lid geworden op: 16 nov 2011, 20:45
Roepletters: pa0sir

Re: Super Simple Sound Doppler Peiler

#568 Bericht door Goos »

Hoi Lodewijk

Ooit wel eens van die meters gezien die 360 graden of zelfs nog iets meer konden doen, kon je eigenlijk geen draaispoelmeter noemen.
Maar ik neem aan dat dit niet voor een vaste opstelling is alleen voor homing in. anders kom je vroeg of laat in de problemen.

De Bendix peiler (vliegtuignavigatie, middengolf ) had vroeger een motor voor de aanwijzing, de traagheid was meteen de averaging.

gr
Goos
Peilen is het omgekeerde van een antennediagram opmeten.
pa0sir

PA3BAS
Berichten: 2609
Lid geworden op: 07 jan 2011, 22:19
Roepletters: PA3BAS
Locatie: JO21XX

Re: Super Simple Sound Doppler Peiler

#569 Bericht door PA3BAS »

http://digitalcommons.calpoly.edu/cgi/v ... ext=theses


Kwam ik tegen op een googlezoektocht. Er zijn mensen die promoveren op je software Dopp...:)
.... But will it blend?

Gebruikersavatar
pa8w
Berichten: 948
Lid geworden op: 22 dec 2011, 21:30
Roepletters: PA8W
Locatie: Beuningen
Contacteer:

Re: Super Simple Sound Doppler Peiler

#570 Bericht door pa8w »

Ik heb die thesis destijds ook gevonden en meneer Stieber medegedeeld dat ik zijn conclusies over de doppler techniek niet kon delen,
omdat ze zijn ontstaan op basis van een experiment waarin ik sowieso al 3 onvolmaaktheden zie:

1, hard switching met het ranzigste signaal wat ik ooit heb gezien, dus heel veel ongewenste mengproducten.
2, magneetvoeten die op VHF veel te weinig koppelen met het dak (aardvlak), kabels gaan dus die rol overnemen.
3, het gebruik van de zero-crossing detectie op een niet-sinusvormig signaal, hetgeen fikse afwijkingen oplevert, juist bij multipad signalen.
de Sin/Cos detector is de betere optie in Lodewijks software.

Stieber gaf toe dat zijn conclusies wellicht erg kort door de bocht waren, maar inhoudelijk ging hij niet op de materie in.

Volgens mij is hij wel geslaagd.... :wink:

Groet,
Wil.
Let op: website verhuisd naar: http://www.paluidsprekers.nl/pa8w/index.html

Plaats reactie