2020年6月18日木曜日

esp8266 VFO

回路全体
esp8266(WeMos mini D1の模造品)を使ったモノバンドVFOである。画面は、SPI 1.3" IPS240x240と組み合わせた。ともに、Aliexpressで格安に入手する事が出来る。このVFOの特徴は、アナログタイプのSメータとデジタル風表示である。
       

画面表示例
esp8266にDIOが少ない為、モノバンドとした。メモリーが十分有るので、PCF8474などをI2Cに接続する事で、マルチバンド化も容易であろう。
s-meterは、イメージデータをimage2cppでモノクロデータにして加工した。カラー表示を行うので有れば、同様なツールとしてlcd-image-converterがある。これらのツールを使えば、簡単にデータ化できる。
周波数表示に使ったフォントは、デジタル風ものを選んだが、等幅フォントでない。この為、1文字毎にロケーションを指定している。
VFOの機能は、オートモード、RIT、自動メモリー保存、バンド範囲チェックなど 際立った機能は無いが実用的に仕上がった。




回路図


DIOにTX/RXまで使っており、拡張性が無いように見えるかも知れないが、必要な機能が達成できれば、それで良い。








mini D1設定

CPUパラメータ設定


esp8266は曲者

開発にArduino IDEを使ったが、esp8266(WeMos mini D1)は個性的な印象だ。DIOすら制限があり、この割付がベストだと思っている。esp8266には、産業用コントローラなどで使っているウォッチドグタイマー装備されおり、トラブル時の対策を悩ませる一員となった。


スケッチ

必要なファイルは、JA2GQP's Download siteのesp8266フォルダからダウンロード可能。
//////////////////////////////////////////////////////////////////////
//  si5351a IPS(240x240) VFO program ver.1.0
//    Copyright(C)2020.JA2GQP.All rights reserved.
//
//                                                2020/6/18
//                                                  JA2GQP
//--------------------------------------------------------------------
//  Function
//    1.STEP(1k,100,10)
//    2.Automatic memory
//    3.Protection Operation At The Time Of Transmission
//    4.Automatic mode switching
//    5.S-Meter/Power meter
//////////////////////////////////////////////////////////////////////

#include <Adafruit_GFX.h> 
#include <Fonts/Org_01.h>
#include <EEPROM.h>
#include "src/Arduino_ST7789.h"
#include "src/Rotary.h"             
#include "src/si5351.h"             
#include <wire.h>
#include "src/smeter.h"
#include <Ticker.h>

//---------- define value ----------------------------------------------

#define TFT_DC    D8                // DC
#define TFT_RST   D6                // RES
#define TFT_MOSI  D7                // SDA
#define TFT_SCLK  D5                // SCL
#define SW_TX     D0                // D0
#define SW_RIT    RX                // RX
#define SW_STEP   TX                // TX

////////////////////////////////
// EEPROM Memory Address
////////////////////////////////
#define Eep_Init  0x00              // Eep Init(1byte*1)
#define Eep_Band  0x01              // Band(1byte*1)
#define Eep_Freq  0x10              // Frequency(4byte*8)
#define Eep_Step  0x30              // STEP(4byte*8)

////////////////////////////////
// frquency data
////////////////////////////////
const unsigned long FRQ_TBL[4] = {
 // DEF     LOW(cw)  MID(ssb)  HI
  7050000 ,7000000 ,7045000 ,7200000
  };

//---- data offset ------------
#define DEF_F  0
#define LOW_F  1
#define MID_F  2
#define HI_F   3

//---- IF offset --------------
#define IF    10700000
#define LSB   10701500
#define USB   10698500
#define CW    10700700

//---- ETC frequency mode -----
#define FT8_1 7041000
#define FT8_2 7074000
#define AM    7195000

////////////////////////////////
// etc
////////////////////////////////
#define Int_End   73                // Initial end code
#define LW_RIT    -5000             // RIT Lower Limit
#define HI_RIT    5000              //     Upper Limit

////////////////////////////////
// Set Device
////////////////////////////////
Rotary r = Rotary(D3,D4);
void ICACHE_RAM_ATTR enc_proc();
Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST);
Si5351 si5351(0x60);
Ticker ticker1;

//---------- Variable setting ------------------------------------------

unsigned long Vfo_Dat = 0;          // VFO data
unsigned long Bfo_Dat = 0;          // BFO data
unsigned int  Enc_Step = 1000;      // STEP

int  Rit_Dat = 0;                   // RIT Data
long Lng_Wk = 0;                    // Long Work
unsigned long Time_Passd = 0;       // Time Pass(ms)

int  Int_Wk = 0;                    // Integer Work
byte Flg_Tx = 0;                    // TX Flag
byte Flg_Mode = 0;                  // Mode Flag
byte Flg_Over = 0;                  // Over Flag
byte Flg_Rit = 0;                   // RIT Flag
byte Flg_enc = 0;                   // EEP Write Flag
byte Disp_Freq = 1;
byte Disp_Rit = 1;

//----------- setup ----------------------------------------------------

void setup(){
  pinMode(SW_TX,INPUT);       
  pinMode(SW_STEP,INPUT);       
  pinMode(SW_RIT,INPUT);       

  EEPROM.begin(128);

  r.begin(0);
  attachInterrupt(digitalPinToInterrupt(D3), enc_proc, CHANGE);
  attachInterrupt(digitalPinToInterrupt(D4), enc_proc, CHANGE);
  ticker1.attach_ms(2000, save_time);

  tft.init(240, 240);   // initialize a ST7789 chip, 240x240 pixels
  tft.setFont(&Org_01);
  tft.fillScreen(BLACK);
  delay(500);

  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
  si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_4MA);//Drive lebel 4mA set
  si5351.drive_strength(SI5351_CLK2,SI5351_DRIVE_4MA);//Drive lebel 4mA set

  if(EEPROM.read(Eep_Init) != Int_End){    // Eep initialaz
    delay(10);
    eep_init();
  }
  eep_rdata();

  si5351_freq(Vfo_Dat);

  band_check();
  mode_disp();
  step_disp();
  dot_disp();
}

//----------- main loop ------------------------------------------------

void loop(){
  meter_disp(analogRead(A0));                 // s-meter,Power meter   

///////////////////
//  Receive
///////////////////

  if(digitalRead(SW_TX) == LOW){          // RX?(TX is HIGH)
    if(digitalRead(SW_STEP) == LOW){      // STEP?
      step_proc();
    }
    if(digitalRead(SW_RIT) == LOW){       // RIT?
      rit_disp(Rit_Dat);
      rit_proc();
    }

    if(Flg_Mode == 3)
      si5351.output_enable(SI5351_CLK2, 0); // VFO disable
    else
      si5351.output_enable(SI5351_CLK2, 1); // VFO enable
    si5351_bfo(Bfo_Dat);

    si5351.output_enable(SI5351_CLK0, 1);   // VFO enable
    freq_disp(Vfo_Dat); 

    if(Flg_Rit == 1)
      si5351_freq(Vfo_Dat+IF+Rit_Dat);      // Frequency(RIT) data out
    else
      si5351_freq(Vfo_Dat+IF);

    Flg_Tx = 0;
    band_check();
    mode_disp();
    yield();
  }

///////////////////
//  Transmit
///////////////////

  else{                                     // TX
    if(Flg_Over == 0){
      si5351.output_enable(SI5351_CLK0, 1); // VFO enable
    }
    else{
      si5351.output_enable(SI5351_CLK0, 0); // VFO disable
    }
    si5351_freq(Vfo_Dat+IF);                // Frequency data out
    Flg_Tx = 1;
    yield();
  }

///////////////////
//  Common
///////////////////
 
  tx_disp();

  if(Flg_Rit == 1){
    if(Disp_Rit == 1){
      rit_disp(Rit_Dat);
      Disp_Rit = 0;
    }
  }
}

//----------  Write EEPROM  --------------------------------------------

void save_time(){
noInterrupts();
  if(Flg_enc == 1){
    eep_wdata();
    Flg_enc = 0;
  }
interrupts();
}

//----------  Write EEPROM 4byte  --------------------------------------

void eep_write4(long value,int address){
  address += 3;
  for(int i = 0;i < 4;i++){
    byte toSave = value & 0xFF;
    if(EEPROM.read(address) != toSave){
      EEPROM.write(address,toSave);
      EEPROM.commit();
    }
    value = value >> 8;
    address--;
  }
}

//----------  Read EEPROM 4byte  ---------------------------------------

long eep_read4(int address){
  long value = 0;

  for(int i = 0;i < 4;i++){
    value = value | EEPROM.read(address);
    if( i < 3){
      value = value << 8;
      address++;
    }
  }
  return value;
}

//----------  EEPROM Dat Read  -----------------------------------------

void eep_rdata(){
  Vfo_Dat = eep_read4(Eep_Freq);
  Enc_Step = eep_read4(Eep_Step);
}

//----------  EEPROM Dat Write  ----------------------------------------

void eep_wdata(){
  eep_write4(Vfo_Dat,Eep_Freq);
  eep_write4(Enc_Step,Eep_Step);
}
 
//----------  EEPROM Initialization ------------------------------------

void eep_init(){
  int i;

  for (i=0;i<128;i++){                       // 0 clear(128byte)
    EEPROM.write(i, 0);
    EEPROM.commit();
  }
  eep_write4(FRQ_TBL[DEF_F],Eep_Freq);
  eep_write4(1000,Eep_Step);                // Step(1kHz)
  EEPROM.write(Eep_Init,Int_End);           // Init end set(73)
  EEPROM.commit();
  }

//---------- over display ------------------------------------------------

void over_disp() {
  static byte Flg_Overb = 0;

  if((Flg_Over == 1) && (Flg_Overb == 0)){
    tft.fillRect(0,208,240,32,BLACK);
    tft.setTextSize(3);
    tft.setCursor(0, 232);
    tft.setTextColor(MAGENTA);
    tft.print("OUT OF RANGE");
    Flg_Overb = Flg_Over;
  }
  if((Flg_Overb == 1) && (Flg_Over == 0)){
    tft.fillRect(0,208,240,32,BLACK);
    Flg_Overb = Flg_Over; 
  }
}

//---------- TX display ------------------------------------------------

void tx_disp() {
  static byte Flg_Txb = 0;

  if((Flg_Tx == 1) && (Flg_Txb == 0)){
    tft.fillRect(0,208,240,32,BLACK);
    tft.setTextSize(3);
    tft.setCursor(0, 232);

    if(Flg_Over == 1){
      tft.setTextColor(MAGENTA);
      tft.print("OUT OF RANGE");
    }
    else{
      tft.setTextColor(YELLOW);
      tft.print("SENDING");
    }
 
    Flg_Txb = Flg_Tx;
  }

  if((Flg_Txb == 1) && (Flg_Tx == 0)){
    tft.fillRect(0,208,240,32,BLACK);
    if(Flg_Rit == 1)
      rit_disp(Rit_Dat);
    Flg_Txb = Flg_Tx; 
  }
}

//---------- Frequency display -----------------------------------------

void freq_disp(long freq){
  static char buf[10]="";
  static char bufb[10]="";

  long_asc(buf,freq);
  tft.setFont(&Org_01);
  tft.setTextSize(6);
  for(int i=0;i<8;i++){
    if(buf[i]!=bufb[i]){
      switch(i){
        case 0:
          tft.fillRect(132+72,155,35,46,BLACK);
          tft.setCursor(135+72, 195);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
        case 1:       
          tft.fillRect(132+36,155,35,46,BLACK);
          tft.setCursor(135+36, 195);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
        case 2:
          tft.fillRect(132,155,35,46,BLACK);
          tft.setCursor(135, 195);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
        case 3:
          tft.fillRect(0+72,155,35,46,BLACK);
          tft.setCursor(0+72, 195);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
        case 4:
          tft.fillRect(0+36,155,35,46,BLACK);
          tft.setCursor(0+36, 195);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
        case 5:
          tft.fillRect(0,155,35,46,BLACK);
          tft.setCursor(0, 195);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
        case 6:
          tft.fillRect(0+36,110,35,46,BLACK);
          tft.setCursor(0+36, 150);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
        case 7:
          tft.fillRect(0,110,35,46,BLACK);
          tft.setCursor(0, 150);
          tft.setTextColor(GREEN);
          tft.print(buf[i]);
          bufb[i] = buf[i];
          break;
      }
    }
  }
}

//----------  band chek  -----------------------------------------------

void band_check(){
  if((Vfo_Dat >= FRQ_TBL[LOW_F])
      && (Vfo_Dat <= FRQ_TBL[MID_F])){
    Flg_Mode = 0;                             // CW(0=CW, 1=LSB, 2=USB) 
    Flg_Over = 0;
    Bfo_Dat = CW;
  }
  else if((Vfo_Dat >= FRQ_TBL[MID_F])
      && (Vfo_Dat <= FRQ_TBL[HI_F])){
    if(Vfo_Dat >= 10000000){                   // greate than 10MHz                     
      Flg_Mode = 2;                           // USB(0=CW, 1=LSB, 2=USB)
      Bfo_Dat = USB;
    }   
    else{
      Flg_Mode = 1;                           // LSB(0=CW, 1=LSB, 2=USB)
      Bfo_Dat = LSB;
    }
    Flg_Over = 0;
  }
  else{
    Flg_Mode = 3;                             // AM
    Flg_Over = 1;
  }

  if((Vfo_Dat == FT8_1) || (Vfo_Dat == FT8_2)){
    Flg_Mode = 2;
    Bfo_Dat = USB;
    Flg_Over = 0;
  }

  if(Vfo_Dat == AM){
    Flg_Mode = 3;
    Flg_Over = 0;
  }
}

//---------- Mode display ----------------------------------------------

void mode_disp() {
  static byte Flg_Modeb = 73;

  if(Flg_Mode != Flg_Modeb){
    tft.setFont(&Org_01);
    tft.setTextSize(3);

    if (Flg_Mode == 0){                         // 0=CW
      tft.fillRect(185,138,52,15,BLACK);
      tft.setCursor(185, 150);
      tft.setTextColor(CYAN);
      tft.print("CW ");
    }
    else if(Flg_Mode == 1){                     // 1=LSB
      tft.fillRect(185,138,52,15,BLACK);
      tft.setCursor(185, 150);
      tft.setTextColor(CYAN);
      tft.print("LSB");
    }
    else if(Flg_Mode == 2){                     // 2=USB
      tft.fillRect(185,138,52,15,BLACK);
      tft.setCursor(185, 150);
      tft.setTextColor(CYAN);
      tft.print("USB");
    }
    else if(Flg_Mode == 3){                     // 3=AM
      tft.fillRect(185,138,52,15,BLACK);
      tft.setCursor(185, 150);
      tft.setTextColor(CYAN);
      tft.print("AM ");
    }

    Flg_Modeb = Flg_Mode;
  }
}

//----------- Dot display ----------------------------------------------

void dot_disp(){
  tft.setFont(&Org_01);
  tft.setTextSize(6);
  tft.setCursor(115, 195);
  tft.setTextColor(GREEN);
  tft.print(".");
}

//----------  long to ascii  -------------------------------------------
 
char *long_asc(char *str,long n){
  int  i = 0;                       // Write the number
  char *p = str;
  unsigned long  u = abs(n);

  do{
    *p++ = "0123456789"[u % 10];
    u = u / 10;
    i++;
    }
  while( 0 != u )
    ;
   *p = '\0';
}

//----------  si5351 PLL Output  ---------------------------------------

void si5351_freq(unsigned long freq){
  si5351.set_freq(freq * SI5351_FREQ_MULT, SI5351_CLK0);
}

//----------  si5351 PLL Output  ---------------------------------------

void si5351_bfo(unsigned long bfo){
    si5351.set_freq(bfo * SI5351_FREQ_MULT, SI5351_CLK2);
}

//----------- s-meter --------------------------------------------------

void meter_disp(uint16_t signalLevel){
  static int a1b,a2b = 0;
  const int hMeter = 120;                                   // horizontal center
  const int vMeter = 120;                                   // vertical center
  const int rMeter = 120;                                   // needle length

//  signalLevel = map(signalLevel, 0, 127, 0, 1023);
  float smeterValue = (signalLevel) * 330 / 1024;           // convert the signal
  smeterValue = smeterValue - 34;                           // shifts needle to zero position
  tft.drawBitmap(0, 0, myBitmap, 240,88, WHITE);            // draws background
  int a1 = (hMeter + (sin(smeterValue / 35.0) * rMeter));   // meter needle horizontal coordinate
  int a2 = (vMeter - (cos(smeterValue / 35.0) * rMeter));   // meter needle vertical coordinate

  if((a1 != a1b) || (a2 != a2b)){
    tft.drawLine(a1b, a2b, hMeter, vMeter, BLACK);          // clear needle
    a1b = a1;
    a2b = a2;
    tft.drawLine(a1, a2, hMeter, vMeter, WHITE);            // draws needle
    delay(1);
  }
}

//----------  rit proc  ------------------------------------------------

void rit_proc(){
  if(Flg_Rit == 0){
    Flg_Rit = 1;
//    eep_wdata();
  }
  else{
    Flg_Rit = 0;
    Rit_Dat = 0;
    Disp_Freq = 1;
    tft.fillRect(0,208,240,32,BLACK);
  }
  while(digitalRead(SW_RIT) == LOW)
    yield();
}

//----------  RIT Display  ---------------------------------------------

void rit_disp(int rit_data) {
  unsigned int ri,rit;

  tft.fillRect(42,208,154,32,BLACK);
  tft.setFont(&Org_01);
  tft.setTextSize(3);
  tft.setCursor(0, 232);
  tft.setTextColor(YELLOW);
  tft.print("RIT ");

  if (rit_data > 0)
    tft.print('+');

  tft.print(rit_data);
}

//----------  Rotaly Encorder  -----------------------------------------

void enc_proc() {                     // rotary encoder events
unsigned char result = r.process();

  if(Flg_Tx == 0){
    if(result) { 
      Disp_Freq = 1;
      Disp_Rit = 1;

      if(result == DIR_CW){
        Lng_Wk = Vfo_Dat + Enc_Step;
        Int_Wk = Rit_Dat + Enc_Step;
      }
      else{
        Lng_Wk = Vfo_Dat - Enc_Step;
        Int_Wk = Rit_Dat - Enc_Step;
      }

      if(Flg_Rit == 1)
        Rit_Dat = Int_Wk;
      else{
        Vfo_Dat = Lng_Wk;
        Rit_Dat = 0;
      }
      Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT);  // RIT range check
      Flg_enc = 1;
    }
  }
}

//----------  step proc ------------------------------------------------

void step_proc(){
  if(Enc_Step == 1000)                       // Step = 10Hz ?
    Enc_Step = 10;                       //   Yes,1khz set
    else
      Enc_Step = Enc_Step * 10;            // Step down 1 digit

  step_disp();
  while(digitalRead(SW_STEP) == LOW)
    yield();
}

//----------  Function STEP Display  -----------------------------------

void step_disp(){
  tft.fillRect(185,113,52,15,BLACK);

  tft.setFont(&Org_01);
  tft.setTextSize(3);
  tft.setCursor(190, 125);
  tft.setTextColor(CYAN);

  switch(Enc_Step){
    case 10:
      tft.println("10 ");
      break;
    case 100:
      tft.println("100");
      break;
    case 1000:
      tft.println("1k ");
      break;
  }
}
   
   

29 件のコメント:

Mikele 9a3xz さんのコメント...

bravooo,very nice dds project.Congratulations.
i like yours and ja2nkd projects.
all the best.

JA2GQP さんのコメント...

Hi Michael.
Thank you for your comment. I've always longed for analog meters. I am very satisfied with the realization of an analog meter.

Alex, US5EVD さんのコメント...

Which library to use with this project?
There are many compilation errors with my library.

Alex, US5EVD さんのコメント...

Which Adafruit_GFX library to use with this project?
There are many compilation errors with my library.

JA2GQP さんのコメント...

Hi Alex.

This 1.2.2 is installed in Arduino IDE.
https://github.com/adafruit/Adafruit-GFX-Library

Alex, US5EVD さんのコメント...

Tnx, My friend!

Alex, US5EVD さんのコメント...

compilation is OK.

Screen is black....

SO does not compile:
#define TFT_DC D8 // DC
#define TFT_RST D6 // RES

compiles just like this:
#define TFT_DC 15 // DC
#define TFT_RST 12 // RES
#define TFT_MOSI 13 // SDA
#define TFT_SCLK 14 // SCL
#define SW_TX 16 // D0
#define SW_RIT 3 // RX
#define SW_STEP 1 // TX
where is the problem?
:(

JA2GQP さんのコメント...


Alex.
Arduino IDE environment seems to be different. It is the same even if you write the port number directly. There is no problem.

Alex, US5EVD さんのコメント...

Thank you, I will understand further.

JA2GQP さんのコメント...

Alex.
The GPIO designation may be written directly.
#define TFT_DC 15 // DC (D8)
#define TFT_RST 12 // RES(D6)
#define TFT_MOSI 13 // SDA(D7)
#define TFT_SCLK 14 // SCL(D5)
#define SW_TX 16 // D0(16)
#define SW_STEP 1 // TX(1)
#define SW_RIT 3 // TX(1)

This is no problem. Another problem is that the TFT displays black.
You do not know which esp8266 board you are using and what kind of circuit it is.
The board and Arduino IDE environment are not what I answer.

Alex, US5EVD さんのコメント...

Thank!
I did it!
I used a different library

#include "src/Adafruit_ST7789.h"
//#include "src/Arduino_ST7789.h" 22-07-20


https://simple-circuit.com/esp8266-nodemcu-st7789-tft-ips-display/

Thanks for an interesting project!
I will study it further.

Alex, US5EVD さんのコメント...

http://us5evd.blogspot.com/

JA2GQP さんのコメント...

Alex.
You are the first to be reported working on this project.
Great.

Alex, US5EVD さんのコメント...
このコメントは投稿者によって削除されました。
Alex, US5EVD さんのコメント...
このコメントはブログの管理者によって削除されました。
Alex, US5EVD さんのコメント...

I continued to work on the project.

http://us5evd.blogspot.com/

JR1MOP さんのコメント...

こんにちは いつも楽しく拝見させていただいて
おります。 ESP8266VFOをDC受信機用に製作し
ました。 動作に判らないところがありコメント
欄に投稿しました。 ロータリエンコーダのコモン
をアースしていると起動しません。 アースを外し
て電源を入れると起動しますが、アースがないので
周波数は変えられません。 起動後にアースをつな
ぐと8266のアンテナ部分にあるブルーLEDが点灯し
ます。 繋いでも周波数は変えられません。 数個
のエンコーダを試しましたが同一症状でした。 
使用したのはARDUINO用の安価なものです。 ご指
定のエンコーダがあれば教えていただければ幸いです。
よろしくお願いします。 

JA2GQP さんのコメント...

JR1MOP OM

エンコーダは、手持ちの色々色々を試験しましたが、全く問題ありませんでした。

電源on時にブルーLEDが点灯するのは、エンコーダがLowレベルになっているからです。多分、エンコーダの中間位置にあるのでクリック感がある所(1クリック)に回してみてください。

それでもLEDが点灯しているならば、エンコーダA,B端子を3.3kから4.7kを3.3Vに繋いでみてください。(スケッチではpullupしてないので、A、B端子ともプルアップしてみてください)

JA2GQP さんのコメント...

JR1MOP OM
エンコーダが使えるか否かは、テスタでA-C間、B-C間、A-B間をあたり各間オープンで、回転させると導通が有れば問題ありません。(正常です)

JR1MOP さんのコメント...

JA2GQP様
早速の回答ありがとうございます。
部品を用意して試してみたいと思います。
エンコーダは、はるばる中国から来たので
たぶんお疲れなのだと思います。
73

JR1MOP さんのコメント...

解決しました。

JA2GQP様
ご教授ありがとうございました。無事に解決です。
原因はロータリーエンコーダでした。今回5個購入
したのですが、4個が端子間導通してました。
残りの1個を試したところバッチリ動作しました。
本当にありがとうございました。新品だったので
信用してしまいました。

JA2GQP さんのコメント...

JR1MOP OM
了解しました。それにしても、4個不良とは酷いですね。私も中華で購入してますが、今迄不良品に出会ったことは有りません。解決して何よりでした。

Mikele 9a3xz さんのコメント...

helloooo!
when i first time conecting everything is ok and i rotate rotary encoder untill 3,5mhz when i conecting again my wemos in tft said "out of range" i reprogramming wemos but still is "out of range" ...whats the problem maybe you know ???thankksssssss.
73 de 9a3xz Mikele

Mikele 9a3xz さんのコメント...

now is ok...tonight i put video on my YT channel.
thankssssss for another nice project !
73 de 9a3xz Mikele

Mikele 9a3xz さんのコメント...

https://youtu.be/bgGARo6eazc

Once again, thanks for nice project!
73 de 9a3xz

JA2GQP さんのコメント...

Hi Mikel.
Tweeted. My Twitter is full of flowers. Hi, Hi
https://twitter.com/ja2gqp/status/1327353790215770112

Mikele 9a3xz さんのコメント...

thanks...now i waiting SI4735 from ebay for your last project and will see how is working:)
all the best and see you soon.
73 de 9a3xz Mikele

charlie さんのコメント...

Great project. Can we have a web based tuning mechanism for this project ? Host a web page on the esp8266 and accomplish a tuning control.

JA2GQP さんのコメント...

Hi Charlie.
It's a chip that can control the Web, so I'd like to support it. There are issues such as Web API creation, and I don't know if it will end with just the concept.