無線ブログ集
メイン | 簡易ヘッドライン |
MODEL 1200FXローテーターその2 (2022/4/12 7:09:38)
ESP32DevKitCのADコンバーターの精度の良い2.5DBアッテネーションを使い誤差を調べての簡易補正を行なったREMOTE端子の角度に対しての出力電圧を角度計算して表示した動画です。
かなり角度と指針位置の精度が取れています。補正前はかなりのズレがありましたが、補正後はほとんど±1カウント以内ぐらいです、多くても±2カウント以内に収まっています。ただし、これは見る角度とかでも多少代わりますし、進めて戻って、または戻って進めてをやると±2カウントぐらいの誤差になります。(とても指針表示にヒステリシス、またはバックラッシュがあるローテーターです。)またスピード設定を早くすると止める位置が難しくなりますし、最初と終わりの止まる位置が勢いがあるのでスピードが遅い時のAD変換値とスピードが速い時のエッヂのAD変換値は多少異なります。通常の仕様を標準とするのでスピードはセンターで設計しています。SWの操作はスピードが遅い程目的の角度で止めやすいです。
大まかな事ですが、指針は−10°〜から+379°まで表示範囲があります。その中の0°から360°を使っています。これもエッヂ近辺の精度の悪いところを使用しない為の方策の一つであるのと、エッヂ指針設定では必ずオーバーするので余裕をもたせる意味でも広くしてあります。
0°超えた左回転時のエッヂ位置 (角度でー10°のゆとり)
360°を超えた右回転時のエッヂ位置(角度で379°(360°から+19°))
ここまでは上手くいった指針と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
次は使うフォントを指定します。面倒なので使える物全部指定しておきます。
// 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
//
// 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
#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);
//-----------------------------------------------------------
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);
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"
#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);
}
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を参考にしました。とても素晴らしい方法かと思います。
回路図も全く同じポートを使っていますので、すべて引用させていただきました。
スケッチ上でのポートD25の設定と出力の下記の2つの処理です。
hiZ(25);
dacWrite(25,9);//9
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);
}
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=-1*0.000123456*deg*deg+0.04444416*deg;
補正をかけるスケッチ箇所(ddを足す箇所)
TFT液晶の所でも取り上げています下記の箇所です。
char cc[6];
sprintf(cc,"%3d", ((deg*1)+dd) );
tft.print(cc);
sprintf(cc,"%3d", ((deg*1)+dd) );
tft.print(cc);
以上です。
ESP32DevKitCのADCでローテーターのリモート端子を用いた指示角度表示が短いスケッチで簡単に作製することが出来ます。
つづく?
execution time : 0.025 sec