[Encoder]
秋月のロータリーエンコーダを使用する。BASCOMでエンコーダを操作するプログラム例はすぐに見つかるがArduinoではなかなか見つからなかった。
dialStep10PinとdialStep1000Pinを同時にOnしてエンコーダを回せば周波数は20kHzごとに変化します。この2つのピンは前日の回路図にあるように1N4148を通じてArduinoに接続する。
但し、まだDDSを接続させてVFOの機能はまだである。KEYの代用しているタクトスイッチを押すと画面表示が変わる。
dialStep10PinとdialStep1000Pinを同時にOnしてエンコーダを回せば周波数は20kHzごとに変化します。この2つのピンは前日の回路図にあるように1N4148を通じてArduinoに接続する。
但し、まだDDSを接続させてVFOの機能はまだである。KEYの代用しているタクトスイッチを押すと画面表示が変わる。
Sketch
//DDS_TestProgram by JA1NHL 21Apr 2012
//EncodeDisplayKeying
// include the library code:
#include <LiquidCrystal.h>
//LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
#include <Bounce.h>
// usually the rotary encoders three pins have the ground pin in the middle
int encoderPinA = 2;
int encoderPinB = 3;
int dialStep10Pin=8;
int dialStep1000Pin=9;
int ledPin=13; //monitor
int keyingPin=19;
long Fdata=7000000;
int FdataZoubun=100;
char TxRxState='R';
volatile long encoderPos = 0; // a counter for the dial
volatile long lastReportedPos = 0; // change management
static boolean rotating=false; // debounce management
boolean A_set = false; // interrupt service routine vars
boolean B_set = false;
Bounce bouncer=Bounce(keyingPin,5);
void setup() {
Serial.begin(9600); // output for Debug
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
// Input Output
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(dialStep10Pin, INPUT);
pinMode(dialStep1000Pin, INPUT);
pinMode(keyingPin, INPUT);
pinMode(ledPin,OUTPUT);
// turn on pullup resistors 内蔵プルアップ
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
digitalWrite(dialStep10Pin, HIGH);
digitalWrite(dialStep1000Pin, HIGH);
digitalWrite(keyingPin, HIGH);
//setup the LCD's number of columns and rows;
lcd.begin(16,2);
lcd.clear();
attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 0 (pin 2)
attachInterrupt(1, doEncoderB, CHANGE); // encoder pin on interrupt 1 (pin 3)
}
// main loop, work is done by interrupt service routines, this one only prints stuff
void loop() {
if (digitalRead (keyingPin) ==LOW){
digitalWrite(ledPin,HIGH);
TxRxState='T';
} else{
digitalWrite(ledPin,LOW);
TxRxState='R';
} displayKeying();
bouncer.update();
int keyingState=bouncer.read();
if(keyingState==LOW){
digitalWrite(ledPin,HIGH);
TxRxState='T';
displayKeying();
}
else{
digitalWrite(ledPin,LOW);
TxRxState='R';
displayKeying();
}
if (digitalRead (dialStep10Pin) ==LOW){
if (digitalRead (dialStep10Pin) ==LOW && digitalRead (dialStep1000Pin)==LOW) {
FdataZoubun=20000; //20kHz
} else {
FdataZoubun=10;
}
} else if (digitalRead (dialStep1000Pin) ==LOW) {
FdataZoubun=1000;
} else {
FdataZoubun=100;
}
rotating = true; // reset the debouncer
if (encoderPos >lastReportedPos ) { //
Serial.println(Fdata+FdataZoubun, DEC);
Serial.println( encoderPos, DEC);
Fdata= Fdata+FdataZoubun;
displayEncoder();
lastReportedPos = encoderPos;
}
if (encoderPos < lastReportedPos) { //
Serial.println(Fdata-FdataZoubun, DEC);
Serial.println( encoderPos, DEC);
Fdata= Fdata-FdataZoubun;
displayEncoder();
lastReportedPos = encoderPos;
}
}
//Subroutine // Interrupt on A changing state
void doEncoderA(){
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done
// Test transition, did things really change?
if( digitalRead(encoderPinA) != A_set ) { // debounce once more
A_set = !A_set; //! not hitei
// adjust counter - if A leads B
if ( A_set && !B_set )
encoderPos -= 1;
rotating = false; // no more debouncing until loop() hits again
}
}
//Subroutine // Interrupt on B changing state, same as A above
void doEncoderB(){
//debounce
if ( rotating ) delay (1);
//Test transition, did things really change?
if( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// adjust counter + 1 if B leads A
if( B_set && !A_set )
encoderPos += 1;
rotating = false;
}
}
//Subroutine display
void displayEncoder(){
lcd.home();
String s =String(Fdata) ;
// String s =String(Fdata+FdataZoubun*encoderPos) ;
lcd.print("FREQ: ");
lcd.print(s.charAt(0));
lcd.print(s.substring(1, 4));
lcd.print(".");
lcd.print(s.substring(4,6));
lcd.print("kHz");
lcd.setCursor(1,1);
lcd.print("* RIT:");
lcd.setCursor(13,1);
lcd.print("kHz");
}
//Subroutine
void displayKeying(){
lcd.setCursor(0,1);
lcd.print(TxRxState);
}
/*
http://www.arduino.cc/playground/Main/RotaryEncoders#Example1
*/
/*
Another Interrupt Library THAT REALLY WORKS (the Encoder
interrupts the processor and
debounces like there is no tomorrow).
by rafbuff
*/
/* interrupt routine for Rotary Encoders
tested with Noble RE0124PVB 17.7FINB-24 http://www.nobleusa.com/pdf/xre.pdf - available at pollin.de
and a few others, seems pretty universal
The average rotary encoder has three pins, seen from front: A C B
Clockwise rotation A(on)->B(on)->A(off)->B(off)
CounterCW rotation B(on)->A(on)->B(off)->A(off)
and may be a push switch with another two pins, pulled low at pin 8 in this case
raf@synapps.de 20120107
*/
0 件のコメント:
コメントを投稿