Re: W8TEE Power/SWR Sketch for Nano

Jerry Gaffke
 

Regarding code for your Tandem Match SWR meter,
below is where my code was parked a couple months ago.
It may or may not be stuff you can use.

I haven't made time yet to fully implement it, though I'm pretty sure it's very close to good.

I'm not planning to talk to anything like the OLED, will use the Raduino's LCD

I am planning to just read Diz's diode detectors (with a slight dc bias current through the diodes)
using the Nano's 10 bit ADC's.  

The code that converts the AD8307 log response to volts is unused and has been commented out.
That 32 bit fixed point code works, but you are probably better of just using a floating point library as you won't
be pressed for flash space.

Jerry, KE7ER

###########################
void lcd_printline(char n, char* s) { // n=0 for top, n=1 for bottom
    lcd.setCursor(0,n);
    lcd.print(s);
    for (n=strlen(s); n<16; n++)  lcd.print(" ");
}
 
// Print val as d digits with r digits after the decimal point
// Will print any leading zeros, if r==0 then no decimal point
void pnum(uint32_t val, uint8_t d, uint8_t r) {
  uint32_t  div=1;
  uint8_t   n; 
  for (n=1; n<d; n++)  div*=10;
  while (div>0) {
    if (d--==r)   lcd.print('.');
    lcd.print(val/div);
    val = val%div;
    div = div/10;
  }
  lcd.print(" ");
}
 
 
//  // Accurately transform AD8307 readings to RF voltage per post 48570
//  int32_t adcSlope32 = 5922023;  // 0x7FFFFFFF * (0.025/2.50 * (20*m.log10(32.0/31)) );   5922023.090616257
//  int32_t adcSlope2048 = 91056;  // 0x7FFFFFFF * (0.025/2.50 * (20*m.log10(2049.0/2048))) 91055.92544695384
//  uint32_t  adcRFmax = 100UL<<24;         // Calibrated Volts*2**24 rms of RF when adcRead at 0xFFFF
//  uint32_t findVoltsRF(uint16_t adcRead)  {               // adcRead is 16 bit ADC read of AD8307's output
//    uint32_t voltsRF = adcRFmax;                          // At adcRead max of 0xFFFF, voltsRF is adcRFmax
//    int32_t  voltsADC = 0x7FFFFFFF - (adcRead<<15);       // Will subtract adcSlope from this till goes negative
//  
//    // The RF voltage falls by 1/32 for each drop in voltsADC by adcSlope32
//    while (voltsADC > 0)  {                                       // while (voltsADC > adcRead<<16)
//      voltsRF = voltsRF - (voltsRF>>5);           // voltsRF *= (31.0/32)
//      voltsADC = voltsADC - adcSlope32;
//    }
//    while (voltsADC < 0) {
//      voltsRF = voltsRF + (voltsRF>>11);
//      voltsADC = voltsADC + adcSlope32/65-52;
//    }
//    return(voltsRF);
//  }
// Read TandemMatch's 2 detectors, display forward and reverse power, swr
#define PSCALE  (1023L*1023/(25*10)) // ADC max of 1023 is 25 Watts, display Watts*10
void  show_swr() {  // SWR = (1+1.0*vr/vf)/(1-1.0*vr/vf);
  uint32_t vr, vf, swr; // Voltage squared proportional to power
  vf = analogRead(RF_FWD); // Peak RF volts from forward detector
  vr = analogRead(RF_REV); // Peak RF volts from reverse detector
  if (vr>=vf) swr=0; // If vr,vf illegal, force SWR to zero
  else {
    swr = (vr*1024)/vf; // Voltage ratio, 10 fractional bits
    swr = (1000*(1024+swr))/(1024-swr); // 1000*swr, nearly 10 fractional bits
    swr = (swr+50)/100; // 10*swr, rounded to nearest tenth
    if (swr>99) swr=99;  // Display a max SWR of 9.9
  }
  lcd.setCursor(0, 1); // Fill bottom LCD line, example:
  lcd.print('f'); pnum(vf*vf/PSCALE,3,1); // "f12.4 r03.1 s1.7"
  lcd.print('r'); pnum(vr*vf/PSCALE,3,1); // with fwd,rev power in watts
  lcd.print('s'); pnum(swr,2,1); // and swr to max of 9.9
}
 

On Mon, Jun 25, 2018 at 06:57 pm, Kees T wrote:
all I need now is some code......

Join BITX20@groups.io to automatically receive all group messages.