Loading

 

おはようございます。昨日は無線もせずに、朝5時に家をでて6時から釣りをやっていたのですが、10時を回ると気温は30℃を越えだし、熱中症になりそうだったので早々に帰宅しました。やはり最近の暑さは異常ですね。

 

釣りから帰宅後は、エアコンの効いた部屋で先日から手を付け始めたDigital APFの実験を始めました。

数日前までには、リグのPhone端子から得た信号を入力とし、ADCからPCM変換でリグのPhone端子で聞く音質と同じようになるまで実験は進みました。

昨日は実際のAPF機能の作り込みです。APFは一般的に、OPアンプの帰還を利用して特定周波数で同調させるような感じで、特定周波数のみを強調して聞こえるようにします。

この強調はOPアンプの帰還率からQの大きさで選択度(ピーク度)が決まりますが、これをデジタル処理しようと言うのが今回の実験です。

更には、FPGAとかDSPとか言う高価でかつ高度な知識を要するモノでは無く、Raspberry Pi pico2を使用して内蔵しているCPUとADCで処理を掛けようというものです。

当然ながら、当局はそんな知識も持ち合わせておりませんので、今までと同じくパートナーのGemini君に活躍して貰いました。

当局は細かな仕様設定をし、後はデバッグを行いながらGemini君にフィードバックしていくだけです。

入出力がちゃんと出来るようになったことを受けて、ADCで得た信号をCPUでピーク処理をし、外付けのVRで選定周波数が変わるようにします。

更には、選択度を変えるQもロータリーエンコーダで可変することでQの大きさを変えて、選択度を変化させると言う所まで実験しました。

最終的に、VRで度の周波数を選定しているのか?Qは幾つでどのくらいの選択度となっているのか?を視覚化するように、OLEDに表示をさせるようにしました。

最終的にOLEDで表示もでき、とりあえず目標としていた実験までは完了しました。

DAPF

センター周波数700Hzに対して、選択度Qは15帯域は一番狭い状態となっております。ロータリエンコーダを回すと、Qの値が小さくなると同時に下部にあるバンド幅が広がっていきます。最低のQ:2に設定すると、最大通過幅になります。

また、APF用VRを回すと中心周波数が変化していきます。

40mで実際の信号を聞いてみると、ズレて呼ぶ局に対してだいぶ減衰して聞こえない状態ですが、VRを回して周波数を合わせると信号が浮いてきます。

OPアンプのAPFと違い、キンキンしたような音質ではなくトランシーバーにヘッドフォンを付けて聞いている音で、帯域が狭くなったりして信号が浮き上がる感じです。

切れは有るが音はキンキンせずに普通の音質で聞こえる、これがDigital APFの特徴なんでしょうね。

トランシーバーについているAPFとフィルタの帯域変更だけでは取り切れない混信を、オーディオスペクトル的に切り落としてしまうDigital APFはなかなかのモノです。

思ったよりは使えるかなって思えてきました。未だ完成ではないですが、先が楽しみです。

コードの一部はこんな感じです

#include <I2S.h>
#include <math.h>
#include "hardware/sync.h"

// OLED用ライブラリ
#include <U8g2lib.h>
#include <Wire.h>

// ★標準のハードウェアI2C(Wire=I2C0)を使用するコンストラクタに戻します
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// GPIOピン定義
const int I2S_BCK  = 18;
const int I2S_LRCK = 19;
const int I2S_DOUT = 22;
const int AUDIO_IN_PIN = 26;
const int FREQ_VR_PIN = 27;  

const int ENCODER_A_PIN = 10;
const int ENCODER_B_PIN = 11;

const int SAMPLE_RATE = 16000;

I2S i2sOutput(OUTPUT);
repeating_timer_t timer;

// リングバッファ
const int BUFFER_SIZE = 1024;
volatile int16_t adc_buffer[BUFFER_SIZE];
volatile int head = 0;
volatile int tail = 0;

float dc_estimate = 2048.0;

// フィルター係数
volatile float b0 = 0, b1 = 0, b2 = 0;
volatile float a1 = 0, a2 = 0;

// フィルターの過去データバッファ
float v_x1 = 0, v_x2 = 0;
float v_y1 = 0, v_y2 = 0;

float current_freq = 700.0;
float current_q = 15.0;    
float target_freq = 700.0;  
int last_vr_value = -999;  
bool is_moving = false;    

// 画面更新フラグ
bool oled_needs_update = true;

// APF係数計算関数
void calc_apf_coefficients(float target_freq, float q_value) {
  float omega = 2.0 * M_PI * target_freq / (float)SAMPLE_RATE;
  float alpha = sin(omega) / (2.0 * q_value);

 

開発言語を十分理解していなくても、プログラムが出来てしまうなんて、すごい世の中になりましたね。もっとも、ポイントは仕様書をどこまで細かく掛けるかにかかっていますが。

 

にほんブログ村 その他趣味ブログ アマチュア無線へ にほんブログ村 ↑ブログランキング参加中。クリックでランキングが上がりますので、ご支援をお願いします。

 

ABOUT ME
JE2UFF_Toshi
年々若者のアマチュア無線人口が減る中、何時までも現役でやり続けたく、若き日の想い出を胸に、熱き思いを忘れないように「燃えよDX」と言うタイトルを付けました。単身赴任以降、過熱するDXスロットゲームに違和感を覚え、主力だったHFのアンテナも下ろしてしまったこともあり、燃えるような情熱からいろんな楽しみ方が有るんだ。そう思えるようになって、タイトルもむせん見聞録に変更しコツコツマイペースでやってます。 最近は6mの面白さのハマっています。 更に、長年勤めた会社も退職しサンデー毎日なった事をきっかけに、更にタイトルをきょうも無線日和に変更し、まだまだ続けますよ。
部材購入に困った時は!

digital-dxer.comからのお知らせ

アマチュア無線をやってて困ったことないですか?
何か作りたいが工具が無い、アンテナ作りたいけど材料が無い

そんな時、工具から小さな小物材料、はたまた無線機からアンテナまで何でも簡単購入ができるYahoo!ショッピングが便利です。
クリックすれば後は到着を待つだけ、近くて簡単便利なYahoo!ショッピング。