7/29/2018 ~ Arduino Code for LCD to OLED replacement http://www.n6qw.com
Look inside the Purple framed text for the link to the code. You will also have to have the included files -- see the notes in the sketch and as mentioned below. If you are unsure on how to do this … don't try it.
73's
Pete N6QW
Secrets Revealed: How to Add a Tune Tone and CW Identifier to your Homebrew Rig. 7/27/2018
Disclaimer: I am not a software programmer nor do I profess to have those skills but I am a person who likes to tinker with things. For several years now I have had a Pulsed Tone TUNE capability with my rigs. I developed the code myself and even figured out how to change the screens to show you are in TUNE. For those who do software on a daily basis --you probably snicker (a lot) at my code. Frankly that is unimportant in that what I developed works!
So today I said to myself "Pete why can't you add a CW identifier following the pulsed tone?" So I did and it works! How this works is that I first put the rig in transmit using the MOX button and then I depress the TUNE momentary push button.
First and all important you need to have a Tone Library in the library section of your main Arduino directory--one that will work with Arduino IDE 1.8.5 -- there is more than one.
There are three lines that must be added initially which state
#include "Tone.h"
#define TONE_PIN 6
#define TONE_PIN 6
#define NOTE_B5 988
Importantly the Tone.h is an included file in the folder and in the sketch that is why it has the quotation marks" ". Next is to identify the output Tone Pin which is Digital Pin 6 and finally Identify the actual tone you want which I chose B5 which is the closest to 1 KHz.
Then we need to identify button states since this is a momentary push button which initiates the Tune process.
int buttonState = 0;
int lastButtonState = 0;
We also need to identify the actual Arduino pin that take the Push Button Input to start the Tune Tone process.
const int SW1 = A2; // provides the TUNE function
Thus we are using Analog Pin A2 to take that input and in the void setup we do that
pinMode(SW1, INPUT); // Tune function
digitalWrite(SW1, HIGH);
digitalWrite(SW1, HIGH);
Thus if we put A2 to ground even momentarily it will start the TUNE Sequence.
Now we need to add some subroutines so that instead of writing out the dots and dashes by each element that makes each timed element for a dot space, dash space we can simply call up a dot with all of the proper timing for turning on the tone and turning off the tone. Ditto for the dash whose timing is 3 times as long. So now with the subroutines we can just call up a dash or call up a dot and it will happen automatically. You can even extend this further to writing characters so that you could call up the letters N 6 Q W and it would send those characters. For those who are subscribers to QRP Quarterly you can find a series of article by myself and Ben AI6YR called the CW Sender -- just following our articles!
Now the delays are set for some slow speed CW which means the newly minted extras who only have to do 5 WPM can read this. Actually it would have been smarter to set up values like: int X = 300; and int Y = 100; and in the delays show it as delay(X); or delay(Y);. This way if you wanted to change the speed you would only need to change two values for X and Y and all else would follow.
//**** Generating CW *********
void dash(){
tone(6, NOTE_B5);
delay(300);
noTone(6);
delay(100);
}
delay(300);
noTone(6);
delay(100);
}
void dot(){
tone(6, NOTE_B5);
delay(100);
noTone(6);
delay(100);
}
delay(100);
noTone(6);
delay(100);
}
So now we have the dots and dashes and we have the Input pin (A2) and the Output pin ((6) and now for the other subroutine that during the polling of the loop asks have you hit the TUNE button?
void loop() {
SplashScreen();
RunOnce = 0;
checkMode();
}
So when the loop sees the activation of the Tune Push Button it shifts to the checkMode() subroutine.
//*********************** See if we are in Tune ***********************************
void checkMode(){
buttonState = digitalRead(SW1); // creates a 10 second tuning pulse train 50% duty cycle and makes TUNE appear on the screen
if(buttonState != lastButtonState){
if(buttonState == LOW){
useVFOA(); // Tells what VFO to use for Tune and starts the pulsed tone sequence
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(10,35); //We are displaying the received Freq of VFO A
display.println(rx1 - bfo);
display.setCursor(1,50);
display.print("TUNE");
display.display();
delay(12);
for(int i = 0; i < 100; i++) {
tone(6, NOTE_B5);
delay(50); // 50 on and 50 off 50% duty cycle
noTone(6);
delay(50);
void checkMode(){
buttonState = digitalRead(SW1); // creates a 10 second tuning pulse train 50% duty cycle and makes TUNE appear on the screen
if(buttonState != lastButtonState){
if(buttonState == LOW){
useVFOA(); // Tells what VFO to use for Tune and starts the pulsed tone sequence
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(10,35); //We are displaying the received Freq of VFO A
display.println(rx1 - bfo);
display.setCursor(1,50);
display.print("TUNE");
display.display();
delay(12);
for(int i = 0; i < 100; i++) {
tone(6, NOTE_B5);
delay(50); // 50 on and 50 off 50% duty cycle
noTone(6);
delay(50);
} // This completes the end of the pulsed tone sequence
// The following code sends my call sign at slow speed with a 988 Hz tone. Note
we are simply calling up dots and dashes. We could take this further to define
characters and then this would just say send -- N6QW
delay(100); // de N6QW in CW
delay(100); // de N6QW in CW
dash(); //D
dot();
dot();
delay(300); //E
dot();
dot();
dot();
delay(300); //E
dot();
delay(400); //A little longer delay between "de" and N6QW
dash(); //N
dot();
delay(300);
dash(); //6
dot();
dot();
dot();
dot();
delay(300);
dash(); //Q
dash();
dot();
dash();
delay(300);
dot(); //W
dash();
dash();
delay(300);
}
else{
//the else resets the screen and puts the rig back into normal operation
display.setTextSize(2); // This prints a Black TUNE over the RED TUNE and makes it disappear from the scereen
display.setTextColor(BLACK);
display.setCursor(1, 50);
display.print("TUNE");
noTone(6);
}
delay(50);
}
That is it and you too can add a CW identifier to your own homebrew rig. Keep on tinkering.!
dot();
delay(300);
dash(); //6
dot();
dot();
dot();
dot();
delay(300);
dash(); //Q
dash();
dot();
dash();
delay(300);
dot(); //W
dash();
dash();
delay(300);
}
else{
//the else resets the screen and puts the rig back into normal operation
display.setTextSize(2); // This prints a Black TUNE over the RED TUNE and makes it disappear from the scereen
display.setTextColor(BLACK);
display.setCursor(1, 50);
display.print("TUNE");
noTone(6);
}
delay(50);
}
That is it and you too can add a CW identifier to your own homebrew rig. Keep on tinkering.!
Pete N6QW
At Times a New Solution > A Fix!
For those not used to mathematical notation the title reads that a new solution at times is greater than fixing the old problem. So it is with a recent experience of mine and I offer this to those who perhaps have had similar problems.
Take the Junk Box Rig which was made (in 2017) almost entirely out of boards lying in my junk box. Often I will build two versions of a circuit module with the first being a prototype and the second the finished unit that benefits from the experimenting with the prototype. Or it may be a case of build the first one large and then the second can be shrunk down in size once the prototype is working satisfactorily. Or as in this case some boards were pulled out of working transceivers as the project was no longer used.
Even though they were junk box boards I did attempt to make it nice looking including a cool blue LCD display. So there you go --Juliyellow background with a blue display. The original Arduino code was a lift from AD7C.
For a long time I had resisted upgrading my Arduino IDE to the latest version because I already knew that the older LCD libraries will not play with the latest IDE's. You can even find some fixes from giants like Adafruit Industries on the internet. Most of my earlier work was done in Arduino 1.0.5 and the LCD Libraries I had loved it.
Well several days ago I wanted to make some changes to this rig and attempted to use the fixed libraries with IDE 1.8.5. Well it will display but not all gets displayed. About 15 minutes worth of frustration was my gag level so I said "Lets rip that LCD out of there and use an OLED"! The code (not AD7C) was extensively modified by me as used on other N6QW projects.
This has some additional benefits as I recently learned how to make two vfos on the Arduino and I also added some features to the rig that would have otherwise compromised the clean looking front panel.
So six hours worth of work created new code, milled out a new front sub panel, added some wiring changes/controls and then final checkout.
The two toggle switches to left of the display are for MOX (for you youngsters MOX = Manually Operated Transmit --you won't find that on your ICOM 7300) and the toggle next to the display selects either VFO A or VFO B. The RED pushbutton engages the TUNE function. When this happen the display reads the transmitted frequency and the word TUNE appears on the screen.
In normal Transmit (hitting the PTT or the MOX) right below VFO B appears the transmitted frequency. While many of those functions could be done with a 16X2 LCD -- you have a lot more real estate in a small size to display simultaneous information.
ZL2CTM, Charlie Morris uses a similar display to show a "spectrum" of signals. but you would need something like a Teensy 3.5 versus the Pro-Mini that is being used for this application. I also took this opportunity to make some changes to the Arduino / Si5351 board.
There are some interesting aspects to this rig. The IF Module uses a 3.180 MHz Crystal Filter out of an early Yaseu FT-101 and the bilateral amplifiers are the Plessey circuit out of EMRFD. A cousin to this radio a 60M rig has many similar circuits only the Plessey amps are surface mount. The microphone amplifier is a germanium PNP transistor --just wanted to prove I could design PNP microphone amplifier circuits.
The driver stage is also out of EMRFD but I use a 2N2222 TO-18 (so you can add a heat sink) and a BD139 in lieu of the expensive 2N3866. Works for me. Here is an interesting aside. The driver stage was built new BUT used a blank board that was originally the audio amplifier stage in my KWM4 (NE5534 and LM380). I realized that there was a circuit layout error so simply cut a new board after fixing the error but did Keep the blank board in the junk box. With a bit of juggling that audio amp board became the Driver Board.
The audio amplifier is the healthy NE5534 driving an LM380 (This has the proper board layout). Also an innovation: the bottom plate is a large piece of PC board which has been stiffened with aluminum side rails. There was a reason for this as the bottom plate is the heat sink for the IRF510 that is fitted with an isolating pad and simply screwed to the bottom plate. Copper is better as a heat spreader and you can verify that with your friendly EMRFD or uBitx illuminati.
Oh, the Band Pass Filter was originally used in the LBS transceiver project. So almost like a wedding something old (old boards), something new (new driver stage built on an old board), something borrowed (LBS BPF), something blue (the PNP audio transistor and the original LCD).
So a problem has turned into a better solution with greater capability. Throw out those LCD's and get an OLED or really go uptown with the Color TFT. For those who wonder --there is no OLED noise in the receiver! I am getting to believe OLED noise is like the phase noise of the Si5351 that was touted before it became an old wives tale.
Oh, not done yet --the sub-panel will be painted black today. That should make the OLED sort of disappear into the background. Done --- See below.
Pete N6QW