jl7gmnのblog

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

2019年09月

Arduino その4

Windows10のブルースクリーンエラーがでて、書いていたブログが消えてしまいました。30分以上かかっていたので、がっくりです。前のヤフーのブログでは、今回のような時も途中のデータまでの文章が残っていますと表示されるような素晴らしい機能がありましたが、今回は全く、書いたものすべてが消えています。とまあ、頭にきたのですが、そうもばかリ言っておられません。

風が吹いている内に、という事で、Arduino UNOを使い、Si5351A使用3ch出力クロックジェネレータモジュールでのTS-820用VFOを考えています。Si5351AはSILICON LABS社製で、I2C接続で使い、2.5KHz~200MHzの周波数を出力することができるクロックジェネレータモジュールです。秋月の通販で3個購入してあります。実は、1個購入して、最初うまく動作せず、壊したかと思い、後から2個追加で購入したのですが、スケッチの書き間違いとかの単純ミスで、動かなかっただけで、最初の1個目のSi5351も結局は問題ありませんでした。Aruduino UNOでのスケッチサンプルがWebで結構ありました。今回VFO用に今回参考にさせていただいたのは、JA2GQP局のブログとダウンロードサイトのスケッチや、ライブラリです。ほぼ丸ごとコピーで動作確認から最初やってみました。再現性は100%でした。私が使わせせていただいたのは、下記の2つのスケッチと対応するライブラリです。
https://sites.google.com/site/ja2gqp/

Si5351_oled(128x32) 
Si5351_oled(128x64)

の2つです。
TS-820のVFOに改良するDDSサンプルはoled(128x32)にすることにしました。
また、oled(128x32)は使用しないで、手持ちの1602の液晶ディスプレー用に、インクルードファイルと、液晶部のコードを全部書き換えました。

”//” で以下の部分のコードをコメント化します。
インクルードファイルでは,ヘッダーの保管場所も変えて簡単に記載できるように直しています。

//#include "src/Rotary.h"               // http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
#include "Rotary.h"               // http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
//#include "src/si5351.h"               // https://github.com/etherkit/Si5351Arduino, v2.1.0
#include "si5351.h"               // https://github.com/etherkit/Si5351Arduino, v2.1.0
//#include "src/SSD1306AsciiAvrI2c.h"   // https://github.com/greiman/SSD1306Asc
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

////////////////////////////////
// Set Device
////////////////////////////////
Rotary r = Rotary(2, 3);
Si5351 si5351(0x60);                 // Si5351 I2C address
   //SSD1306AsciiAvrI2c oled;
LiquidCrystal_I2C lcd(0x27,16,2);

他コード中のoledのコードはコメント化して、新たな1602用のコードで書き換えで対応できました。

液晶上の送受切替表示、モード表示、周波数表示、ステップ表示、Sメータ表示、コールサインはこんな感じに配置しました。
CIMG8091

もともとの仕様で送受切替SW、ステップ切替SW、バンド切替SWの3つのSWがありますが、最終的には状況で対応します。VFOの機能はまだ深く考えていません。とにかく最初なので、5.500.00~5.000.00MHz(7.000.00~7.500.00MHz)までロータリーエンコーダーで可変できれば良しとします。
その前に、TS-820のVFOの周波数と実際のバンドの対応を見ると、5.5MHzで7.000MHz エッヂの5.000MHzでは7.500MHzとVFOの周波数は下がる方向で7MHzの送受信周波数は上がるので、通常のDDSでは周波数を上げていくと、7.5MHzから下がっていくことになり、具合が悪い動作になってしまします。
先ずは、これを解決する必要があります。TS-820のサービスマニュアルをWEBでダウンロードしてあったので、PLLとVCO辺りを確認してみました。以下の関係がありました。

TRX-FREQ    7.000MHz       7.500MHz
VCO-FREQ  15.830MHz     16.330MHz
VFO-FREQ    5.500MHz        5.000MHz
IF-FREQ        8.830MHz        8.830MHz

HET_FREQ = TRX-FREQ + VFO-FREQ
HET_FREQ=  12.500MHz

このHET-FREQより発振するVFO周波数が得られることがわかります。
DDSで発振する周波数をFREQとするとVFOの発振周波数は

FREQ =(HET_FREQ-FREQ) 

になります。
7.000MHzでは
FREQ=(12.500MHz-7.000MHz) より5.500MHzがVFOのデータとなり、これを送ればよいとなります。
7.200MHzでは
FREQ=(12.500MHz-7.200MHz) より5.300MHz がVFOのデータとなり、これを送ればよいとなります。

上記の理屈から以下の2か所のsi5351Aへの周波数設定部分を次の様に書き換えました


①void loop ()内の周波数設定箇所 


if(Flg_Over == 0){                      // Within transmittable range?
      si5351.output_enable(SI5351_CLK0, 1); // VFO enable
      if(Flg_Vfo == 1){
        //si5351_set_freq(Vfo_Dat + TX_IF);
        si5351_set_freq(HET_FREQ-(Vfo_Dat + TX_IF));      // 2019/sep/22 7Mhz Tx;
        Flg_Vfo = 0;
      }
    }

②si5351 PLL Outputルーチン内の周波数設定箇所の書き換え
//----------  si5351 PLL Output  ---------------------------------------
void si5351_set_freq(uint32_t frequency) {
  //frequency = frequency + awase;
  frequency = HET_FREQ-(frequency + awase); //TS-820 VFO freq set
  Serial.print(frequency);
  Serial.print("\n");
  si5351.set_freq(frequency * SI5351_FREQ_MULT, SI5351_CLK0);
}

①と②のTX_IF やRX_IF、awase 他は宣言で設定します。
送信と受信のオフセットは例では、受信が10.7MHzのオフセットとなっています。自分の装置のIFに合わせて設定できるのでこの機能はとても便利ということですね。
今回は送信も受信も使わないので、設定値は0です。
使うのはHET_FREQの12.500MHzです。

//---- IF offset -------
//const unsigned long RX_IF = 10700000;
const unsigned long RX_IF = 0;
const unsigned long TX_IF = 0;
const unsigned long HET_FREQ = 12500000;  //TS-820 VFO 2019/sep/22
const int awase=40;    //frequency 周波数補正


サンプルのTS-820用外部VFO用の書き換えは以上ですが、他にも変更した箇所があります。アナログポートを一部デジタルポートへ変更しました。
単純に空いているデジタルポートへすれば良いわけではなく、スケッチをよく見てみると、既にデジタルポートの void setup()内でpinModeにて設定済み(割り当て済み)は使えない事になります。
9,10,11,12,13のデジタルポートは使えません。
なので、8,7,4に変更しました。
void setup() {
  Serial.begin(9600);
  pinMode(SW_STEP, INPUT_PULLUP); //INPUT 4
  pinMode(SW_TX, INPUT_PULLUP);   //INPUT 8
  pinMode(SW_BAND, INPUT_PULLUP);  //INPUT 7
  pinMode(9, OUTPUT);                 // Band1         
  pinMode(10, OUTPUT);                //     2         
  pinMode(11, OUTPUT);                //     3          
  pinMode(12, OUTPUT);                // LOW=none, HOGH=CW
  pinMode(13, OUTPUT);                // LOW=USB,  HIGH=LSB         
  attachInterrupt(0, rotary_encoder, CHANGE);
  attachInterrupt(1, rotary_encoder, CHANGE);


下記のSW類です。
入力ポートとして、使えそうなのでA0,A1,A2,を空けました。A3はSメータ入力ポートで使用済み, A4,A5はsi5351のI2C接続で使用済み
もともとのA7はArduino UNOにはないので(miniにはある?手持ちにまだないので?)、入力ポートA3に変更して使用しました。
////////////////////////////////
// I/O Port
////////////////////////////////
//const byte SW_BAND = A0;              // Band SW
//const byte SW_STEP = A1;              // STEP SW
// const byte SW_TX = A2;                // TX/RX
//const byte AD_SM = A7;                // S-meter AD

const byte AD_SM = A3;   // s-meter AD
const byte SW_TX = 8;           // TX/RX
const byte SW_STEP = 7;         // STEP SW
const byte SW_BAND = 4;         //Band SW


他にSメータの表示があります。数値にしてディスプレーに表示してますがが、検討の余地があります。
ほか、オリジナルのスケッチにバンドの下限と上限データがありTX時に範囲外では発振停止という面白いフィーチャーがありました。とても使えます。VFOでは受信も送信もRX状態で使用するので使えませんが、送信機機能のTXスイッチを使用するときは利用できます。(オフバンド考慮)

下限が7.000.00MHz 上限が7.200.00MHzにしておけば、VFOも下限上限を外れると送信時に発振しません。
以上、LEDチカから飛躍のDDSへトライでしたが、スケッチが素晴らしい為、すんなりとVFOが出来そうな感じになりました。まだいろいろと検討が必要なところがあります。Sメータの入力回路(倍電圧整流等)、DDS出力のローパスフィルター、バンド毎のHET_FREQへの自動対応(ハイレベル?)
ヤルことはいっぱいありますが、どれから手をつけていきましょうか?

つづく?

Arduino その3

Arduinoがとても使いやすいし簡単なので、つい、AmazonでArduino互換のKKHMF UNO R3開発ボード USB付属、KKHMF DC 5V 1602 LCDディスプレーモジュール、EasyWordMall 1602 LCDブラックIIC/I2C/TWI/SPIシリアルインターフェースボードモジュール、KKHMFはんだブレッドボード400ネクタイArduino用、Pinbotronix0.91 IIC I2CシリアルOLED液晶ディスプレイモジュール(I2C SSD1306白色I2C OLEDスクリーンドライバArduino用DC 128X32 3.3V〜5V AVR PIC UNO MEGA Arduino ),Rasbee Mini USB Nano V3.0 マイクロコントローラボードArduino用(Atmega328P CH340G 5V 16MHz NANOボードNano V3モジュールCH340改造バージョンを注文しました。一応ネット上のたくさんある例スケッチサンプルでよく使われているものを選んでの注文です。
9月10日の注文で、早いものでシリアルOLED液晶モジュールは13日に届きました。ほか、Atmega328P CH340G 5V 16MHz NANOボード以外の物は18日に届いています。

Arduino互換-KKHMF-UNO-R3

Arduino互換-KKHMF-UNO-R3-package


全部中国からの配達です。予定よりは早く到着しています。また、秋月電子の通販では0.96インチOLED液晶モジュールの128X64 、ロータリーエンコーダ、3CH出力プログラマブル周波数ジェネレーターモジュール【AE-Si5351A-B】、FT234X超小型USBシリアル変換モジュール、片面ガラスコンポジット・ユニバーサル基板など注文しました。表示はI2C通信のディスプレーで行うのが接続線が少なくていいと思っての購入です。

購入したものでだいたい何をやるのかがわかるかと思います。特に秋月の通販で購入した物がメインのスケッチを作成していく対象です。以前、DDS用のICでAD9834を使ったDDS-VFOの製作のコピーを行いましたが、今回も物は違いますが、3CH出力プログラマブル周波数ジェネレータモジュール(Si5351A)を使ってDDS-VFOをPICでなく、Arduino UNOで行います。勿論、スケッチはWEB上の実用的な素晴らしいOMさんが作成したスケッチのコピーです。何よりも、最初から作るのではなく、動くものをまねてやってみて、楽しむことからやるのが、一番飽きずに続けれるのではないかと思っています。なので、素晴らしいスケッチを公開してくれてるOMには、本当に感謝です。Hi!

Arduinoの駆け出しLEDのチカから、突然DDS-VFOのスケッチへと飛びますが、まずは、いいものを経験してからという考えです。後から、理屈はわかってくると思います。という事で、この予定しているDDS-VFOは、実は30年以上も前のトランシーバーのアナログVFOをDDS-VFOにする為、という事が雄一の目的です。無線機はTRIO(今はKENWOOD)のTS-820V(改)です。

今日は、互換UNOが動作するか、まず確認です。届いてから先ず、PCに繋いでみました。レビューではWindows10では自動でドライバーインストール不要だったとかありましたが、繋いだところ、LEDが点滅して動作しませんでした。レビューのなかにドライバーをダウンロードしてインストールしてOKだったというのもありましたので、以下の中国のドライバー提供WEBを検索して、ダウンロードしてやってみました。実は、Windows10ではシリアルケーブルで、CH340のドライバーは入っていましたが、それでは動いてくれませんでした。以前購入したCH340のシリアル通信用のドライバーでは、ダメでした。

「江苏沁恒股份有限公司」で検索してホームページのドライバーをダウンロードです。

CH341SER-EXE
クリックして次のページを開きます。

DRIVER-CH341


ダウンロード
上記をクリックしてダウンロードされます。

ダウンロード後、実行すると以下のフォームが表示され、インストール、アンインストールなどを選んで行えます。

driver-setup64

上記のINSTALLをクリックしてドライバーをインストールします。

繋いだ互換Arduino はLEDが点滅していますが、このままの状態で、確認済みのスケッチを開いて、コンパイルして、ボードへ書き込みをしてみます。点滅が止まり、書き込みLEDがひかって、点灯に変わり動作しました。

専用のドライバーを宛てるのが一番間違いないようです。

次から、参考にした、OMさんのホームページ、ブログ等のDDS-VFOを参考にスケッチを作成してゆきます。

とてもシンプルに構成できるところがArduinoの魅力でもあります。

つづく?



Arduino その2

Arduino UNOが面白くなってきました。最初の、LEDを光らせて、シリアル通信を確認して、とってもやり易いとの第一値印象を得ました。即、液晶ディスプレーを秋月電子の通販に注文しました。4線式のI2C接続タイプのものです。本当の目的は、DDSのVFOを製作したいが為です。先ずは、使用する液晶部の準備、確認からという訳です。なにせ、超初心者ですから! Hi 

I2Cタイプの液晶は2種類ほど購入しました。まず最初に試したのはSC1602BBWB-XA-GB-G です。
I2C接続小型キャラクタLCDモジュール(16×2行・3.3V/5V)ピッチ変換キットです。
http://akizukidenshi.com/catalog/g/gK-08896/

早速付いてきた変換用基板にLCDと端子を半田付けして、Arduino Unoに接続してゆきます。のっけから少し迷いました。Arduinoには種類があるため、それぞれがハードの違いに合わせた端子を使う必要がある様です。接続端子の数は4本ありますが、SCL,SDA端子は下記の様に、自分のArduinoに合わせます。

私のはArduino UNOなので
SCL ⇒ A5
SDA ⇒ A4
となります。他は、+Vは+5Vへ、GNDはGNDへで共通です。

上記の使用する端子はWire Libraryの下記URLで確認できます。
https://www.arduino.cc/en/Reference/Wire

とにかく、早くディスプレーに何かを表示して見たくて、ネットのサンプルを新規からスケッチしました。
ところが、です。コーディング終了して、検証コンパイルをすると、残酷にも、エラーがでました。
打ち間違いはないので、チョットお手上げ状態に一瞬なりました。少し冷静に考えて、まずは、ネットの例よりも提供されているサンプルを試してみようとふと思いつきました。スケッチ例より LiquidCrystal 下サンプルのHelloWorldのサンプルを読み込みしました。
I2C接続ではない、データ線を使った通常の接続のスケッチです。接続は全く異なりますが、コンパイル可能かの確認の為だけの読み込みです。

HelloWorld001
上記を検証コンパイル可能か実施してみますと、エラーも出ずコンパイル完了しました。
書き込みもArduinoUnoではディスプレーには表示しませんが、書き込みの表面上動作は大丈夫でした。

という事で、問題なくコンパイルできたこのスケッチを利用して書き直しで試してみます。
HelloWorld001-a
コンパイルOKのスケッチを利用した結果は目論み通りOKでした。
新規で作製したスケッチでなぜエラーが出たかは不明ですが、この後に新規で最初のようにスケッチを一から
作製して再度確認しました。

HelloWorld001-b
結果は全く問題なく検証コンパイルでき、書き込みも動作もOKでした。
何だったのかは、わかりませんが、新規で作製しても、問題なくコンパイル、書き込み実行ができることになったので、結果オーライとします。

なお、ここで使用した液晶のサンプルは、下記のWEB上の物を利用させていただきました。
https://asukiaaa.blogspot.com/2016/01/arduino-leonardoae-aqm1602a.html

上記のページの中に インクルードファイルを作成してくれている方のURLがあります。
https://n.mtng.org/ele/arduino/i2c.html

以下のファイルの (最新)をありがたく、使わさせていただきました。いろいろな液晶に対応する優れたインクルードファイルのようです。
sc1602-i2cインクルードファイル
上記の説明通りにダウンロードして、展開し、LibrariesフォルダにコピーすればインクルードファイルをIDE上から他のインクルードファイルと同様に指定読み込みできるようになりました。

子のインクルードファイルは通常のArduinoにはありません。

なので、通常のArduinoの場合も一応確認しておきます。
スケッチのサンプルは秋月の液晶の説明書上のその物になります。

// Arduino 1.8.9
#include <Wire.h>
#define LCD_ADRS 0x3E

char moji[]="SC1602BBWB-XA-GB-G";

void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  init_LCD();
}

void loop() {
  for(int i=0;i<16;i++)
  {
    writeData(moji[i]);
  }
  writeCommand(0x40+0x80);
  for(int i=0;i<16;i++)
  {
    writeData(i+0xB1);
  }
  while(1){}
}

void writeData(byte t_data)
{
  Wire.beginTransmission(LCD_ADRS);
  Wire.write(0x40);
  Wire.write(t_data);
  Wire.endTransmission();
  delay(1);
}
void writeCommand(byte t_command)
{
  Wire.beginTransmission(LCD_ADRS);
  Wire.write(0x00);
  Wire.write(t_command);
  Wire.endTransmission();
  delay(10);
}

void init_LCD()
{
  delay(100);
  writeCommand(0x38);
  delay(20); 
  writeCommand(0x39);
  delay(20);
  writeCommand(0x14);
  delay(20);
  writeCommand(0x73);
  delay(20);
  writeCommand(0x52);  // 5V動作用
  //writeCommand(0x56);  // 3V動作用
  delay(20);
  writeCommand(0x6C);
  delay(20);
  writeCommand(0x38);
  delay(20);
  writeCommand(0x01);
  delay(20);
  writeCommand(0x0C);
  delay(20);
}

インクルードファイルは Wire.hになるようですが、やはり、初期化ルーチンなどの事細かな設定や、データとコマンドルーチンも作製する必要があり、若干余分にスケッチが長くなります。
ま、つかうことは可能ですが、やはり、専用のライブラリを作っていただいた方の方が、スケッチも簡単になります。

以上で問題なく液晶もI2C接続で出来ることがわかりました。 次は何をしましょうか?

つづく ?

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

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