Super Simple Sound Doppler Peiler

Hardware en software.
Bericht
Auteur
Gebruikersavatar
pa8w
Berichten: 948
Lid geworden op: 22 dec 2011, 21:30
Roepletters: PA8W
Locatie: Beuningen
Contacteer:

Re: Super Simple Sound Doppler Peiler

#496 Bericht door pa8w »

Hoi allemaal,

@Egbert:
Ja, het kan altijd kleiner, maar dat is hier geen issue; de standaard Arduino is al kleiner dan het grafisch scherm.
Ik maak denk ik een soort sandwich van scherm, eigen print, Arduino.

@Goos:
Ik ga even voor eenvoud: Een 4-polig SCF-filter, dus een C per antenne, en een enkele buffer op-amp.
Dan moet dus de Arduino gesynchroniseerd worden om de 4 opeenvolgende samples te lezen van de 4 kwadranten.
Zou moeten kunnen.
Mocht dat een probleem zijn dan kan ik altijd per C een buffer plaatsen die ieder via een eigen input poortje wordt gelezen.
Dan vervalt de synchronisatie- eis.
Middelen gebeurt idd al in de C-s, maar ook nog door het instelbaar aantal samples die ik optel en middel (2 tot 20 of zo).
Daarachter zit nog een routine die de pelorus stroperig laat volgen; de pelorus sprong is altijd een breukdeel van de AOA sprong, zodat de pelorus vrij stroperig naar de "waarheid" loopt.
Beetje overkill denk ik maar daar moet ik gewoon in de praktijk mee stoeien.

@Lodewijk:
Kostprijs Arduino + scherm: net over de 20 euro.. :)
Elevatie-routine moet ik nog maken.

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

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

Re: Super Simple Sound Doppler Peiler

#497 Bericht door Goos »

Dan moet dus de Arduino gesynchroniseerd worden om de 4 opeenvolgende samples te lezen van de 4 kwadranten.
Zou moeten kunnen.
Hoeft niet gesynchroniseerd , je kunt dan gewoon met 4 ingangen werken, voor elke C een. je mag ze dan ook door elkaar uitlezen , maakt echt niet meer uit.
Ik zou ook niet te veel samples nemen per C , dit is niet nodig omdat de 10 bits al voldoende resolutie geven om binnen de graad nauwkeurig te zijn ( wat rekenen betreft natuurlijk )

Als je de Q van het scf laag houd kun je met de Arduino de middeling gaan bepalen , met een up/down knopje o.i.d. in de geest van 1 2 4 8 16 32 etc. Is telkens 6dB s/r verbetering.

Wat dat stroperige betreft (niet voor mobiel denk ik ):
Als je de de wortel uit de som vd kwadraten van X en Y voor uitrekent voor de laatste "omwenteling" en die deelt door het gemiddelde van de vorige 3. en dit X 100%.
Dan heb je een criterium om bv de Xtot en Ytot buffer leeg te maken. Je moet dan denken aan bv 10%
Dit kun je gebruiken als een soort squelch voor allerlei toepassingen bv
1 buffer niet leegmaken voor onderbroken signalen uit dezelfde richting
2 buffer wel leegmaken voor signalen met onderbrekingen uit verschillende richtingen ( packet )
3 stoppen onder een bepaalde waarde ( squelch ) (alleen de wortel(X^2+Y^2) )

Goos
Peilen is het omgekeerde van een antennediagram opmeten.
pa0sir

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

Re: Super Simple Sound Doppler Peiler

#498 Bericht door pa8w »

Ja, ok Goos,

Ik moet een buffer gebruiken omdat ik daarna een spanningsdeler toepas om binnen de 5V voor de Arduino te blijven.
Met een enkele buffer zoals in mijn klassieke dopplers verschijnt aan de uitgang een trapsgewijze presentatie van de spanningswaarden van alle C-s.
Derhalve moet de Arduino dan mooi op de juiste momenten 4 achtereenvolgende samples nemen.
Gesynchroniseerd dus.
Met een eigen buffer+spanningsdeler per C kan dit inderdaad asynchroon en in willekeurige volgorde.

Ik kan overigens ook met de ingangsbuffer bepalen dat de C's niet hoger dan 5V kunnen worden geladen, dan vervalt de noodzaak voor de buffer(s). Lijkt me eigenlijk nog wel de beste optie.
Dank voor je input!

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

EA5JEX
Berichten: 1472
Lid geworden op: 14 nov 2007, 18:56
Roepletters: pa5cw
Locatie: Pedralba Valencia Spanje

Re: Super Simple Sound Doppler Peiler

#499 Bericht door EA5JEX »


Gebruikersavatar
PE2AAB
Moderator
Berichten: 7117
Lid geworden op: 12 apr 2005, 19:06
Roepletters: PE2AAB
Locatie: Aalst - Waalre
Contacteer:

Re: Super Simple Sound Doppler Peiler

#500 Bericht door PE2AAB »

pa5cw schreef:Kennen jullie dit ontwerp?
http://iphone-atom1945.blogspot.nl/2014 ... -nano.html
Dat ziet er wel gaaf uit! Wil ik mijn Nano wel eens voor gaan 'misbruiken' ;-)

Bouwpakketjes zijn al verkrijgbaar!
http://iphone-atom1945.blogspot.nl/2014 ... n-usa.html

Afbeelding

Afbeelding
'73 Rick, PE2AAB www.pe2aab.nl

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

Re: Super Simple Sound Doppler Peiler

#501 Bericht door Dopp »

Hallo Allemaal,


Tsja dat Luca Ontwerp hebben wij al een tijdje geleden in deze thread behandeld hi...

jackdev23 eevblog
Copyright 2014 Luca Facchinetti, IW2NDH
IW2NDH
http://youtu.be/jm0Q4p4GudA?list=UU17SR ... Brsh_ak_sQ
Nadeel is de antenne switcher unit en aansturing die is gewoon slecht bij IW2NDH

Ik ben ook met software bezig voor de arduino uno r3 ....


Zit nog te stoeien met de 4 c's

hoe ze te resetten hi (lees leegmaken ontladen)

Dat is dus een hardware kwestie denk ik.....

Mijn software voor de arduino wordt dus een SuperSimpleArduinoDoppler

met de rs232/USB aan de PC met mijn programma MyMapping
wat ondertussen een hele mooie opacity pelorus heeft...

Ik denk Wil dat we de pin bezetting gelijk moeten houden aan elkaars ontwerp

wat betreft de 4 c's en de inputs en de antenne output control lijnen.

Ik zou mijn ontwerp dus het instap model willen noemen waar je toch een PC bij nodig hebt
maar geen Soms lastige Stereo input geluidkaart op een PC

Ik wil geen enkele knop extra monteren aan de arduino.

Ook geen calibratie en.of cw/ccw hardware knop/potmeter.

Dus de arduino uno r3 kaal
met minimale extra hardware
73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Gebruikersavatar
PE2AAB
Moderator
Berichten: 7117
Lid geworden op: 12 apr 2005, 19:06
Roepletters: PE2AAB
Locatie: Aalst - Waalre
Contacteer:

Re: Super Simple Sound Doppler Peiler

#502 Bericht door PE2AAB »

Ik ben zeer benieuwd Lodewijk ;-)

Vandaag even met mijn Arduino Nano aan het stoeien geweest. Dat rotding vergeet telkens zijn eigen Hardware ID waardoor elke keer als ik de USB kabel in de laptop steek e.e.a. moet worden geïnstalleerd. Dat lukt dan vervolgens niet omdat de PC de hardwareID weer niet herkent. Vaag probleem waar veel over wordt geschreven op internet.
Oplossing heb ik gevonden door de hardwareID waarop de arduino telkens terugvalt toe te voegen aan de drivers ;-)
Beetje voor de gek houden dus maar daarna was het probleem wel verholpen ;-) Als iemand de INF bestandjes wil hebben moet ie maar even mailen.

Nou ja. Als je dus iets met een Arduino en een mooi display hebt dan houd ik me aanbevolen. Mooi schermpje in de auto en peilen maar die lastpakken op de paal van Utrecht ;-)
'73 Rick, PE2AAB www.pe2aab.nl

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

Re: Super Simple Sound Doppler Peiler

#503 Bericht door Dopp »

Hallo Allemaal,


Alvast een voorproefje van mijn Arduino SuperSimpelArduinoDoppler
software.

Pin nummers enzo zijn nog niet okay gezet
en de ISR routine moet nog..

Dit is maar een beginnetje.

Zullen nog meer fouten enzo inzitten...


Belangrijke functies zijn:

Format3Degrees
SetAntennePins
SinCosDetector
LimitDegrees360
Squelch
Average
EmptyCaps




Dus kijk maar is of je het snapt hi wat ik allemaal doe...



How me aanbevolen voor tips etc....

Not ready to run Yet this code.


Code: Selecteer alles



/*
  ((C))PA3BNX 
  Trying to create a SuperSimpleArduinoDoppler on Arduino Uno R3
  @12-04-2015
  Not ready yet!
*/

//Const Integer
//Antenna Control Pins & refpa3bnx
const int antPin[] = {2,3,4,5};
const int refpa3bnx = 6;

//Kwadrant Capicity switches & analogue SCF read pin
const int kPin[] = {7,8,9,10};
const int kPinAnalog = 11;
const int offset = 511;    //.5 * 1023 caps offset  
//Signals
const int sqlclosed = 0;
const int sqlclosed2open = 1;
const int sqlopen2closed = 2;
const int sqloverflow = 3;          //Capicitors are full
//
const int cNodegrees = 999;         //Squelch No Signal or sqlopenclosed
//MaxMinValues
const int MaxAveragedCount = 100;   //Before Reset Average to only last Degrees in Average()
const int MaxAudioAmplitude = 1023; //Max (Voltage?) analoge value
const int MinAudioAmplitude = 300;  //There is signal to SinCosDetect

//Float const
const float pi = 4 * atan(1);
const float rad = pi/180;
const float rad1 = 180/pi;
const float TwoPi = 2 * pi;

//Bool
boolean bMultiPath = false;

//Array with the 4 kwandrants tension
int Cap[] = {0,0,0,0};

//Integer
int DopplerFreq = 500; //Frequency in Hz
int DopplerISRtics;    //Calc in SetUp() 

int Quality = 0;  
int sqlstatus = sqlclosed; 


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

//Antenna Control Lines Just counts 1234 1234 etc
void SetAntPins(int t){
switch (t){
  case 0:
  digitalWrite(antPin[1], HIGH);
  digitalWrite(antPin[4], LOW);
  digitalWrite(refpa3bnx,HIGH);
  break;
case 1:
  digitalWrite(antPin[2], HIGH);
  digitalWrite(antPin[1], LOW);
  break;
 case 2:
  digitalWrite(antPin[3], HIGH);
  digitalWrite(antPin[2], LOW); 
  digitalWrite(refpa3bnx,LOW);
  break;
 case 3:
  digitalWrite(antPin[4], HIGH);
  digitalWrite(antPin[3], LOW);
  break;
}
}

//Get 4 Cap Value's in Cap[]
void GetCapValues(){
 
  for (int i=1; i<4; i++)
 {
   digitalWrite(kPin[i],LOW); 
 }


  digitalWrite(kPin[1],HIGH);
  Cap[1]  = analogRead(kPinAnalog);  
  
  digitalWrite(kPin[1],LOW);
  digitalWrite(kPin[2],HIGH);
  Cap[2]  = analogRead(kPinAnalog);  
  
  digitalWrite(kPin[2],LOW);
  digitalWrite(kPin[3],HIGH);
  Cap[3]  = analogRead(kPinAnalog);  
  
  digitalWrite(kPin[3],LOW);
  digitalWrite(kPin[4],HIGH);
  Cap[4] = analogRead(kPinAnalog);  
  digitalWrite(kPin[4],LOW); 
 
}


//Empty the 4 capicitors by discharging 
void EmptyCaps(){

pinMode(kPinAnalog ,OUTPUT);
digitalWrite(kPinAnalog,LOW);

for (int i=1; i<4; i++)
{
 pinMode(kPin[i],LOW);
 delay(200); //mSec's
}  

pinMode(kPinAnalog,INPUT);

}  


//-------------Squelch-----------------------
int Squelch(){
//Returns the sqlstatus
//Try Find a full cap   
 int x;
 
 for(int i=1; i<4; i++)
 {
  if (Cap[i] >= MaxAudioAmplitude )
  {
   x = Cap[i];
  }
 }
 
 
 //See if there is a Full Cap 
 if (x >= MaxAudioAmplitude)
 {
  return sqloverflow;
 //Caps are full so need emptied
 
 }
 else if (x >= MinAudioAmplitude)
 {
  return sqlclosed2open;
 }
 else if (x < MinAudioAmplitude)
 {
  return sqlclosed;
 }

}


//Return Agrelo formatted string % and 3 digits always
  char* Format3Degrees(int degrees){
  int digits[3];
  int reminder ;  
  digits[1]=degrees/100;
  reminder = degrees % 100;
  digits[2]= reminder/10;
  reminder = reminder % 10;
  digits[3]=reminder;
  
  char str[4] = {'%','digit[1]','digit[2]','digit[3]'};
  return str;
}

//Limit Degrees 0 to 360 degrees
int LimitDegrees360(int d){
  //Limit degrees 0 to 360 here
  if (d >= 720){
  return d - 720;
  }
  else if (d >= 360){
  return d - 360;
  }
  else if (d <= 720){
  return d + 720;
  }
  else if (d <= 360){
  return d;
  }
 return cNodegrees;  
}


//Average
int Average(int d){
  //If d = 999 then reset average
  //Else return averaged degrees
  
  //Integer
  static int sum[4];
  static int c[4];
  int xx[4] ={0,0,0,0};
  int z = 0;
  int z1 = 0;
  int y = 0; 
  int avDegrees; 

//Limit amount off averaged headings
if  (c[1]+c[2]+c[3]+c[4] > MaxAveragedCount){
 for (int i = 1; i < 5 ; i++){
 c[i]=0;
 sum[i]=0;
 }
}

  if (d!=cNodegrees){
   
  if (d >= 0 && d < 90){
  sum[1] += d;
  c[1]++;
  } 
  if (d >= 90 && d < 180){
   sum[2] += d;
   c[2]++;
  }
  if (d >= 180 && d < 270){
  sum[3] += d;
  c[3]++;
  }
  if (d >= 270 && d <= 360){
  sum[4] += d;
  c[4]++;
  }
  }
 else
 {
 //Reset
  for (int i=1; i<4; i++){ 
  sum[i]=0;
  c[i]=0;
  bMultiPath = false;
 }
 return cNodegrees;
}

  //Find 2 adjacent kwadrants with hold most counts
     
  //Count all adjacents kwadrants
  xx[1] = c[1]+c[2];
  xx[2] = c[2]+c[3];
  xx[3] = c[3]+c[4];
  xx[4] = c[4]+c[1];
  
  //Find out in witch two kwadrants the most headings are
  for (int i=1; i<=4; i++){
    if (xx[i] >= z){
    z = xx[i]; //Most Headings
    y = i;     //Witch Array Index
  }
 }
 

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

if (z > z1){
bMultiPath = true;
}
else
{
bMultiPath = false;
}

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


//SinCosDetector Find the degrees from the 4 Cap[] tensions
int SinCosDetector(){
  int x; 
  int y;
  int SinSum; 
  int CosSum; 
  int d;
  float z;

//In Cap[] is the tension value of 1 of the 4 C'S
//Not okay yet!
for (int i = 1; i<4;i++){
 z = TwoPi *  (i / 4);  
 SinSum +=   Cap[i] * sin(z);  
 CosSum +=   Cap[i] * cos(z);
}

  
if (SinSum == 0 && CosSum == 0){
 return cNodegrees;
}

//Never division by zero
if (CosSum == 0){
 z = 100000;
}
else
{
 z = SinSum / CosSum;
} 

//Never endless
if (SinSum == 0) {
 z = .0001;
} 
else
{
z = SinSum / CosSum;
}
  
  x =  atan(z) * rad1;
  
  if (SinSum<0 && CosSum<90){d=90 - abs(x); return d; } 
  if (SinSum>0 && CosSum>90){d=90 + x;return d;} 
  if (SinSum<0 && CosSum<90){d=270 + x;return d;} 
  if (SinSum>0 && CosSum<90){d=270 + x;return d;} 
}



//------------------------------------Main Functions-----------------------------------------

//SetUp 
void setup() 
{
  // Loop over the pin array and set them all to output:
   Serial.begin(4800); // Opens serial port, sets data rate to 4800 bps
   Serial.println("((C))PA3BNX Arduino Doppler");
   pinMode(refpa3bnx,OUTPUT);
   pinMode(kPinAnalog, OUTPUT);  
   pinMode(refpa3bnx,OUTPUT);
   pinMode( kPinAnalog,INPUT); //Okay here ????
    for (int i=1; i<4; i++){
     pinMode(kPin[i],OUTPUT); 
     pinMode(antPin[i] ,OUTPUT);
   }
   SetAntPins(4);       //Set antPins to LOW   
   Average(cNodegrees); //Reset all to 0 
 }

//Main Loop
void loop() {
  // ToDo
  // Set the ant1,2,3,4 and refpa3bnx  pins
  // Squelch status
  // OverFlow Reset the 4 kwadrant capicitors
  // SinCosDetector 
  // Send (averaged) degrees out through serialport
  
 
   //Integer
   static int c; 
   int degrees = 0;   
   
   
   //ToDo
   //ISR Do this at regular intervals Timer Interrupt Controlled
   //DopplerFreq DopplerISRticks ??
  
 
   if (c == 3) {
     c = -1;
   } 
  GetCapValues();
  SetAntPins(c);
  
  
  
  
  sqlstatus = Squelch();
  
  if (sqlstatus == sqloverflow)
  {
    EmptyCaps(); 
  } 
 else
 {
 degrees = SinCosDetector();

 //Relaxed sending to comport
 if (sqlstatus == sqlopen2closed && bMultiPath == false)
 { 
  Serial.println(Format3Degrees(Average(degrees)));
  sqlstatus = sqlclosed;
  c++;
 }
 }
}

//End of sketch 
 
 
 
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

#504 Bericht door Dopp »

Hallo Allemaal,

Heb alweer een hoop gedaan/verandert aan de software sketch in de Arduino Uno R3
sinds de laatste upload hierboven.

Heb nog niet duidelijk dat een arduino zgn
TRIState pinnen heeft...


Ik wil immers de kwadranten 4 c's ieder afzonderlijk kunnen laten zweven
en naar massa leggen.

Maar ik zou ze ook willen kunnen ontladen...(tot halve voedingsspanning 2.5V)
bij een overflow van een kwadrant bijvoorbeeld.

Daar moet ik nog mee aan de stoei hi

Voor Wil kun je ook een average bug maken rondom de Pelorus ?

De arrow dus de actuele waarde en de bug de averaged waarde.

En de digitale uitlezing eigenlijk op het scherm altijd met 3 digits.

Dat leest nu eenmaal simpel af..

Omdat mijn GPS muis zelf een USB stekker heeft
maak ik een tweede compoort input in Mymapping programma

Dat word dan dus ahw een Arduino Agrelo poort...

Met een terminal in Mymapping die commando's naar de arduino kan sturen
voor bv Calibratie en CW/CWW draaiende doppler antenne array.

Dus dat wordt dan MyMapping1.54.exe hi...


It's programming Time Now !!!
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

#505 Bericht door Goos »

Eindelijk even tijd gehad.

Dit is mijn versie voor een amplitude peiler met de Arduino.
Het is eigenlijk meer een werkend concept waar nog van alles aan toegevoegd kan worden.

Voordeel van dit systeem is dat er geen Noord kalibratie nodig is.
De DF spanning wordt afgeleid van de RSSI spanning van de ontvanger ( Log uitgang ) Deze moet wel eerst gekalibreerd worden. Bij mij was de factor 0.4 dB / stapje vd AD-convertor bij 8 bits
Ik heb hiervoor een ontvanger gebruikt met een AD-8307 dit is over +/- 90 dB.Beter is het om nog een opamp er achter te zetten om de volledige 5 volt te benutten.
Vanwege ruimte gebrek voor de array gebruik ik maar 8 bits

Het gaat ook met de AGC van de ontvanger ( moet wel blijven werken bij FM ). De tijdconstanten moeten dan wel aangepast worden ( snel op , "lang" hangen , langzaam afvallen )
De array voor log-> lin kan dan vervallen en kan de AD waarde direct gebruikt worden.

Uitlezing is nog heel prematuur , het venstertje v/d onwikkelomgeving. of UDP
Geprobeerd alles zo overzichtelijk neer te zetten zodat het eenvoudig aan te passen is aan de wensen.

De delay na het schakelen vd antenne is om de vertraging in het filter te compenseren en om uitslinger verschijnselen buiten de samples te houden. ( gaat goed t/m ssb filter )

Code: Selecteer alles

/*
PAo-SIR-Watson-Watt Direction finder
Author; G.L.H. Visser PAoSIR.

Pin ~5 Sin control antenna
Pin ~6 Cos Control antenna
Pin A0 Analog input from Log Detector ( rssi )

 */

// the setup routine runs once when you press reset:
	// voor ethernet 
	//#include <SPI.h>

	//#include <Ethernet.h>

	//#include <EthernetUdp.h> 
	//byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

	//byte ip[] = { 192,168,1,110};

	//EthernetUDP Udp; 

#include <math.h>

float lin[256];
float hoek=0;
long Uant1=0;
long Uant2=0;
long Uant3=0;
long Uant4=0;
byte samp = 16;
int wachten =500;
float Xval=0;
float Yval=0;
int average=64;

void setup() {
	//Ethernet.begin(mac, ip);

	//Udp.begin(8888); 

 // initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(5 , OUTPUT);
pinMode(6 , OUTPUT);



for( int i = 0 ; i < 256 ; i++ ){
Serial.println(i);
lin[i]= pow(10 , (float)i*0.4237/20);
// 0.4237 is de factor dB/stapje bij 8 bits ( AD8703 )
}

}




// the loop routine runs over and over again forever:
void loop() {


  ant1();
  Uant1=0;
  for(int  x = 0 ; x < samp ; x++){
      Uant1 = Uant1+ lin[analogRead(A0)>>2];
  }


 ant2();
 Uant2=0;
  for(int x = 0 ; x < samp ; x++){
      Uant2 = Uant2 + lin[analogRead(A0)>>2];
  }

 ant3();
 Uant3=0;
  for(int x = 0 ; x < samp ; x++){
    Uant3  = Uant3 + lin[analogRead(A0)>>2];
  }

 ant4();
 Uant4=0;
  for(int x = 0 ; x < samp ; x++){
      Uant4 = Uant4 + lin[analogRead(A0)>>2];
  }

// volgende 2 regels is een 1 op 1 vervanging van het gebruikelijke scf
Yval = Yval+Uant1-Uant3-Yval/average;
Xval = Xval+Uant2-Uant4-Xval/average;

 hoek = atan2(Yval , Xval)*180/3.14159;
if (hoek <0 ){hoek=hoek+360;}

Serial.println(int(hoek));
	//Udp.beginPacket("192.168.1.106",8888);


	//Udp.print(String(int(hoek)));

	//Udp.endPacket(); 
}




// de rest zijn functies voor het schakelen vd antenne omschakeling om het overzichtelijk te houden

void ant1(){
 digitalWrite(5, HIGH);
 digitalWrite(6, HIGH);
delayMicroseconds(wachten);
}

void ant2(){
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
delayMicroseconds(wachten);
}
void ant3(){
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  delayMicroseconds(wachten);
}
void ant4(){
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
delayMicroseconds(wachten);
}
PA0_SIR_Watson_Watt.jpg
PA0_SIR_Watson_Watt.jpg (17.28 KiB) 5393 keer bekeken
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

#506 Bericht door Dopp »

Hallo Allemaal,


Mooi Goos die Am peiler sketch

Daar is de timing preciesie niet zo van belang.

Bij de doppler is de timing wel van belang
Ik wil iets doen met Timer Interrupts om de
antenne control signalen te roteren met ca 500 Hz.

De C' s laden per kwadrant en dan na bepaalde tijd
de analoge waardes uitlezen van de 4 capaciteiten

En dan zorgen dat de C's niet vast gelopen zijn tegen de voedings spanning

En als er een vastloper overflow kwadrant is de 4 c's dan ontladen tot weer 1/2 U

Ik dac ht oa ook aan een diode in serie met de - van de elcootjes
zodat als het kwadrant pootje hoog is de elco's zweven
en als het laag is dan worden ze geladen.

Dan hoef ik niet om te schakelen van Output naar input zonder pullup hi...


Tsja ik zal jou code nog is precies uitpluizen


Onder tussen vandaag bezig geweest met een tweede COM/USB poort
in mijn Mymapping kaarten programma zodat een GPS muis met USB direct
op de PC kan en op een andere poort van de PC de USB/COM van de Arduino...
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

#507 Bericht door Goos »

Wat mij het beste lijkt ( van afstand ) dat je op de discriminator een vaste uitgang maakt met een opamp, voordeel is dat deze onafhankelijk is van volume regeling toonregeling en alles wat invloed heeft op de delay.
Eventueel met een paar vaste keuze instellingen voor de amplitude i.v.m. een hogere frequentie.
Een jaar of 20 geleden dit programmaatje ontwikkeld ,gedeeltelijk in ASM en qbasic voor de R9000 van Icom.
Op de accesoire plug de extra uitgangen gemaakt met een stropje voor de instellingen voor de hang-AGC. Plugje eruit en alles weer normaal. vraag me niet meer hoe , te lang geleden. Ging tot mijn verbazing ook goed met SSB


Verder de schakeling gebruiken met clock en 4017 voor de antennesturing en het scf , voor het scf zou ik kiezen voor een 4066
De C'tjs groot kiezen en een kleine RC-tijd , niet veel groter dan 50 milisec. ( experimenteren ) zodat de hoogste modulatie er al grotendeels uitgefilterd is
en dan kun je gewoon mijn sketch of variant gebruiken , zonder de antennesturing natuurlijk en met 4 analoge ingangen
De truuk is dat je volledig asynchroon mag aftasten. Met Arduino bepaal je de middeling. en hoe vaak je wilt uitrekenen
Dat uitrekenen kost namelijk te veel tijd om ea synchroon te kunnen doen.

De AD ingangen zijn redelijk hoogohmig > 100k , maar er moet net voor de conversie een C'tje opgeladen worden ( sample and hold ) via 10 k wel eens waar maar een kleintje maar , meestal verraad deze zich wel op de scoop maar heb het niet waargenomen. Wat wel in de specs staat dat ze het liefst een laagohmige bron zien. Vandaar de grote C's voor het scf

datasheet vd Amtel
http://www.atmel.com/images/Atmel-8271- ... mplete.pdf

Op blz 77 staat iets over tri-state is wel mogelijk dus, maar hoeft denk ik niet.
Op blz 244 staat de belangrijkste info over de ADconvertor.

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

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

Re: Super Simple Sound Doppler Peiler

#508 Bericht door pa8w »

Hoi luitjes,

Lekker actief allemaal!
Ik gebruikt de Tone functie van de Arduino om een clocksignaal te genereren, die ik vervolgens met een deler-ic (4040) opdeel naar 2 adreslijntjes, die dan weer een 4052 bilateral switch sturen.
Deze 4052 werkt voor de helft als SCF, de andere helft stuurt de antennedrivers aan.

Die Tone functie is een hardware voorziening in de Arduino dus niet afhankelijk van timing/vertraging door software.

Maar er zijn natuurlijk vele oplossingen denkbaar.

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

#509 Bericht door Dopp »

Hallo Allemaal,


Alvast een idee voor wat er allemaal op het arduino shield zou moeten komen.

Voor de audio input naar de 4 c's
zit er een discharge transistor op.

Misschien niet nodig als je ervan uitgaat
dat als je alle 4 de c's aan massa legt en effe wacht

dan zullen de c's vanzelf naar 1/2 U gaan
ondanks data er wat audio uit de speaker op staan (PAFYM Hint)

Maar goed nu zit er dus een extra rapide discharge(1/2U) transistor bij op...



ook de de verbeterde uitgebreide Arduino Sketch.

Nog niet getest en gebouwd alles hi...
Maar dat gaat wel komen binnenkort


Code: Selecteer alles


/*
  ((C))PA3BNX 
  Trying to create a SuperSimpleArduinoDoppler on Arduino Uno R3
  @12-04-2015
  @13-05-2015
  @15-05-2015
  @17-05-2015
  No Calibration throug serialPort yet
  No CW/CCW through serialPort yet
  Not ready yet!
*/

//Byte= 0 >255
//Int=  -32768>32767


//Const Integer
//Antenna Control Pins & refpa3bnx
const byte antPin[] = {2,3,4,5}; //Set antenna control pins pins 
const byte refpa3bnx = 6;        //Pin for Referency frequency output to soundcard   

//Kwadrant Capicity switches & analogue SCF read pin
const byte kPin[] = {7,8,9,10,11}; //4 pins caps 4u7 Last Pin in array = Discharge
const byte kPinAnalog = 0; //A0 read voltage acros 1 4u7 pin 0 to 5
const int offset = 511;    //.5 * 1023 caps offset  

//Signals
const byte sqlclosed = 0;
const byte sqlclosed2open = 1;
const byte sqlopen2closed = 2;
const byte sqloverflow = 3;          //Capicitors are full
//
const int cNodegrees = 999;         //Squelch No Signal or sqlopenclosed
//MaxMinValues
const int MaxAveragedCount = 100;   //Average to only last Degrees in Average()
const int MaxAudioAmplitude = 511;  //Max (Voltage?) analoge value
const int MinAudioAmplitude = 100;  //There is signal to SinCosDetect

//Float const
const float pi = 4 * atan(1);
//const float rad = pi/180;
const float rad1 = 180/pi;
//const float TwoPi = 2 * pi;

//Bool
boolean bMultiPath = false;

//Array with the 4 kwandrant tensions
int Cap[] = {0,0,0,0};

//Integer
int KwartDopplerPerioduSec = 8000; // 4/500 = 0.008 Sec  @ 500 Hz
unsigned long StartTimer;
unsigned long MaxTime ;

byte Quality = 0; //Not used yet 
byte sqlstatus = sqlclosed; 


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

//Antenna Control Lines Just counts 1234 1234 etc
void SetAntPins(byte t){
static byte tt; 
 //Do never set twice the same pins states
 if (t != tt){ 
  
 switch (t){
  case 0:
  digitalWrite(antPin[1], HIGH);
  digitalWrite(antPin[4], LOW);
  digitalWrite(refpa3bnx,HIGH);
  tt=t;
  break;
case 1:
  digitalWrite(antPin[2], HIGH);
  digitalWrite(antPin[1], LOW);
  tt=t;
  break;
 case 2:
  digitalWrite(antPin[3], HIGH);
  digitalWrite(antPin[2], LOW); 
  digitalWrite(refpa3bnx,LOW);
  tt=t;
  break;
 case 3:
  digitalWrite(antPin[4], HIGH);
  digitalWrite(antPin[3], LOW);
  tt=t;
  break;
}
}
}

//Get 4 Cap Value's in Cap[]
void GetCapValues(){
 
  for (byte i=0; i<4; i++)
 {
   digitalWrite(kPin[i],LOW); 
 }


  digitalWrite(kPin[1],HIGH);
  Cap[1]  = analogRead(kPinAnalog)-offset;  
  
  digitalWrite(kPin[1],LOW);
  digitalWrite(kPin[2],HIGH);
  Cap[2]  = analogRead(kPinAnalog)-offset;  
  
  digitalWrite(kPin[2],LOW);
  digitalWrite(kPin[3],HIGH);
  Cap[3]  = analogRead(kPinAnalog)-offset;  
  
  digitalWrite(kPin[3],LOW);
  digitalWrite(kPin[4],HIGH);
  Cap[4] = analogRead(kPinAnalog)-offset;  
  digitalWrite(kPin[4],LOW); 
 
}


//Empty the 4 capicitors by discharging to 1/2 U
void EmptyCaps(){
  
for (byte i=0; i<4; i++)
{
 pinMode(kPin[i],LOW);
 delay(200); //mSec's
}  

digitalWrite(kPin[5],HIGH);
delay(2000); //Let the 4 caps charge to 1/2 U  to 99%  5 * (22k * (4,7uF * 4))  2068 Sec
digitalWrite(kPin[5],LOW);
}  


//-------------Squelch-----------------------
int Squelch(){
//Returns the sqlstatus
//Try Find a full cap   
 int x;
 
 //Find cap with most tension
 for(byte i=0; i<4; i++)
 {
  if abs((Cap[i]) >= MaxAudioAmplitude )
  {
   x = abs(Cap[i]);
  }
 }
 
 
 //See if there is a Full Cap 
 if (x >= MaxAudioAmplitude)
 {
  return sqloverflow;
 //Caps are full so need emptied
 
 }
 else if (x >= MinAudioAmplitude)
 {
  return sqlclosed2open;
 }
 else if (x < MinAudioAmplitude)
 {
  return sqlclosed;
 }

}


//Return Agrelo formatted string % and 3 digits always
  char* Format3Degrees(int degrees){
  int digits[3];
  int reminder ;  
  digits[1]=degrees/100;
  reminder = degrees % 100;
  digits[2]= reminder/10;
  reminder = reminder % 10;
  digits[3]=reminder;
  
  char str[4] = {'%','digit[1]','digit[2]','digit[3]'};
  return str;
}

//Limit Degrees 0 to 360 degrees
int LimitDegrees360(int d){
  //Limit degrees 0 to 360 here
  
if (d >= 360){
  return d - 360;
  }
  else if (d < 360)
  {
  return d;
  }
  else if (d < 0)
  {
  return 360 + d;
  }
  else
  {
  return cNodegrees;  
  }
}

//Average
int Average(int d){
  //If d = 999 (cNoDegrees) then reset average
  //Else return averaged degrees
  
  //Integer
  static int sum[4];
  static int c[4];
  int xx[4] ={0,0,0,0};
  int z = 0;
  int z1 = 0;
  int y = 0; 
  int avDegrees; 


 //Limit amount off averaged headings
 if  (c[1]+c[2]+c[3]+c[4] > MaxAveragedCount){
  for (byte i = 0; i < 4 ; i++){
   sum[i]=0;
   c[i]=0;
  return cNodegrees;
 }
}


  if (d!=cNodegrees){
   
  if (d >= 0 && d < 90){
  sum[1] += d;
  c[1]++;
  } 
  if (d >= 90 && d < 180){
   sum[2] += d;
   c[2]++;
  }
  if (d >= 180 && d < 270){
  sum[3] += d;
  c[3]++;
  }
  if (d >= 270 && d <= 360){
  sum[4] += d;
  c[4]++;
  }
  }
 else
 {
 //Reset
  for (byte i=0; i<4; i++){ 
  sum[i]=0;
  c[i]=0;
  bMultiPath = false;
 }
 return cNodegrees;
}

  //Find 2 adjacent kwadrants with hold most counts
     
  //Count all adjacents kwadrants
  xx[1] = c[1]+c[2];
  xx[2] = c[2]+c[3];
  xx[3] = c[3]+c[4];
  xx[4] = c[4]+c[1];
  
  //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 Headings
    y = i;     //Witch Array Index
  }
 }
 

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

if (z > z1){
bMultiPath = true;
}
else
{
bMultiPath = false;
}

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


//SinCosDetector Find the degrees from the 4 Cap[] tensions
int SinCosDetector(){
  int SinSum; 
  int CosSum; 
  int x;
//In Cap[] is the tension value of 1 of the 4 C'S

SinSum = Cap[1] - Cap[3];  
CosSum = Cap[2] - Cap[4];
  
if (SinSum == 0 && CosSum == 0){
 return cNodegrees;
}

return LimitDegrees360(atan2(SinSum,CosSum) * rad1);
 
}



//------------------------------------Main Functions-----------------------------------------

//SetUp 
void setup() 
{
  // Loop over the pin array and set them all to output:
   Serial.begin(4800); // Opens serial port, sets data rate to 4800 bps
   Serial.println("((C))PA3BNX Arduino Doppler");
   pinMode(refpa3bnx,OUTPUT);
   pinMode(kPinAnalog, INPUT);  
   pinMode(refpa3bnx,OUTPUT);
   pinMode( kPinAnalog,INPUT); //Okay here ????
   pinMode(kPin[5],OUTPUT);//Discharge Pin
   for (byte i=0; i<4; i++){
     pinMode(kPin[i],OUTPUT); 
     pinMode(antPin[i] ,OUTPUT);
     digitalWrite(kPin[i],LOW);  //Set Cap pins to low so the can charge to 1/2U
   }
   SetAntPins(4);       //Set antPins to LOW   
   Average(cNodegrees); //Reset all to 0 
   EmptyCaps; //All kPins to 1/2 U
 
   
   MaxTime = KwartDopplerPerioduSec * 4 * 1000000 * 15; //15 Secondes max before EmtyCaps
   StartTimer = micros()+ KwartDopplerPerioduSec;
  }

//Main Loop
void loop() {
  // ToDo
  //GetCapValues
  // Set the ant1,2,3,4 and refpa3bnx  pins
  // Squelch status
  // OverFlow Reset the 4 kwadrant capicitors
  // SinCosDetector 
  // Send (averaged) and calibrated degrees out through serialport
  // Set c microseconds
  
   //Integer
  
   byte c; 
   unsigned long t;    
   
   if (c == 3) {
     c = -1;
   } 
  
  
  GetCapValues();
  SetAntPins(c);
  
  sqlstatus = Squelch();
   
  
  if (sqlstatus == sqloverflow || (t >= MaxTime))
  {
    t = 0; 
    EmptyCaps(); 
  } 
 else
 {
  //Relaxed sending to comport
 if (sqlstatus == sqlopen2closed && bMultiPath == false)
 { 
   Serial.println(Format3Degrees(Average(SinCosDetector())));
   sqlstatus = sqlclosed;
  }
 }

//What ToDo if overflow ?  This micros() number will overflow (go back to zero), after approximately 70 minutes
if (micros()>=(StartTimer)){ 
 c++;//AntPin Counter
 t++;//Total rotations counter TimeMax has uSec for 15 Sec's
 StartTimer = micros()+ KwartDopplerPerioduSec;
}

}

//End of sketch 
 
 
Bijlagen
Arduino-Doppler-Shield.GIF
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

#510 Bericht door Dopp »

73's
PA3BNX
Lodewijk

Mijn Credo!

Zelfbouw:
Minimaal hardware
en maximaal software.

Plaats reactie