Impedance Measurement and Curve Fitting (2)

root5

Now let’s try to measure the impedance of my dipole antenna. The figure shows the reference signal in red and the signal across the antenna in yellow. If the impedance of the dipole antenna is exactly 50 ohm, the two signals should be the same.

% head -15 owondata.txt
Save Time: 2016-09-11 13:27:26
Units:(mV)
                           CH1            CH2
Frequency:           7.026 MHz      7.042 MHz
Period:               0.142 uS       0.142 uS
SP:                   0.001 uS       0.001 uS
PK-PK:                 4.080 V        3.200 V

1              0.000                  1760.00        1560.00
2              0.001                  1760.00        1560.00
3              0.001                  1720.00        1560.00
4              0.002                  1720.00        1560.00

A text file obtained from the oscilloscope, OWON PDS 5022S, is fed into an AWK one-liner before being processed by a program written in ROOT.

% cat owondata.txt | awk 'NR>8 {print $1, $3}' >owondata_ch1.txt
% cat owondata.txt | awk 'NR>8 {print $1, $4}' >owondata_ch2.txt
// file name = mytest5.cc
{
  TGraph *g = new TGraph("owondata_ch1.dat");
  g->SetMarkerStyle( 20 );
  g->SetMarkerSize( 0.5 );
  g->Draw("AP");
  TF1 *f1 = new TF1("f1", "[0]*sin([1]*x+[2])+[3]"); 
  f1->SetParameter(0, 2000.0);
  f1->SetParameter(1, 0.022);
  f1->SetParameter(2, 0.0);
  f1->SetParameter(3, 0.0);
  f1->SetLineColor(kRed);
  g->Fit(f1);

  TGraph *h = new TGraph("owondata_ch2.dat");
  h->SetMarkerStyle( 24 );
  h->SetMarkerSize( 0.5 );
  h->Draw("P");
  TF1 *f2 = new TF1("f2", "[0]*sin([1]*x+[2])+[3]");
  f2->SetParameter(0, 2000.0);
  f2->SetParameter(1, 0.022);
  f2->SetParameter(2, 0.0);
  f2->SetParameter(3, 0.0);
  f2->SetLineColor(kYellow);
  h->Fit(f2);
}

root4

% root mytest5.cc

****************************************
Minimizer is Minuit / Migrad
Chi2                      =       536853
NDf                       =          996
Edm                       =  7.63442e-09
NCalls                    =          148
p0                        =      2001.67   +/-   1.04511     
p1                        =    0.0220756   +/-   1.82267e-06 
p2                        =      2.03624   +/-   0.00102561  
p3                        =     -12.2567   +/-   0.749788    

****************************************
Minimizer is Minuit / Migrad
Chi2                      =       459226
NDf                       =          996
Edm                       =  8.91283e-08
NCalls                    =          128
p0                        =      1558.13   +/-   0.960465    
p1                        =    0.0220847   +/-   2.15852e-06 
p2                        =      1.50439   +/-   0.00124773  
p3                        =     -14.2113   +/-   0.68435     

The parameters p0 and p2 are the amplitude and the phase, respectively, so the amplitude ratio is 1558.13/2001.67=0.778415, and the phase difference is 1.50439-2.03624=-0.531850[rad]=-30.4728[deg].

Mutex

A mutex is an object used for controlling access in a multi-threaded system.

#include <mutex>
std::mutex mtx; /* global */

void thread_test(Sound* s) {
	while(1) {
		usleep(200000); /* 0.2sec */
		mtx.lock();
		s->loop_count = s->asound_read(); /* write pointer goes forward */
		mtx.unlock();
	}
}

bool MyDrawingAreaS::on_draw(const Cairo::RefPtr<Cairo::Context> &cr) {
	if(s->loop_count) {
		while(s->signal_end - s->signal_start >= nfft*channels) {
			mtx.lock();
			s->asound_fftcopy(); /* write pointer sometimes goes back */
			mtx.unlock();
//
}
% ag locked log.txt | tail
58033:AAA locked in thread_test();
58037:BBB locked in on_draw();
58038:BBB locked in on_draw();
58039:BBB locked in on_draw();
58040:BBB locked in on_draw();
58041:BBB locked in on_draw();
58042:BBB locked in on_draw();
58043:BBB locked in on_draw();
58044:AAA locked in thread_test();
58046:BBB locked in on_draw();
58047:BBB locked in on_draw();

% ag AAA | wc; ag BBB | wc                          
   4284   17136  183477
  40219  160876 1561654

The lines AAA and BBB should appear 5 (=1/0.2) times per second, and 46.9 (=48000/1024) times per second, respectively. Note that 40219/4284 (= 9.39) is close to 46.9/5 (=9.37).

No Data Structures (2)

gtk3a

A little bit improved?

#include "radiobuttons.h"
#include <iostream>
void myfunc (int);

RadioButtons::RadioButtons() :
  m_Box_Top(Gtk::ORIENTATION_VERTICAL),
  m_Box1 (Gtk::ORIENTATION_HORIZONTAL, 10),
  m_Box10(Gtk::ORIENTATION_VERTICAL  , 10),
  m_Box11(Gtk::ORIENTATION_VERTICAL  , 10),
  m_Box12(Gtk::ORIENTATION_VERTICAL  , 10),
  m_Box2 (Gtk::ORIENTATION_VERTICAL  , 10),
  m_Button_Quit ("Quit")
{
  set_title("Spinor Lab");
  set_border_width(10);

  static char label[10][256] = { "CW", "CW-R", "LSB", "USB", "DSP FIL1", "DSP FIL2", "DSP FIL3", "DSP SHARP", "DSP SOFT" };

  for(int i=0;i<9;i++) {
    m_RadioButton[i].set_label(label[i]);
  }

  for(int i=0;i<=3;i++) {
    if(i==0) {m_group[0] = m_RadioButton[i].get_group();
    } else {
      m_RadioButton[i].set_group(m_group[0]);
    }
    m_Box10.pack_start(m_RadioButton[i], FALSE, FALSE, 0);
  }

  for(int i=4;i<=6;i++) {
    if(i==4) {m_group[1] = m_RadioButton[i].get_group();
    } else {
      m_RadioButton[i].set_group(m_group[1]);
    }
    m_Box11.pack_start(m_RadioButton[i], FALSE, FALSE, 0);
  }

  for(int i=7;i<=8;i++) {
    if(i==7) {m_group[2] = m_RadioButton[i].get_group();
    } else {
      m_RadioButton[i].set_group(m_group[2]);
    }
    m_Box12.pack_start(m_RadioButton[i], FALSE, FALSE, 0);
  }

  add(m_Box_Top);

  m_Box_Top.pack_start(m_Box1);
  m_Box_Top.pack_start(m_HSeparator);
  m_Box_Top.pack_start(m_Box2);

  m_Box1.set_border_width(10);
  m_Box2.set_border_width(10);

  m_Box1.pack_start(m_Box10);
  m_Box1.pack_start(m_VSeparator[0]);
  m_Box1.pack_start(m_Box11);
  m_Box1.pack_start(m_VSeparator[1]);
  m_Box1.pack_start(m_Box12);
  
  m_RadioButton[0].set_active();

  m_Box2.pack_start(m_Button_Quit);

  m_Button_Quit.set_can_default();
  m_Button_Quit.grab_default();

  m_Button_Quit.signal_clicked().connect (sigc::            mem_fun(*this, &RadioButtons::on_button_clicked )    );
  for(int i=0;i<9;i++) {
    m_RadioButton[i].signal_clicked().connect(sigc::bind<gint> (mem_fun(*this, &RadioButtons::on_button_clicked9), i));
  }

  show_all_children();
}
void RadioButtons::on_button_clicked9(gint data)
{

  if(m_RadioButton[data].get_active()) {
    std::cout << "button " << data << " is active " << std::endl;
	myfunc(data);
  }
}
#ifndef GTKMM_EXAMPLE_RADIOBUTTONS_H
#define GTKMM_EXAMPLE_RADIOBUTTONS_H

#include <gtkmm/box.h>
#include <gtkmm/window.h>
#include <gtkmm/radiobutton.h>
#include <gtkmm/separator.h>

class RadioButtons : public Gtk::Window
{
public:
  RadioButtons();
  virtual ~RadioButtons();
protected:
  void on_button_clicked ();
  void on_button_clicked9(gint data);
  Gtk::Box         m_Box_Top, m_Box1, m_Box10, m_Box11, m_Box12, m_Box2;
  Gtk::RadioButton::Group m_group[ 3];
  Gtk::RadioButton m_RadioButton [10];
  Gtk::HSeparator  m_HSeparator;
  Gtk::VSeparator  m_VSeparator  [ 2];
  Gtk::Button      m_Button_Quit;
};

#endif //GTKMM_EXAMPLE_RADIOBUTTONS_H

Radio Buttons revisited

radiobuttonsrevisited

Now let’s start at the very beginning.

When you read you begin with A B C, when you write your codes with gtkmm3 you begin with radio buttons.

#include "radiobuttons.h"
#include <iostream>
void myfunc (int);

RadioButtons::RadioButtons() :
  m_Box_Top(Gtk::ORIENTATION_VERTICAL),
  m_Box1(Gtk::ORIENTATION_VERTICAL, 10),
  m_Box2(Gtk::ORIENTATION_VERTICAL, 10),
  m_RadioButton1("CW"),
  m_RadioButton2("CW-R"),
  m_RadioButton3("LSB"),
  m_RadioButton4("USB"),
  m_Button_Quit ("Quit")
{
  set_title("Spinor Lab");
  set_border_width(10);

  Gtk::RadioButton::Group group = m_RadioButton1.get_group();
  m_RadioButton2.set_group(group);
  m_RadioButton3.set_group(group);
  m_RadioButton4.set_group(group);

  add(m_Box_Top);

  m_Box_Top.pack_start(m_Box1);
  m_Box_Top.pack_start(m_Separator);
  m_Box_Top.pack_start(m_Box2);

  m_Box2.set_border_width(10);
  m_Box1.set_border_width(10);

  m_Box1.pack_start(m_RadioButton1);
  m_Box1.pack_start(m_RadioButton2);
  m_Box1.pack_start(m_RadioButton3);
  m_Box1.pack_start(m_RadioButton4);

  m_RadioButton1.set_active();

  m_Box2.pack_start(m_Button_Quit);

  m_Button_Quit.set_can_default();
  m_Button_Quit.grab_default();

  m_Button_Quit.signal_clicked().connect (sigc::mem_fun(*this, &RadioButtons::on_button_clicked ) );
  m_RadioButton1.signal_clicked().connect(sigc::mem_fun(*this, &RadioButtons::on_button_clicked1) );
  m_RadioButton2.signal_clicked().connect(sigc::mem_fun(*this, &RadioButtons::on_button_clicked2) );
  m_RadioButton3.signal_clicked().connect(sigc::mem_fun(*this, &RadioButtons::on_button_clicked3) );
  m_RadioButton4.signal_clicked().connect(sigc::mem_fun(*this, &RadioButtons::on_button_clicked4) );

  show_all_children();
}

void RadioButtons::on_button_clicked1()
{
  if(m_RadioButton1.get_active()) {
    std::cout << "clicked1: active" << std::endl;
	myfunc(1);
  }
}

There is a lot of room for improvement.

void myfunc (int index) {
  std::cout << "myfunc: " << index << std::endl;
  switch (index) {
    case 1: 
      operating_mode = 0x03; 
      dsp_filter     = 0x01; 
      break;  
    case 2: 
      operating_mode = 0x07; 
      dsp_filter     = 0x01; 
      break;  
    case 3: 
      operating_mode = 0x00; 
      dsp_filter     = 0x01; 
      break;  
    case 4: 
      operating_mode = 0x01; 
      dsp_filter     = 0x01; 
      break;  
    }
  set_operating_mode();
}

The Magic Flute

713omyHigJL._SY606_

When I am extremely or exceptionally unbuy, I start watching a blue-ray disk for some operas.

To tell you the truth, however, I have never completed watching an opera until the very end. Today I aborted after around 90 min, although the run time of the video is 182 min.

http://www.youtube.com/watch?v=fas6zUDa5t8