Add 20x04LCD and S.Meter

This commit is contained in:
phdlee 2018-04-16 23:56:32 +09:00
parent d721816039
commit 0e245fc488
9 changed files with 417 additions and 293 deletions

View File

@ -24,10 +24,10 @@
//Depending on the type of LCD mounted on the uBITX, uncomment one of the options below.
//You must select only one.
//#define UBITX_DISPLAY_LCD1602P //LCD mounted on unmodified uBITX
#define UBITX_DISPLAY_LCD1602P //LCD mounted on unmodified uBITX
//#define UBITX_DISPLAY_LCD1602I //I2C type 16 x 02 LCD
//#define UBITX_DISPLAY_LCD1602I_CUST //I2C type 16 x 02 Custom Tiny Library
#define UBITX_DISPLAY_LCD2004P //24 x 04 LCD
//#define UBITX_DISPLAY_LCD2004P //24 x 04 LCD
//#define UBITX_DISPLAY_LCD2004I //I2C type 24 x 04 LCD
//==============================================================================
@ -95,6 +95,7 @@
extern unsigned long frequency;
extern byte WsprMSGCount;
extern byte sMeterLevels[9];
extern void printLine1(const char *c);
extern void printLine2(const char *c);

View File

@ -1,11 +1,19 @@
//Firmware Version
#define FIRMWARE_VERSION_INFO F("CEC v1.071")
//+ : This symbol identifies the firmware.
// It was originally called 'CEC V1.072' but it is too long to waste the LCD window.
// I do not want to make this Firmware users's uBITX messy with my callsign.
// Putting one alphabet in front of 'v' has a different meaning.
// So I put + in the sense that it was improved one by one based on Original Firmware.
// This firmware has been gradually changed based on the original firmware created by Farhan, Jack, Jerry and others.
#define FIRMWARE_VERSION_INFO F("+v1.072")
#define FIRMWARE_VERSION_NUM 0x02 //1st Complete Project : 1 (Version 1.061), 2st Project : 2
/**
Cat Suppoort uBITX CEC Version
This firmware has been gradually changed based on the original firmware created by Farhan, Jack, Jerry and others.
Most features(TX, Frequency Range, Ham Band, TX Control, CW delay, start Delay... more) have been added by KD8CEC.
However, the license rules are subject to the original source rules.
My wish is to keep the original author's Comment as long as the meaning does not change much, even if the code looks a bit long.
Ian KD8CEC
Original source comment -------------------------------------------------------------
@ -172,6 +180,7 @@ unsigned long SDR_Center_Freq; //
unsigned long beforeIdle_ProcessTime = 0; //for check Idle time
byte line2DisplayStatus = 0; //0:Clear, 1 : menu, 1: DisplayFrom Idle,
char lcdMeter[17];
byte sMeterLevels[9];
byte isIFShift = 0; //1 = ifShift, 2 extend
int ifShiftValue = 0; //
@ -183,8 +192,8 @@ int ifShiftValue = 0; //
//Ham Band
#define MAX_LIMIT_RANGE 10 //because limited eeprom size
byte useHamBandCount = 0; //0 use full range frequency
byte tuneTXType = 0; //0 : use full range, 1 : just Change Dial speed, 2 : just ham band change, but can general band by tune, 3 : only ham band (just support 0, 2 (0.26 version))
byte useHamBandCount = 0; //0 use full range frequency
byte tuneTXType = 0; //0 : use full range, 1 : just Change Dial speed, 2 : just ham band change, but can general band by tune, 3 : only ham band (just support 0, 2 (0.26 version))
//100 : use full range but not TX on general band, 101 : just change dial speed but.. 2 : jut... but.. 3 : only ham band (just support 100, 102 (0.26 version))
unsigned int hamBandRange[MAX_LIMIT_RANGE][2]; // = //Khz because reduce use memory
@ -819,6 +828,10 @@ void initSettings(){
EEPROM.get(DISPLAY_OPTION1, displayOption1);
EEPROM.get(DISPLAY_OPTION2, displayOption2);
for (byte i = 0; i < 8; i++) {
sMeterLevels[i + 1] = EEPROM.read(S_METER_LEVELS + i);
}
//User callsign information
if (EEPROM.read(USER_CALLSIGN_KEY) == 0x59)
userCallsignLength = EEPROM.read(USER_CALLSIGN_LEN); //MAXIMUM 18 LENGTH

View File

@ -50,6 +50,9 @@
// 256 ~ 1023 (EEProm Section #1)
// 255 ~ 101 (EEProm Section #2)
//==============================================================================
#define S_METER_LEVELS 230 //LEVEL0 ~ LEVEL7
#define ADVANCED_FREQ_OPTION1 240 //Bit0: use IFTune_Value, Bit1 : use Stored enabled SDR Mode, Bit2 : dynamic sdr frequency
#define IF1_CAL 241
#define ENABLE_SDR 242

View File

@ -409,13 +409,13 @@ void updateLine2Buffer(char displayType)
//EXAMPLE #1
if ((displayOption1 & 0x04) == 0x00) //none scroll display
line2Buffer[6] = 'k';
line2Buffer[6] = 'M';
else
{
//example #2
if (freqScrollPosition++ > 18) //none scroll display time
{
line2Buffer[6] = 'k';
line2Buffer[6] = 'M';
if (freqScrollPosition > 25)
freqScrollPosition = -1;
}

View File

@ -570,13 +570,13 @@ void updateLine2Buffer(char displayType)
//EXAMPLE #1
if ((displayOption1 & 0x04) == 0x00) //none scroll display
line2Buffer[6] = 'k';
line2Buffer[6] = 'M';
else
{
//example #2
if (freqScrollPosition++ > 18) //none scroll display time
{
line2Buffer[6] = 'k';
line2Buffer[6] = 'M';
if (freqScrollPosition > 25)
freqScrollPosition = -1;
}

View File

@ -175,7 +175,8 @@ void LCD_CreateChar(uint8_t location, uint8_t charmap[])
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
*/
//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA
#define OPTION_SKINNYBARS
//========================================================================
//Begin of Display Base Routines (Init, printLine..)
@ -183,93 +184,12 @@ LiquidCrystal lcd(8,9,10,11,12,13);
char c[30], b[30];
char printBuff[2][17]; //mirrors what is showing on the two lines of the display
const PROGMEM uint8_t meters_bitmap[] = {
B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 , //custom 1
B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 , //custom 2
B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 , //custom 3
B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 , //custom 4
B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 , //custom 5
B01000, B11100, B01000, B00000, B10111, B10101, B10101, B10111 //custom 6
};
PGM_P p_metes_bitmap = reinterpret_cast<PGM_P>(meters_bitmap);
const PROGMEM uint8_t lock_bitmap[8] = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000};
PGM_P plock_bitmap = reinterpret_cast<PGM_P>(lock_bitmap);
// initializes the custom characters
// we start from char 1 as char 0 terminates the string!
void initMeter(){
uint8_t tmpbytes[8];
byte i;
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(plock_bitmap + i);
LCD_CreateChar(0, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i);
LCD_CreateChar(1, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 8);
LCD_CreateChar(2, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 16);
LCD_CreateChar(3, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 24);
LCD_CreateChar(4, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 32);
LCD_CreateChar(5, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 40);
LCD_CreateChar(6, tmpbytes);
}
void LCD_Init(void)
{
LCD1602_Init();
initMeter(); //for Meter Display
}
//by KD8CEC
//0 ~ 25 : 30 over : + 10
void drawMeter(int needle) {
//5Char + O over
int i;
for (i = 0; i < 5; i++) {
if (needle >= 5)
lcdMeter[i] = 5; //full
else if (needle > 0)
lcdMeter[i] = needle; //full
else //0
lcdMeter[i] = 0x20;
needle -= 5;
}
if (needle > 0)
lcdMeter[5] = 6;
else
lcdMeter[5] = 0x20;
}
// The generic routine to display one line on the LCD
void printLine(unsigned char linenmbr, const char *c) {
if ((displayOption1 & 0x01) == 0x01)
@ -534,13 +454,13 @@ void updateLine2Buffer(char displayType)
//EXAMPLE #1
if ((displayOption1 & 0x04) == 0x00) //none scroll display
line2Buffer[6] = 'k';
line2Buffer[6] = 'M';
else
{
//example #2
if (freqScrollPosition++ > 18) //none scroll display time
{
line2Buffer[6] = 'k';
line2Buffer[6] = 'M';
if (freqScrollPosition > 25)
freqScrollPosition = -1;
}
@ -625,7 +545,13 @@ void updateLine2Buffer(char displayType)
line2Buffer[13] = ' ';
//Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb
if (cwKeyType == 0)
if (sdrModeOn == 1)
{
line2Buffer[13] = 'S';
line2Buffer[14] = 'D';
line2Buffer[15] = 'R';
}
else if (cwKeyType == 0)
{
line2Buffer[14] = 'S';
line2Buffer[15] = 'T';
@ -648,20 +574,26 @@ void DisplayMeter(byte meterType, byte meterValue, char drawPosition)
{
if (meterType == 0 || meterType == 1 || meterType == 2)
{
drawMeter(meterValue); //call original source code
drawMeter(meterValue);
int lineNumber = 0;
if ((displayOption1 & 0x01) == 0x01)
lineNumber = 1;
LCD_SetCursor(drawPosition, lineNumber);
for (int i = 0; i < 6; i++) //meter 5 + +db 1 = 6
LCD_Write(lcdMeter[i]);
//for (int i = 0; i <26; i++) //meter 5 + +db 1 = 6
LCD_Write(lcdMeter[0]);
LCD_Write(lcdMeter[1]);
}
}
byte testValue = 0;
char checkCount = 0;
int currentSMeter = 0;
//byte sMeterLevels[] = {0, 1, 4, 10, 18, 35, 63, 91, 117}; //John's default Value (divide / 4)
byte scaledSMeter = 0;
void idle_process()
{
//space for user graphic display
@ -679,6 +611,7 @@ void idle_process()
line2DisplayStatus = 2;
checkCount = 0;
}
}
//EX for Meters
/*
@ -686,7 +619,29 @@ void idle_process()
if (testValue > 30)
testValue = 0;
*/
}
//S-Meter Display
if ((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0))
{
int newSMeter;
//VK2ETA S-Meter from MAX9814 TC pin / divide 4 by KD8CEC for reduce EEPromSize
newSMeter = analogRead(ANALOG_SMETER);
//Faster attack, Slower release
currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10) / 4;
scaledSMeter = 0;
for (byte s = 8; s >= 1; s--) {
if (currentSMeter > sMeterLevels[s]) {
scaledSMeter = s;
break;
}
}
DisplayMeter(0, scaledSMeter, 14);
} //end of S-Meter
}
}

View File

@ -22,7 +22,6 @@
**************************************************************************/
#ifdef UBITX_DISPLAY_LCD2004P
//========================================================================
//Begin of TinyLCD Library by KD8CEC
//========================================================================
@ -176,7 +175,8 @@ void LCD_CreateChar(uint8_t location, uint8_t charmap[])
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
*/
//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA
//#define OPTION_SKINNYBARS
//========================================================================
//Begin of Display Base Routines (Init, printLine..)
@ -184,92 +184,12 @@ LiquidCrystal lcd(8,9,10,11,12,13);
char c[30], b[30];
char printBuff[4][20]; //mirrors what is showing on the two lines of the display
const PROGMEM uint8_t meters_bitmap[] = {
B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 , //custom 1
B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 , //custom 2
B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 , //custom 3
B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 , //custom 4
B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 , //custom 5
B01000, B11100, B01000, B00000, B10111, B10101, B10101, B10111 //custom 6
};
PGM_P p_metes_bitmap = reinterpret_cast<PGM_P>(meters_bitmap);
const PROGMEM uint8_t lock_bitmap[8] = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000};
PGM_P plock_bitmap = reinterpret_cast<PGM_P>(lock_bitmap);
// initializes the custom characters
// we start from char 1 as char 0 terminates the string!
void initMeter(){
uint8_t tmpbytes[8];
byte i;
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(plock_bitmap + i);
LCD_CreateChar(0, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i);
LCD_CreateChar(1, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 8);
LCD_CreateChar(2, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 16);
LCD_CreateChar(3, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 24);
LCD_CreateChar(4, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 32);
LCD_CreateChar(5, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 40);
LCD_CreateChar(6, tmpbytes);
}
void LCD_Init(void)
{
LCD2004_Init();
initMeter(); //for Meter Display
}
//by KD8CEC
//0 ~ 25 : 30 over : + 10
void drawMeter(int needle) {
//5Char + O over
int i;
for (i = 0; i < 5; i++) {
if (needle >= 5)
lcdMeter[i] = 5; //full
else if (needle > 0)
lcdMeter[i] = needle; //full
else //0
lcdMeter[i] = 0x20;
needle -= 5;
}
if (needle > 0)
lcdMeter[5] = 6;
else
lcdMeter[5] = 0x20;
}
// The generic routine to display one line on the LCD
void printLine(unsigned char linenmbr, const char *c) {
@ -289,10 +209,10 @@ void printLine(unsigned char linenmbr, const char *c) {
void printLineF(char linenmbr, const __FlashStringHelper *c)
{
int i;
char tmpBuff[20];
char tmpBuff[21];
PGM_P p = reinterpret_cast<PGM_P>(c);
for (i = 0; i < 17; i++){
for (i = 0; i < 21; i++){
unsigned char fChar = pgm_read_byte(p++);
tmpBuff[i] = fChar;
if (fChar == 0)
@ -324,7 +244,7 @@ void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, b
// short cut to print to the first line
void printLine1(const char *c)
{
printLine(2,c);
printLine(1,c);
}
// short cut to print to the first line
void printLine2(const char *c)
@ -340,7 +260,7 @@ void clearLine2()
// short cut to print to the first line
void printLine1Clear(){
printLine(2,"");
printLine(1,"");
}
// short cut to print to the first line
void printLine2Clear(){
@ -368,6 +288,7 @@ void updateDisplay() {
// tks Jack Purdum W8TEE
// replaced fsprint commmands by str commands for code size reduction
// replace code for Frequency numbering error (alignment, point...) by KD8CEC
// i also Very TNX Purdum for good source code
int i;
unsigned long tmpFreq = frequency; //
@ -409,6 +330,7 @@ void updateDisplay() {
strcpy(c, "CWU ");
}
}
if (vfoActive == VFO_A) // VFO A is active
strcat(c, "A:");
else
@ -437,18 +359,18 @@ void updateDisplay() {
c[i] = ' ';
}
if (sdrModeOn)
strcat(c, " SDR");
else
strcat(c, " SPK");
//remarked by KD8CEC
//already RX/TX status display, and over index (20 x 4 LCD)
//if (inTx)
// strcat(c, " TX");
printLine(1, c);
c[16] = ' ';
c[17] = 'H';
c[18] = 'z';
printLine(2, c);
byte diplayVFOLine = 2;
byte diplayVFOLine = 1;
if ((displayOption1 & 0x01) == 0x01)
diplayVFOLine = 0;
@ -481,9 +403,7 @@ int freqScrollPosition = 0;
//warning : unused parameter 'displayType' <-- ignore, this is reserve
void updateLine2Buffer(char displayType)
{
//Second Frequency Display
unsigned long tmpFreq = 0;
if (ritOn)
{
strcpy(line2Buffer, "RitTX:");
@ -512,77 +432,61 @@ void updateLine2Buffer(char displayType)
line2Buffer[i] = ' ';
}
//return;
return;
} //end of ritOn display
else
//other VFO display
if (vfoActive == VFO_B)
{
//other VFO display
if (vfoActive == VFO_B)
{
tmpFreq = vfoA;
}
else
{
tmpFreq = vfoB;
}
// EXAMPLE 1 & 2
//U14.150.100
//display frequency
for (int i = 9; i >= 0; i--) {
if (tmpFreq > 0) {
if (i == 2 || i == 6) line2Buffer[i] = '.';
else {
line2Buffer[i] = tmpFreq % 10 + 0x30;
tmpFreq /= 10;
}
tmpFreq = vfoA;
}
else
{
tmpFreq = vfoB;
}
// EXAMPLE 1 & 2
//U14.150.100
//display frequency
for (int i = 9; i >= 0; i--) {
if (tmpFreq > 0) {
if (i == 2 || i == 6) line2Buffer[i] = '.';
else {
line2Buffer[i] = tmpFreq % 10 + 0x30;
tmpFreq /= 10;
}
else
line2Buffer[i] = ' ';
}
line2Buffer[6] = 'k';
line2Buffer[7] = ' ';
line2Buffer[8] = 'S';
//strcat(line2Buffer, "k SDR:");
if (sdrModeOn == 0)
{
line2Buffer[9] = 'P';
line2Buffer[10] = 'K';
}
else
{
line2Buffer[9] = 'D';
line2Buffer[10] = 'R';
}
line2Buffer[11] = ' ';
line2Buffer[i] = ' ';
}
memset(&line2Buffer[10], ' ', 10);
if (isIFShift)
{
line2Buffer[6] = 'M';
line2Buffer[7] = ' ';
//IFShift Offset Value
line2Buffer[12] = 'I';
line2Buffer[13] = 'F';
line2Buffer[8] = 'I';
line2Buffer[9] = 'F';
line2Buffer[14] = ifShiftValue >= 0 ? '+' : 0;
line2Buffer[15] = 0;
line2Buffer[16] = ' ';
//15, 16, 17, 18, 19
line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0;
line2Buffer[11] = 0;
line2Buffer[12] = ' ';
//11, 12, 13, 14, 15
memset(b, 0, sizeof(b));
ltoa(ifShiftValue, b, DEC);
strncat(line2Buffer, b, 5);
} //end of else
printLine(1, line2Buffer);
memset(line2Buffer, ' ', 20);
for (int i = 12; i < 17; i++)
{
if (line2Buffer[i] == 0)
line2Buffer[i] = ' ';
}
} // end of display IF
else // step & Key Type display
{
//if (isDirectCall != 0)
// return;
memset(&line2Buffer[8], ' ', 8);
//Step
long tmpStep = arTuneStep[tuneStepIndex -1];
@ -592,7 +496,7 @@ void updateLine2Buffer(char displayType)
isStepKhz = 2;
}
for (int i = 10; i >= 8 - isStepKhz; i--) {
for (int i = 14; i >= 12 - isStepKhz; i--) {
if (tmpStep > 0) {
line2Buffer[i + isStepKhz] = tmpStep % 10 + 0x30;
tmpStep /= 10;
@ -603,29 +507,30 @@ void updateLine2Buffer(char displayType)
if (isStepKhz == 0)
{
line2Buffer[11] = 'H';
line2Buffer[12] = 'z';
line2Buffer[15] = 'H';
line2Buffer[16] = 'z';
}
line2Buffer[13] = ' ';
//Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb
if (cwKeyType == 0)
{
line2Buffer[14] = 'S';
line2Buffer[15] = 'T';
}
else if (cwKeyType == 1)
{
line2Buffer[14] = 'I';
line2Buffer[15] = 'A';
}
else
{
line2Buffer[14] = 'I';
line2Buffer[15] = 'B';
}
}
line2Buffer[17] = ' ';
//Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb
if (cwKeyType == 0)
{
line2Buffer[18] = 'S';
line2Buffer[19] = 'T';
}
else if (cwKeyType == 1)
{
line2Buffer[18] = 'I';
line2Buffer[19] = 'A';
}
else
{
line2Buffer[18] = 'I';
line2Buffer[19] = 'B';
}
}
//meterType : 0 = S.Meter, 1 : P.Meter
@ -633,20 +538,93 @@ void DisplayMeter(byte meterType, byte meterValue, char drawPosition)
{
if (meterType == 0 || meterType == 1 || meterType == 2)
{
drawMeter(meterValue); //call original source code
int lineNumber = 0;
if ((displayOption1 & 0x01) == 0x01)
lineNumber = 1;
drawMeter(meterValue);
//int lineNumber = 0;
//if ((displayOption1 & 0x01) == 0x01)
//lineNumber = 1;
LCD_SetCursor(drawPosition, lineNumber);
LCD_SetCursor(drawPosition, 2);
LCD_Write('S');
LCD_Write(':');
for (int i = 0; i < 6; i++) //meter 5 + +db 1 = 6
LCD_Write(lcdMeter[i]);
}
}
//meterType : 0 = S.Meter, 1 = Forward Power Meter, 2 = SWR Meter
void DisplayMeter(byte meterType, int meterValue, char drawPosition)
{
#ifdef OPTION_SKINNYBARS //We want skinny meter bars with more text/numbers
memcpy(&(line2Buffer[drawPosition]), " ", 8); //Blank that section of 8 characters first
if (meterType == 0) { //SWR meter
drawMeter(meterValue); //Only 2 characters
line2Buffer[drawPosition] = 'S';
byte sValue = round((float)meterValue * 1.5); //6 bars available only to show 9 S values
sValue = sValue > 9 ? 9 : sValue; //Max S9
line2Buffer[drawPosition + 1] = '0' + sValue; //0 to 9
memcpy(&(line2Buffer[drawPosition + 2]), lcdMeter, 2); //Copy the S-Meter bars
//Add the +10, +20, etc...
if (meterValue > 6) {
//We are over S9
line2Buffer[drawPosition + 4] = '+';
line2Buffer[drawPosition + 5] = '0' + meterValue - 6; //1,2,3 etc...
line2Buffer[drawPosition + 6] = '0';
}
} else if (meterType == 1) { //Forward Power
drawMeter(round((float)meterValue / 40)); //4 watts per bar
//meterValue contains power value x 10 (one decimal point)
line2Buffer[drawPosition] = 'P';
meterValue = meterValue > 999 ? 999 : meterValue; //Limit to 99.9 watts!!!!
//Remove decimal value and divide by 10
meterValue = round((float)meterValue / 10);
if (meterValue < 10) {
line2Buffer[drawPosition + 1] = ' ';
line2Buffer[drawPosition + 2] = '0' + meterValue; //0 to 9
} else {
line2Buffer[drawPosition + 1] = '0' + meterValue / 10;
line2Buffer[drawPosition + 2] = '0' + (meterValue - ((meterValue / 10) * 10));
}
line2Buffer[drawPosition + 3] = 'W';
memcpy(&(line2Buffer[drawPosition + 4]), lcdMeter, 2); //Copy the S-Meter bars
} else { //SWR
drawMeter((int)(((float)meterValue - 21) / 100)); //no bar = < 1.2, then 1 bar = 1.2 to 2.2, 2 bars = 2.2 to 3.2, etc...
//meterValue contains SWR x 100 (two decimal point)
memcpy(&(line2Buffer[drawPosition]), "SWR", 3);
meterValue = round((float)meterValue / 10); //We now have swr x 10 (1 decimal point)
if (meterValue < 100) { //10 to 99, no decimal point
//Draw the decimal value
line2Buffer[drawPosition + 3] = '0' + meterValue / 10;
line2Buffer[drawPosition + 4] = '.';
line2Buffer[drawPosition + 5] = '0' + (meterValue - ((meterValue / 10) * 10));
} else {
memcpy(&(line2Buffer[drawPosition + 3]), "10+", 3); //over 10
}
memcpy(&(line2Buffer[drawPosition + 6]), lcdMeter, 2); //Copy the S-Meter bars
}
#else //We want fat bars, easy to read, with less text/numbers
//Serial.print("In displaymeter, meterValue: "); Serial.println(meterValue);
drawMeter(meterValue);
//Always line 2
char sym = 'S';
if (meterType == 1) sym = 'P';
else if (meterType == 2) sym = 'R'; //For SWR
line2Buffer[drawPosition] = sym;
memcpy(&(line2Buffer[drawPosition + 1]), lcdMeter, 7);
#endif //OPTION_SKINNYBARS
}
byte testValue = 0;
char checkCount = 0;
int currentSMeter = 0;
//int sMeterLevels[] = {0, 5, 17, 41, 74, 140, 255, 365, 470};
byte scaledSMeter = 0;
//execute interval : 0.25sec
void idle_process()
{
//space for user graphic display
@ -664,14 +642,45 @@ void idle_process()
line2DisplayStatus = 2;
checkCount = 0;
}
//EX for Meters
/*
DisplayMeter(0, testValue++, 7);
if (testValue > 30)
testValue = 0;
*/
}
//EX for Meters
/*
DisplayMeter(0, testValue++, 0);
if (testValue > 30)
testValue = 0;
*/
//Sample
//DisplayMeter(0, analogRead(ANALOG_SMETER) / 30, 0);
//DisplayMeter(0, analogRead(ANALOG_SMETER) / 10, 0);
//delay_background(10, 0);
//DisplayMeter(0, analogRead(ANALOG_SMETER), 0);
//if (testValue > 30)
// testValue = 0;
//S-Meter Display
if ((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0))
{
int newSMeter;
//VK2ETA S-Meter from MAX9814 TC pin
newSMeter = analogRead(ANALOG_SMETER);
//Faster attack, Slower release
currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10);
scaledSMeter = 0;
for (byte s = 8; s >= 1; s--) {
if (currentSMeter > sMeterLevels[s]) {
scaledSMeter = s;
break;
}
}
DisplayMeter(0, scaledSMeter, 0);
} //end of S-Meter
}
}
@ -689,8 +698,7 @@ void Display_AutoKeyTextIndex(byte textIndex)
void DisplayCallsign(byte callSignLength)
{
printLineFromEEPRom(3, 12, 0, userCallsignLength -1, 0); //eeprom to lcd use offset (USER_CALLSIGN_DAT)
//delay(500);
printLineFromEEPRom(3, 20 - userCallsignLength, 0, userCallsignLength -1, 0); //eeprom to lcd use offset (USER_CALLSIGN_DAT)
}
void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo)
@ -698,5 +706,4 @@ void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo)
printLineF(3, fwVersionInfo);
}
#endif

View File

@ -59,12 +59,10 @@ void menuBand(int btn){
btnPressCount = 0;
if (tuneTXType > 0) { //Just toggle 0 <-> 2, if tuneTXType is 100, 100 -> 0 -> 2
tuneTXType = 0;
//printLineF2(F("General mode"));
printLineF2(F("General"));
}
else {
tuneTXType = 2;
//printLineF2(F("Ham band mode"));
printLineF2(F("Ham band"));
}
delay_background(1000, 0);

View File

@ -6,6 +6,153 @@
* quickly cleared up.
*/
/*
const PROGMEM uint8_t meters_bitmap[] = {
B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 , //custom 1
B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 , //custom 2
B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 , //custom 3
B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 , //custom 4
B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 , //custom 5
B01000, B11100, B01000, B00000, B10111, B10101, B10101, B10111 //custom 6
};
*/
//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA
#ifdef OPTION_SKINNYBARS //We want skninny bars with more text
//VK2ETA modded "Skinny" bitmaps
const PROGMEM uint8_t meters_bitmap[] = {
// B01110, B10001, B10001, B11111, B11011, B11011, B11111, B00000, //Padlock Symbol, for merging. Not working, see below
B00000, B00000, B00000, B00000, B00000, B00000, B00000, B10000, //shortest bar
B00000, B00000, B00000, B00000, B00000, B00000, B00100, B10100,
B00000, B00000, B00000, B00000, B00000, B00001, B00101, B10101,
B00000, B00000, B00000, B00000, B10000, B10000, B10000, B10000,
B00000, B00000, B00000, B00100, B10100, B10100, B10100, B10100,
B00000, B00000, B00001, B00101, B10101, B10101, B10101, B10101, //tallest bar
B00000, B00010, B00111, B00010, B01000, B11100, B01000, B00000, // ++ sign
};
#else
//VK2ETA "Fat" bars, easy to read, with less text
const PROGMEM uint8_t meters_bitmap[] = {
// B01110, B10001, B10001, B11111, B11011, B11011, B11111, B00000, //Padlock Symbol, for merging. Not working, see below
B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111, //shortest bar
B00000, B00000, B00000, B00000, B00000, B00000, B11111, B11111,
B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111,
B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111,
B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111,
B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111, //tallest bar
B00000, B00010, B00111, B00010, B01000, B11100, B01000, B00000, // ++ sign
};
#endif //OPTION_SKINNYBARS
PGM_P p_metes_bitmap = reinterpret_cast<PGM_P>(meters_bitmap);
const PROGMEM uint8_t lock_bitmap[8] = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000};
PGM_P plock_bitmap = reinterpret_cast<PGM_P>(lock_bitmap);
// initializes the custom characters
// we start from char 1 as char 0 terminates the string!
void initMeter(){
uint8_t tmpbytes[8];
byte i;
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(plock_bitmap + i);
LCD_CreateChar(0, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i);
LCD_CreateChar(1, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 8);
LCD_CreateChar(2, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 16);
LCD_CreateChar(3, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 24);
LCD_CreateChar(4, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 32);
LCD_CreateChar(5, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 40);
LCD_CreateChar(6, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 48);
LCD_CreateChar(6, tmpbytes);
}
//by KD8CEC
//0 ~ 25 : 30 over : + 10
/*
void drawMeter(int needle) {
//5Char + O over
int i;
for (i = 0; i < 5; i++) {
if (needle >= 5)
lcdMeter[i] = 5; //full
else if (needle > 0)
lcdMeter[i] = needle; //full
else //0
lcdMeter[i] = 0x20;
needle -= 5;
}
if (needle > 0)
lcdMeter[5] = 6;
else
lcdMeter[5] = 0x20;
}
*/
//VK2ETA meter for S.Meter, power and SWR
void drawMeter(int needle)
{
#ifdef OPTION_SKINNYBARS
//Fill buffer with growing set of bars, up to needle value
for (int i = 0; i < 6; i++) {
if (needle > i)
lcdMeter[i / 3] = byte(i + 1); //Custom characters above
else if (i == 1 || i == 4) {
lcdMeter[i / 3] = 0x20; //blank
}
}
#else //Must be "fat" bars
//Fill buffer with growing set of bars, up to needle value
for (int i = 0; i < 6; i++) {
if (needle > i)
lcdMeter[i] = byte(i + 1); //Custom characters above
else
lcdMeter[i] = 0x20; //blank
}
if (needle > 7) {
lcdMeter[6] = byte(7); //Custom character "++"
} else if (needle > 6) {
lcdMeter[6] = 0x2B; //"+"
} else lcdMeter[6] = 0x20;
#endif //OPTION_FATBARS
}
char byteToChar(byte srcByte){
if (srcByte < 10)
return 0x30 + srcByte;