jl7gmnのblog

yahooブログから移行してきました。アマチュア無線を中心としたブログです。

2022年04月

MODEL 1200FXローテーターその2

ESP32DevKitCのADコンバーターの精度の良い2.5DBアッテネーションを使い誤差を調べての簡易補正を行なったREMOTE端子の角度に対しての出力電圧を角度計算して表示した動画です。

かなり角度と指針位置の精度が取れています。補正前はかなりのズレがありましたが、補正後はほとんど±1カウント以内ぐらいです、多くても±2カウント以内に収まっています。ただし、これは見る角度とかでも多少代わりますし、進めて戻って、または戻って進めてをやると±2カウントぐらいの誤差になります。(とても指針表示にヒステリシス、またはバックラッシュがあるローテーターです。)またスピード設定を早くすると止める位置が難しくなりますし、最初と終わりの止まる位置が勢いがあるのでスピードが遅い時のAD変換値とスピードが速い時のエッヂのAD変換値は多少異なります。通常の仕様を標準とするのでスピードはセンターで設計しています。SWの操作はスピードが遅い程目的の角度で止めやすいです。


大まかな事ですが、指針は−10°〜から+379°まで表示範囲があります。その中の0°から360°を使っています。これもエッヂ近辺の精度の悪いところを使用しない為の方策の一つであるのと、エッヂ指針設定では必ずオーバーするので余裕をもたせる意味でも広くしてあります。

0°超えた左回転時のエッヂ位置 (角度でー10°のゆとり)
CIMG9524

360°を超えた右回転時のエッヂ位置(角度で379°(360°から+19°))
CIMG9525

ここまでは上手くいった指針とTFT液晶への角度表紙動画と写真説明で終了です。
TFT液晶表示関係のスケッチやTFT液晶を使う場合の設定についての重要と思われた点,等を私自身の忘備録して記します。

今回使用したTFT液晶は1.8インチのものです。
仕様としてwidth 128 x height 160 typeがST7735REDTAB 中華製でALIEXPRESSで購入したものです。とても使いやすいTFT液晶ですが、使うためには使用するESP32DevKitCの端子の指定と使用するフォントとかをドライバー設定のように予め設定を行う必要があります。それは User_Setup.h のヘッダーファイルの設定です。
Arduinoの中のlibrariesフォルダの中のTFT_eSPIのフォルダの中にあります。
先ずは仕様のWIDTHと HEIGHTを自分の液晶の物に合わせてコメントアウトを外し設定します。
define the pixel width and height in portrait orientation とあります。

#define TFT_WIDTH  128
#define TFT_HEIGHT 160

次に液晶のtypeも自分の液晶に合わせてコメントアウトを外して設定します。たくさん種類がある中から自分の使う液晶のtypeを選びます。
define the type of display とあります。

#define ST7735_REDTAB

次はESP32 のDev board pinセットアップです。ここが一番厄介でした。というのもWebのスケッチで動作しているものと、この設定が違う事がある為、オリジナルの設定では表示できない事が起きえます。ある程度の自由度(ポート選択可能)があるためです。自分のTFT液晶とESP32Dev boardではいつも同じポート設定で行ないたいのが心情ですが、Webで気に入ったスケッチで動作している物に合わせて設定を変えてしまうのが手です。私はそうしてます。ブログで作成したTS-820 DDS-VFOでも同じTFT液晶を使っていますので、これと同じポート設置に書きかえています。すると全部同じ接続で新たなスケッチでの液晶表示も悩まずに組んで行けます。
下記のTFT_CS  5,  TFT_RST 15 の2つは書き換えてあります。元はそれぞれ 15 と 4です。

// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP32 SETUP   ######

// For ESP32 Dev board (only tested with ILI9341 display)
// The hardware SPI can be mapped to any pins

#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18

#define TFT_CS    5  // Chip select control pin 15
#define TFT_DC    2  // Data Command control pin
#define TFT_RST  15  // Reset pin (could connect to RST pin) 4

次は使うフォントを指定します。面倒なので使える物全部指定しておきます。
// ##################################################################################
//
// Section 3. Define the fonts that are to be used here
//
// ##################################################################################

// Comment out the #defines below with // to stop that font being loaded
// The ESP8366 and ESP32 have plenty of memory so commenting out fonts is not
// normally necessary. If all fonts are loaded the extra FLASH space required is
// about 17Kbytes. To save FLASH space only enable the fonts you need!

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
// this will save ~20kbytes of FLASH
#define SMOOTH_FONT

残りの設定はオプションです。これは次の2つを設定します。
ST7735は27MHzより上では動作しない(スプリアスピクセルライン障害)とコメントあります。なので最大である27MHzの設定なのでしょう!
// With a ST7735 display more than 27MHz may not work (spurious pixels and lines)

#define SPI_FREQUENCY  27000000

これはおまじない?
#define SPI_TOUCH_FREQUENCY  2500000

これで設定する箇所の全部です。
一度設定しておくと同じ液晶とESP32Dev ボードの接続は代わりませんので、スケッチがしやすくなります。

User_Setup.hの設定が終わったら次は今回の1200FXの角度の液晶への表示方法のスケッチについてです。TFT液晶の表示についてのみ特化して記します。

ヘッダーのロードを設定します。
//TFT1.8
#include <SPI.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h

次にセットアップでの設定です。
void setup(){
    Serial.begin(115200);

    //TFT setting -----------------------------------------------
    tft.init();
    tft.setRotation(1);
    tft.fillScreen(TFT_BLACK);
    //-----------------------------------------------------------


void loop(){ での設定です。
ミソはlongの数値はcharに変換して表示することです。
 char cc[6];で文字配列を用意して  sprintfで数値を文字変換します。
 sprintf(cc,"%3d",((deg*1)+dd)); 
上は変換時に補正した角度を入れています。
後はTFTのテキストカラーを指定(白)、テキストサイズ設定(5)、セットする位置設定(0,50)で後は数値をccに変換し、後はccをTFTで表示するだけです。
    tft.setTextColor(TFT_WHITE,TFT_BLACK);
    tft.setTextSize(5);
    tft.setCursor(0,50);
    char cc[6];
    sprintf(cc,"%3d",((deg*1)+dd)); 
    tft.print(cc);


以下 void loop 全スケッチです
void loop(){
    uint32_t voltage;
    // ADC1_CH6の電圧値を取得
    esp_adc_cal_get_voltage(ADC_CHANNEL_6, &adcChar, &voltage);

    long d =0;
    for(int i=0 ;i<2000;i++){
      d +=analogRead(34);
    }
    
    long deg =0;
    long dd =0;
  
    // deg=((((d-78)/2000)-14)/15.27)*1.02;
    // Serial.print("deg = ");
    // Serial.println(deg*5);
    
    // deg=((((d-78)/2000)-14)/1.52);
    // Serial.print("deg = ");
    // Serial.println(deg*0.5);

    deg=(((d/2000)-62)/2.83);
    Serial.print("deg = ");
    Serial.println(deg*1.0);

    //hosei
    dd=-1*0.000123456*deg*deg+0.0444444*deg;
    char cd[6];
    sprintf(cd,"%4d",dd);
    Serial.print("HOSEI:");
    Serial.println(cd);

    tft.setTextColor(TFT_WHITE,TFT_BLACK);
    tft.setTextSize(5);
    tft.setCursor(0,50);
 

    char cc[6];
    sprintf(cc,"%3d",((deg*1)+dd));
    tft.print(cc);
 
    Serial.println(((d)/2000));
     delay(10);
}

以上で角度の数値変換値は液晶表示できます。
--------------------------------------------------------------------------------------------------------------------------------------


AD変換のスケッチ設定についてはお決まりなので、しかも説明付きのサンプルですので省略します。
ADC用のヘッダーのインクルードを2つします。
//adc header ----------------------------
#include "driver/adc.h"
#include "esp_adc_cal.h"

esp_adc_cal_characteristics_t    adcChar;

ADCのATTの設定が11dB1つしかなかったので,コメントアウトで全部の設定を載せました。
使用出来る電圧のフルスケールは便利です。
今回は2.5dB設定で使用しましたので1.5Vフルスケールです。

void setup(){
    Serial.begin(115200);

    //TFT setting -----------------------------------------------
    tft.init();
    tft.setRotation(1);
    tft.fillScreen(TFT_BLACK);
    //-----------------------------------------------------------
    // ADCを起動(ほかの部分で明示的にOFFにしてなければなくても大丈夫)
    adc_power_on();
 
    // ADC1_CH6を初期化
    adc_gpio_init(ADC_UNIT_1, ADC_CHANNEL_6);// GPIO 34
   
    // ADC1の解像度を12bit(0~4095)に設定
    adc1_config_width(ADC_WIDTH_BIT_12);
   
    // ADC1の減衰を11dBに設定
   // adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
    
   //ADC_ATTEN_DB_0     //FULL SCALE 1.1V
   //adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_0);
   //ADC_ATTEN_DB_2_5   //FULL SCALE 1.5V
   adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_2_5);
   //ADC_ATTEN_DB_6     //FULL SCALE 2.2V
   //adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_6);
   //ADC_ATTEN_DB_11    //FULL SCALE 3.9V
   //adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
 

  hiZ(25);
  dacWrite(25,9);//9
   
    // 電圧値に変換するための情報をaddCharに格納
    esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_2_5, ADC_WIDTH_BIT_12, 1100, &adcChar);

}

次にADC変換時入力感度特性でゼロボルト付近のオフセットが(不感帯)が大きい回避策としてですが、ラジオペンチのWebを参考にしました。とても素晴らしい方法かと思います。


回路図も全く同じポートを使っていますので、すべて引用させていただきました。
範囲を選択_279

スケッチ上でのポートD25の設定と出力の下記の2つの処理です。

    hiZ(25);
    dacWrite(25,9);//9

上記のサブルーチンhiZ();
void hiZ(int n) {               // 指定ピンをHi-Zに設定 set the pin to hi-z
  pinMode(n, INPUT);            // 入力にして set INPUT
  digitalWrite(n, LOW);         // 念のためにプルアップを解除 no pull up
}
dacWriteではポート25に9を出力しています。出力は0,1,、、、7,8,9などと入れてみてオフセットの不感地帯がなくなる補正電圧値を見つけます。通常時は78mV出力がありますが、私の場合は以下の電圧値でした。9の97mVを採用しました。

2の出力時 78mV
3の出力時   78mV
4の出力時 78mV
5の出力時   79mV
6の出力時 83mV
7の出力時    89mV
8の出力時 93mV
9の出力時    97mV

補正電圧は差し引きして使います。
不感地帯はローテーターの0°から増加時の数値の変化が突然数値が上がる様な感じの所を言っています。上記の出力設定の状態で0°近辺でもADC出力値が変化する様になり変換値も同様に変化します。不感帯はキャンセルされています。

平均値化の為のスケッチです。アナログポートからの電圧の読み込みです。
void loop(){
    uint32_t voltage;
    // ADC1_CH6の電圧値を取得
    esp_adc_cal_get_voltage(ADC_CHANNEL_6, &adcChar, &voltage);

    long d =0;
    for(int i=0 ;i<2000;i++){
      d +=analogRead(34);
    }

dは2000回のDACの入力値の和算値が入ります。1000回ではバラツキが顕著だったので変えました。
平均値化する事でノイズ的な突飛な値が押さえられるのでバラツキがなくなります。
2000で割ることで平均値となります。
0°の時の電圧値分をひきます。
0°で62mV 360°で1084mV   0°分を引く処理で 0mV〜1022mVの電圧範囲を検出します。
2.83は360°のADC変換値の1022を360°分割した1°当たりのADC変換値です。各角度時のADC変換値を2.83で割ることで角度が算出されます。

deg=(((d/2000)-62)/2.83);

残りは補正の式のスケッチですが、単にコーディングするだけです。桁数は電卓の桁です。
求めた補正の計算式をスケッチ様に書きます。

dd=−0.000123456deg^2+(−360)*(−0.000123456)*deg
上を更にまとめると
dd=−0.000123456deg^2+0.04444416*deg

上をスケッチ用に書き換えます。
//hosei
  dd=-1*0.000123456*deg*deg+0.04444416*deg;

補正をかけるスケッチ箇所(ddを足す箇所)
TFT液晶の所でも取り上げています下記の箇所です。
 char cc[6];
    sprintf(cc,"%3d",((deg*1)+dd));
    tft.print(cc);

以上です。
ESP32DevKitCのADCでローテーターのリモート端子を用いた指示角度表示が短いスケッチで簡単に作製することが出来ます。

つづく?

MODEL 1200FX ローテーターその1

なんでか気にかかる事の内の一つのエモトのローテーターの予備を動かしてみたくなり、動作確認をしてみたところ、LEFTボタン、RIGHTボタン、プリセットのSTARTボタン、RESETボタンでのローテーターモーターは回転するが、指示が回らない現象が起きていました。早速フタを開けて症状の確認です。指針を動かしているモーターへの電圧チェックです。やはり、電圧がかかっていません。この症状はWeb情報からモーターの回転を止める為のSWが接触不良をおこしている場合起きる事があるとの他のエモトのローテーターでの対策方法を参考にばらしてみました。ばらすといっても、ギヤの部分をはずして、SWを直接見て確認する為です。後はテスターの抵抗レンジで導通チェックです。確認するのはすべての3端子が常時コンタクトしていればOKと言うことです。
残念ながらオープン状態でした。気をつけながら(銅板に無理に力を掛けすぎないように)中心の端子に常時コンタクトするように調整しました。
1200FXはDC24Vのモータータイプです。参考にしたのは100Vモータータイプですが、回路構成は似ています。ネットからの回路図参考にしました。

範囲を選択_279

端子のコンタクトが全てあると思い、一度組み直しましたがVRを回してカチ,カチとVRをいじっている内にまた指針が動かなくなってしまいました。またバラしてSWのコンタクトを調整です。今度は少しバネ圧が効く様にコンタクト調整してみました。最初の時は、少しSW板コンタクト同士の接触圧がたりなかった為に、VRギヤに付いているストッパーが数回当たっただけでオープンとなってしまった様です。
ギヤを組み直して、今度は安定して指示もCW,CCWともに問題なく指示動作してくれています。一応これで指針動作は解決しました。
ついでに、ゴムベルトの交換もしました。ほってあったのでやはり老けてひび割れて切れる寸前でした。

ニトリルゴムも過酷な使用をしなければ10年は持つと書いてありましたが
長持ちはしますがひび割れは間違いなく起きてきています。
CIMG9516

以前購入した時の交換説明書です。説明書があると本当にスムーズに交換作業がはかどります。Hi!
原理が同じなので、他のモデルも同じ同じ様にゴムベルト交換できます。
CIMG9515

予備がなくなったので、ネットで先日また注文しておきました。

ついでに、最近またどハマりしてるESP32DevKitCでの方角の表示を検討してみることにしました。
4エリアのJA4BUA局IICT-KuwaOMが素晴らしいシリアル制御対応のRTC-59,RCC-59DCを販売頒布してかなりのアマチュア無線家が使用しているものがありますが、やることは同じ内容ですが、違う方向からのローテーターコントロールまでを実験してみたいと思います。ESP32を使うので、色々と方法が考えられます。ブルートゥ-スや、WiFiやUDP通信等で方角をコントロールできれば、面白いかと思います。

先ずは取り掛かり方角の表示をやってみました。
CIMG9513

コントローラの30°です。
CIMG9510

ESP32DevKitC TFT1.8インチでの表示にしました。
CIMG9517

評判の悪い(精度の悪いと言われてる)A/Dを使いました。
比較的精度の取れる(リニアリティの良い)ADC1のATT 2.5DBを使いました。
CIMG9519
抵抗での分圧です。ネットのESP32でのオシロ作製からの情報を参考にしました。
入力側510KΩと120KΩアース側をESP32のD25ポートに繫いでオフセット処理して不感部をなくす方法を利用させていただきました。とても素晴らしい方法だと思います。
ADの入力ポートへは510KΩと120KΩの接続からの分圧電圧が繋がります。ローテーターの角度に対しての電圧は0から(厳密には数mV〜十数mV出ています。)4.64Vです。上記の分圧でのAD変換値を求めてゆきます。
先に角度範囲の0°〜360°間の分解能をどうするかを考えました。最初は5°毎で良いのでないかと思いましたが、本家のRTC-59は0.3°毎です。実際に動作させてみて1°毎に決めました。

なおAD変換する値は2000個取得での平均値を利用してばらつきをなくしています。平均値を使うことは表示値のチラツキ防止効果があります。
抵抗分圧を通したAD変換後の値は0°が62、360°が1084となりました。なので0°の分を引く処理をするので実質のAD変換後の値の範囲は0から1022になります。
なので、1022÷360=2.83888888888 となります。これより次の式で角度を表示します。

deg=(((d/2000)-62)/2.83);

このAD変換値をシリアルモニタで確認して見ました。
0°と360°でドンピシャに合うのですがローテーターのVRの非直線性が出ます。つまり間の値がばらつきます。片方向だけですので、設定角度との差をとって見ました。30°毎にとって見ました。数回やってみての値です。
設定角度に満たない状態の差の角度です。

0°:0
30°:2
60°:2, 3
90°:4, 5
120°:4, 5, 6
150°:6, 7
180°:3
210°:2, 3
240°:2, 3
270°:2, 3
300°:1, 2
330°:2
360°:0

なんとなくフリーハンドでグラフをかいてみました。
CIMG9520

確かめてないので、あくまでも推測ですが、VRのカーブにA,B,Cとあったと思いますがリニアのBではないのではないかと思います。数値が低めなのでオーディオのVRでよく使われるAタイプではないかと思います。

参考:マルツオンラインより
範囲を選択_279b


このフリーハンドの感じから差分値は2次関数である程度近似できそうだと思いました。グラフは中学生の得意な2次関数です。
y=ax^2+bx+cが基本ですが、このグラフの場合はX軸で2点交わりますから次の式になります。

y=a(x-α)(x-β) が基本のグラフです。(角度0°と360°)
これに合わせると
y=ax(x−360)
y=ax^2-(a*360)x

グラフの式が立ちましたのでaを求めます。
180°の時のy値を4と仮に決めて求めてみます。
4=a(180)^2-(360*180)a
4=32400a-64800a
4=-32400a
a=(-4/32400)
a≒−0.000123456
もとの式に入れると
y=−0.000123456x^2+(-360)*(−0.000123456)x
y=−0.000123456x^2+0.04444416x

これで近似式が出来ました。xは角度です。
この値を求めたdegに加えると補正完了です。

これをスケッチしました。
近似されて表示番とAD読み取り角度表示の差が気にならない程度にすることが出来ました。
他TFT液晶表示とかスケッチの詳細は次にします。

つづく?



アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード
  • ライブドアブログ