回路図である。
ダイレクトコンバージョン受信機と組合わせた40m CW QRP機で、フルブレイクイン動作する。オリジナルからkey paddleとエンコーダのIO割付のみ変更。
スケッチ
基本的な処理は、オリジナルを継承している。RIT処理がアナログ処理で行われており、参考になる所もある。スケッチは、ダウンロードサイトのsi5351aフォルダ。/**************************************************************************
DIRECT CONVERSION CW TRANSCEIVER CONTROLLER WITH IAMBIC KEYER FOR ARDUINO
Uses SI5351 clock generator shild from Adafruit for VFO
Uses NT7S SI5351 library for Arduino on github:
https://github.com/etherkit/Si5351Arduino
2 x 16 LCD display for frequency, offset, and tuning rate
Has an iambic keyer with dot/dash memories
Arduino Pro Mini pin assignments:
2) Encoder A input
3) Encoder B input
4) STEP SW
5) Iambic paddle DSH input
6) Iambic paddle DIT input
7)
8) Transmit/mute output
9) Sidetone output
10) LCD RS output
11) LCD E output
12) LCD D4 output
13) LCD D5 output
A0) LCD D6 output
A1) LCD D7 output
A2)
A3)
A4) si5351 SDA
A5) si5351 SCL
A6) Offset voltage input
A7) Keyer speed voltage input
***************************************************************************/
#include <si5351.h>
#include "Wire.h"
#include <Rotary.h>
#include "src/LiquidCrystal.h" // use Arduino LCD library.
//---------- PLL setting --------------------
Si5351 si5351;
//---------- LCD setting --------------------
LiquidCrystal lcd(10, 11, 12, 13, A0, A1); // RS,E,D4,D5,D6,D7
//---------- Encorder setting ---------------
#define ENC_A 2 // Encorder A
#define ENC_B 3 // Encoeder B
Rotary r=Rotary(ENC_A,ENC_B);
////////////////////////ENCODER SETUP///////////////////////////////////////
#define SW_STEP 4
#define Pad_Dah 5
#define Pad_Dit 6
#define XMIT 8
#define TONE 9
#define LW_FRQ 7000000L
#define HI_FRQ 7200000L
long Vfo_Dat = 7030000L; //Start up frequency <<<2017/6/27>>>
long Vfo_Datb = 0; // <<<2017/6/27>>>
int Enc_Stp = 10; // STEP=10Hz
int rateindicator = 5;
char Lcd_data[17] = " ";
int Flg_Set0 = 1;
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////RIT SETUP//////////////////////////////////////
int rit = A6;
int ritvoltage = 0;
int oldritvoltage = 0;
int modulo = 0;
int ritcenter = 512;
int rittune = 0;
int rittuneb = rittune;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////IAMBIC KEYER////////////////////////////////////
int count = 0;
int dit = 1;
int dah = 1;
int sidetone = 700;
int ditmem = 0;
int dahmem = 0;
int sspeed = 50;
int speedinput = A7;
/////////////////////////////////////////////////////////////////////////////
//---------- Setup ---------------
void setup(){
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
lcd.begin(16, 2);
pinMode(Pad_Dah, INPUT_PULLUP); // Dah
pinMode(Pad_Dit, INPUT_PULLUP); // Dit
pinMode(SW_STEP, INPUT_PULLUP); // STEP
pinMode(TONE, OUTPUT);
pinMode(XMIT, OUTPUT);
digitalWrite(XMIT, HIGH);
PCICR |=(1<<PCIE2);
PCMSK2 |=(1 << PCINT18) | (1 << PCINT19);
sei();
Fnc_Step_Disp();
}
//---------- Main loop --------
void loop() {
if(digitalRead(SW_STEP) == LOW) // STEP SW On?
Fnc_Stp();
setclock0();
ritvoltage = analogRead(A6);
rittune = ritvoltage - ritcenter;
rittune = rittune * 5;
if (ritvoltage != oldritvoltage){
ritune();
}
if (ditmem == 1) makedit();
if (dahmem == 1) makedah();
sspeed = analogRead(speedinput);
sspeed = sspeed / 6.5;
if (sspeed < 24) sspeed = 24;
count = 0;
checkpaddle();
}
//---------- Encorder procedure(INT) ---------------
ISR(PCINT2_vect) {
unsigned char result = r.process();
if(result) {
if(result == DIR_CW)
Vfo_Dat = Vfo_Dat + Enc_Stp;
else
Vfo_Dat = Vfo_Dat - Enc_Stp;
Vfo_Dat = constrain(Vfo_Dat,LW_FRQ,HI_FRQ);
}
Flg_Set0 = 1;
}
//---------- Set Clock0 ---------------
void setclock0() { //function to set the SI5351 clock frequency
if(Flg_Set0 == 1){
lcd.setCursor(2, 0);
Fnc_Dot_Edit(Lcd_data,Vfo_Dat);
lcd.print(Lcd_data);
lcd.print(" MHz");
si5351.set_freq((Vfo_Dat + rittune) * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK0);
}
Flg_Set0 = 0;
}
//---------- RIT proc ---------------
void ritune() { //function to determine RIT offset frequency
modulo = 0;
oldritvoltage = ritvoltage;
rittune = ritvoltage - ritcenter;
rittune = rittune * 5; //RIT steps in 5 Hz increments
if (rittune > 30) { //Keep a dead zone near 0 offset
rittune = rittune;
}
else if (rittune < -30) {
rittune = rittune; //Keep a dead zone near 0 offset
}
else {
rittune = 0;
}
lcd.setCursor(8, 1);
lcd.print(" ");
lcd.setCursor(8, 1);
lcd.print("Rit");
if (rittune > 0) {
lcd.print("+");
}
lcd.print(rittune);
Flg_Set0 = 1;
setclock0();
}
//---------- Check Paddle ---------------
void checkpaddle() { //function for checking iambic paddle status
dit = digitalRead(Pad_Dit);
dah = digitalRead(Pad_Dah);
if (!dit) makedit();
if (!dah) makedah();
}
//---------- Dit make proc ---------------
void makedit() { //function to make dits
count = 0;
ditmem = 0;
si5351.set_freq(Vfo_Dat * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK0);
digitalWrite(XMIT, 0);
tone(TONE, sidetone);
while (count < sspeed) {
dah = digitalRead(Pad_Dah);
if (!dah) dahmem = 1;
delay(1);
++count;
}
count = 0;
noTone(TONE);
digitalWrite(XMIT, 1);
si5351.set_freq((Vfo_Dat + rittune) * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK0);
while (count < sspeed) {
dah = digitalRead(Pad_Dah);
delay(1);
++count;
}
}
//---------- Dah make proc ---------------
void makedah(){ //function to make dahs
count = 0;
dahmem = 0;
si5351.set_freq(Vfo_Dat * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK0);
digitalWrite(XMIT, 0);
tone(TONE, sidetone);
while (count < (sspeed * 3)){
dit = digitalRead(Pad_Dit);
if (!dit) ditmem = 1;
delay(1);
++count;
}
count = 0;
noTone(TONE);
digitalWrite(XMIT, 1);
si5351.set_freq((Vfo_Dat + rittune) * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK0);
while (count < sspeed) {
dit = digitalRead(Pad_Dit);
if (!dit) ditmem = 1;
delay(1);
++count;
}
}
//---------- Function String Dot Edit --------
char *Fnc_Dot_Edit(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++;
if((0 != u) && (0 == (i % 3)))
*p++ = '.';
}
while( 0 != u );
if ( n < 0 )
*p++ = '-';
*p = '\0';
Fnc_Revr( str );
return str;
}
//---------- Function String Reverse ---------
void Fnc_Revr(char *str){
int i,n;
char c;
n=strlen(str);
for(i = 0;i < n / 2;i++){
c=str[i];
str[i]=str[n - i - 1];
str[n - i - 1]=c;
}
}
//---------- Function Encorder STEP ---------
void Fnc_Stp(){
if(Enc_Stp == 10000) // Step = 10kHz ?
Enc_Stp = 10; // Yes,100khz set
else
Enc_Stp = Enc_Stp * 10; // Step up 1 digit
Fnc_Step_Disp();
while(digitalRead(SW_STEP) == LOW)
;
delay(50);
}
//---------- Function STEP Display ----------
void Fnc_Step_Disp(){
lcd.setCursor(0,1);
switch(Enc_Stp){
case 10:
lcd.print("Step10 ");
break;
case 100:
lcd.print("Step100");
break;
case 1000:
lcd.print("Step1k ");
break;
case 10000:
lcd.print("Step10k");
break;
default:
lcd.print("Step10 ");
Enc_Stp = 10;
break;
}
}
こんにちは、ARDUINO NANOのために、このプロジェクトのバージョンがありますか???
返信削除残念ですがありません。
返信削除ありがとう、Akio。
返信削除このプロジェクトに興味がありますか?
プログラムはarduino pro miniにロードする準備ができていますか?
何か追加する必要がありますか?
ありがとうLW4DZC(アルゼンチン)
とても良いブログです。
返信削除おめでとうございます
日本語でのコメントありがとうございました。
削除K4GC OFVかどうか知りたい
返信削除うまく動作するか、何らかの欠陥があります。
ありがとう LW4DZC (Argentina)
I want to know if the K4GC OFV
返信削除works well or has some defect ..
Thank you LW4DZC Argentina
K4GCのVFOはボリュームを使ったアナログコントロールで動作不良でした。その為、エンコーダを使った処理にしました。
削除私はこのプロジェクトを作りたいです。
返信削除興味がある
うまくいくことを願っています
お返事ありがとうございます
SKETCH LOAD ERROR
返信削除#include
si5351.h: No such file or directory
#include
返信削除si5351.h: No such file or directory
こんにちは、画面には完全なメニューが表示されますが、常に7030.00です。ステップを変更することはできますが、周波数はエンコーダーで変更されません。
返信削除問題は何ですか?
ありがとう
G2さん こんにちは
返信削除挙動がおかしいとの事でしたので、環境を作って試験しました。
エンコーダの配線に問題なければ、動作します。(動作するはずです。)
si5351の線が外れていても、エンコーダ操作で表示器は変わります。
問題は、エンコーダ配線不良または、半田付け不良と思われます。
I detect that the problem due to the next line.
返信削除´
'unsigned char result = r.process ();'
The process() function from Rotary.h is returning always empety (DIR_NONE) so it never enter de if statament.
Do you ever have this problem?
I try adding r.begin() in the setup by reading rotary documentation (https://github.com/brianlow/Rotary) but doesnt work.
Thank you.
G2
返信削除Sometimes I have problems, but I can't say anything because I don't have version control for the library.
I am using the latest version of the arduino IDE. It is convenient to use an older version for this project.
返信削除which version of arduino do you recommend using ???
Thank you so much
返信削除Hi G2.
I use the latest Arduino IDE. You don't seem to know where the problem lies. The problem is in Rotary.h. Download the Rotary library here.
https://github.com/buxtronix/arduino
Thank you very much for your help!!!!!
返信削除The vfo works perfectly now ..
A faulty solder on the chip generated the problem. Now it works very well !!!
Thanks and sorry for bothering.
LW4DZC
Hi LW4DZC.
返信削除I was relieved to work.
I wish you all the best. 73.
Hello
返信削除The vfo works perfectly, but it generates a very strong signal in the receiver, at approximately 7,024 Mhz.
What can be the motive???
Thank you very much, you are so kind
Guillermo LW4DZC
Hi G2.
返信削除Unfortunately, I don't have an environment to check.
I can't confirm, so I can't reply.