Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Many UI fixes #17

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
# ubitxv6

uBitx v6.3.1 Arduino sketch

IMPORTANT: It will compile only if you place this in the Arduino's own sketch directory! This is because of the restricted places that the Arduino searches for it's include files (the headers).

- This is refactored to remove dependencies on any library except the standard Arduino libraries of SPI, I2C, EEPROM, etc.
- This works with ILI9341 display controller. The pins used by the TFT display are the same as that of the 16x2 LCD display of the previous versions.
- As the files are now split into .cpp files, the nano gui, morse reader, etc. can be reused in other projects as well

This is released under GPL v3 license.

## This sketch now includes AB1GO's fixes:

- Immediate change when pressing USB / LSB buttons
- Better automatic USB / LSB switching and corresponding display update
- Correct display of frequencies below 1 MHz
- Fix crashing bug when entering menu (due to uninitialized variable)
- Tuning knob improvement: only register detents, not half-way points
- Tuning knob improvement: Improve tuning speed and display update rate. This was almost all there with the interrupt driven encoder code, but needed some final cleanup to get it to be really smooth.
- Tuning knob improvement: Rework knob "momentum" code: now the tuning jumps at fast rate if you have been turning the knob fast for a while.
- Fix some text alignment issues: buttons were being erased
- Fix some focus related issues: now selected VFO is indicated by white text, and white outline only means focus. So now when you press tuning button you get immediate feedback.
- Put project into folder with same name as sketch so that Arduino IDE is happy

## Arduino IDE hints

Install CH340 serial port driver on your operating system if COM port /
serial port does not show up when you plug uBitx v6 into your computer.

Use "Arduino Duemilanove or Diecimila" instead of "Arduino Nano" as the
board type if you get errors when trying to upload. Some low cost Arduino
Nano clones don't match real Nanos and this is a work-around.
71 changes: 34 additions & 37 deletions encoder.cpp → ubitx_v6.1_code/encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

//Normal encoder state
uint8_t prev_enc = 0;
int8_t enc_count = 0;
int16_t enc_count = 0;

#define DECAY_RATE 10
#define MAX_SLAM 40
#define FAST_THRESH 30
#define FAST_STEP 20

//Momentum encoder state
int16_t enc_count_periodic = 0;
int8_t momentum[3] = {0};
int go_fast;
static const uint16_t CALLBACK_PERIOD_MS = 200;
static const uint8_t MOMENTUM_MULTIPLIER = 1;

Expand Down Expand Up @@ -37,17 +41,25 @@ ISR (PCINT1_vect)
(prev_enc == 3 && cur_enc == 1) ||
(prev_enc == 1 && cur_enc == 0))
{
enc_count -= 1;
enc_count_periodic -= 1;
if (go_fast >= FAST_THRESH)
enc_count -= FAST_STEP;
else
enc_count -= 1;
if (go_fast != MAX_SLAM)
++go_fast;
}
//these transitions point to the enccoder being rotated clockwise
else if ((prev_enc == 0 && cur_enc == 1) ||
(prev_enc == 1 && cur_enc == 3) ||
(prev_enc == 3 && cur_enc == 2) ||
(prev_enc == 2 && cur_enc == 0))
{
enc_count += 1;
enc_count_periodic += 1;
if (go_fast >= FAST_THRESH)
enc_count += FAST_STEP;
else
enc_count += 1;
if (go_fast != MAX_SLAM)
++go_fast;
}
else {
// A change to two states, we can't tell whether it was forward or backward, so we skip it.
Expand Down Expand Up @@ -87,37 +99,22 @@ void enc_setup(void)

ISR(TIMER1_COMPA_vect)
{
momentum[2] = momentum[1];
momentum[1] = momentum[0];
momentum[0] = enc_count_periodic;
enc_count_periodic = 0;
if (go_fast > DECAY_RATE)
go_fast -= DECAY_RATE;
else
go_fast = 0;
}

int8_t min_momentum_mag()
{
int8_t min_mag = 127;
for(uint8_t i = 0; i < sizeof(momentum)/sizeof(momentum[0]); ++i){
int8_t mag = abs(momentum[i]);
if(mag < min_mag){
min_mag = mag;
}
}
return min_mag;
}
// Number of ticks knob was moved since last time this was called
// ...this way we don't miss any
// We divide enc_count by 2 to ignore the half-ticks, when knob is between detents

int enc_read(void) {
if(0 != enc_count){
int16_t ret = enc_count;
int8_t s = (enc_count < 0) ? -1 : 1;
int8_t momentum_mag = min_momentum_mag();
if(momentum_mag >= 20){
ret += s*40;
}
else if(momentum_mag >= 5){
ret += s*(20 + momentum_mag)/(20 - momentum_mag);
}
enc_count = 0;
return ret;
}
return 0;
int8_t prev_mod_count;

int enc_read(void)
{
int8_t mod_count = enc_count / 2;
int8_t rtn = mod_count - prev_mod_count;
prev_mod_count = mod_count;
return rtn;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 6 additions & 3 deletions nano_gui.cpp → ubitx_v6.1_code/nano_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,12 +457,15 @@ void displayRawText(char *text, int x1, int y1, int color, int background){
}

// The generic routine to display one line on the LCD
void displayText(char *text, int x1, int y1, int w, int h, int color, int background, int border) {
void displayText(char *text, int x1, int y1, int w, int h, int color, int background, int border, int just) {

displayFillrect(x1, y1, w ,h, background);
displayRect(x1, y1, w ,h, border);

x1 += (w - displayTextExtent(text))/2;
if (just == CENTERED)
x1 += (w - displayTextExtent(text))/2;
else
x1 += 2;
y1 += (h - TEXT_LINE_HEIGHT)/2;
while(*text){
char c = *text++;
Expand All @@ -487,7 +490,7 @@ void setupTouch(){
int x1, y1, x2, y2, x3, y3, x4, y4;

displayClear(DISPLAY_BLACK);
displayText("Click on the cross", 20,100, 200, 50, DISPLAY_WHITE, DISPLAY_BLACK, DISPLAY_BLACK);
displayText("Click on the cross", 20,100, 200, 50, DISPLAY_WHITE, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);

// TOP-LEFT
displayHline(10,20,20,DISPLAY_WHITE);
Expand Down
5 changes: 4 additions & 1 deletion nano_gui.h → ubitx_v6.1_code/nano_gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void displayFillrect(unsigned int x,unsigned int y,unsigned int w,unsigned int h
void displayChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg);
int displayTextExtent(char *text);
void displayRawText(char *text, int x1, int y1, int color, int background);
void displayText(char *text, int x1, int y1, int w, int h, int color, int background, int border);
void displayText(char *text, int x1, int y1, int w, int h, int color, int background, int border, int just);

/* touch functions */
boolean readTouch();
Expand Down Expand Up @@ -53,6 +53,9 @@ void scaleTouch(struct Point *p);
#define BUTTON_CHECK
#define BUTTON_SPINNER

#define CENTERED 1
#define LEFT 0

/// Font data stored PER GLYPH
typedef struct {
uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap
Expand Down
99 changes: 46 additions & 53 deletions setup.cpp → ubitx_v6.1_code/setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void setupFreq(){
//displayRawText("Rotate to zerobeat", 20, 120, DISPLAY_CYAN, DISPLAY_NAVY);

ltoa(calibration, b, 10);
displayText(b, 100, 140, 100, 26, DISPLAY_CYAN, DISPLAY_NAVY, DISPLAY_WHITE);
displayText(b, 100, 140, 100, 26, DISPLAY_CYAN, DISPLAY_NAVY, DISPLAY_WHITE, CENTERED);
}

EEPROM.put(MASTER_CAL, calibration);
Expand Down Expand Up @@ -131,7 +131,7 @@ void setupCwDelay(){

itoa(10 * (int)cwDelayTime, b, 10);
strcat(b, " msec");
displayText(b, 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText(b, 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);

while (!btnDown()){
knob = enc_read();
Expand All @@ -145,7 +145,7 @@ void setupCwDelay(){

itoa(10 * (int)cwDelayTime, b, 10);
strcat(b, " msec");
displayText(b, 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText(b, 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);

}

Expand All @@ -164,11 +164,11 @@ void setupKeyer(){
displayDialog("Set CW Keyer", "Press tune to Save");

if (!Iambic_Key)
displayText("< Hand Key >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText("< Hand Key >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);
else if (keyerControl & IAMBICB)
displayText("< Iambic A >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText("< Iambic A >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);
else
displayText("< Iambic B >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText("< Iambic B >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);

if (!Iambic_Key)
tmp_key = 0; //hand key
Expand All @@ -192,11 +192,11 @@ void setupKeyer(){
tmp_key = 0;

if (tmp_key == 0)
displayText("< Hand Key >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText("< Hand Key >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);
else if (tmp_key == 1)
displayText("< Iambic A >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText("< Iambic A >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);
else if (tmp_key == 2)
displayText("< Iambic B >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
displayText("< Iambic B >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK, CENTERED);
}

active_delay(500);
Expand All @@ -217,9 +217,9 @@ void setupKeyer(){
}

void drawSetupMenu(){
displayClear(DISPLAY_BLACK);
displayClear(DISPLAY_NAVY);

displayText("Setup", 10, 10, 300, 35, DISPLAY_WHITE, DISPLAY_NAVY, DISPLAY_WHITE);
displayText("Setup", 10, 10, 300, 35, DISPLAY_WHITE, DISPLAY_NAVY, DISPLAY_WHITE, CENTERED);
displayRect(10,10,300,220, DISPLAY_WHITE);

displayRawText("Set Freq...", 30, 50, DISPLAY_WHITE, DISPLAY_NAVY);
Expand All @@ -231,72 +231,65 @@ void drawSetupMenu(){
}

static int prevPuck = -1;

void movePuck(int i){
if (prevPuck >= 0)
displayRect(15, 49 + (prevPuck * 30), 290, 25, DISPLAY_NAVY);
displayRect(15, 49 + (i * 30), 290, 25, DISPLAY_WHITE);
prevPuck = i;

}

void doSetup2(){
int select=0, i,btnState;

drawSetupMenu();
movePuck(select);
int select=0;

//wait for the button to be raised up
while(btnDown())
active_delay(50);
active_delay(50); //debounce

menuOn = 2;

while (menuOn){
i = enc_read();

if (i > 0){
if (select + i < 60)
select += i;
movePuck(select/10);
}
if (i < 0 && select - i >= 0){
select += i; //caught ya, i is already -ve here, so you add it
movePuck(select/10);
}
while (menuOn)
{
drawSetupMenu();
movePuck(select);

if (!btnDown()){
//wait for the button to be raised up
wait_released();

// Move selection, wait for press
for (;;)
{
int i = enc_read();

if (i > 0){
if (select + i < 6)
select += i;
movePuck(select);
}
if (i < 0 && select + i >= 0){
select += i; //caught ya, i is already -ve here, so you add it
movePuck(select);
}

if (btnDown())
break;
active_delay(50);
continue;
}

//wait for the touch to lift off and debounce
while(btnDown()){
active_delay(50);
}
active_delay(300);
wait_released();

if (select < 10)
setupFreq();
else if (select < 20 )
if (select < 1)
setupFreq(); // Exits back to menu
else if (select < 2 )
setupBFO();
else if (select < 30 )
else if (select < 3 )
setupCwDelay();
else if (select < 40)
else if (select < 4)
setupKeyer();
else if (select < 50)
setupTouch();
else if (select < 5)
setupTouch(); // Exits back to menu
else
break; //exit setup was chosen
//setupExit();
//redraw
drawSetupMenu();
}

//debounce the button
while(btnDown())
active_delay(50);
active_delay(50);
wait_released();

checkCAT();
guiUpdate();
Expand Down
10 changes: 9 additions & 1 deletion ubitx.h → ubitx_v6.1_code/ubitx.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
*/

extern const char version_string[];

#define ENC_A (A0) // Tuning encoder interface
#define ENC_B (A1) // Tuning encoder interface
#define FBUTTON (A2) // Tuning encoder interface
Expand Down Expand Up @@ -61,7 +63,6 @@ it uses an ILI9341 display controller and an XPT2046 touch controller.
* the serial port as we can easily run out of buffer space. This is done in the serial_in_count variable.
*/
extern char c[30], b[30];
extern char printBuff[2][20]; //mirrors what is showing on the two lines of the display
extern int count; //to generally count ticks, loops, etc

/**
Expand Down Expand Up @@ -185,6 +186,7 @@ void cwKeyer(void);
void switchVFO(int vfoSelect);

int enc_read(void); // returns the number of ticks in a short interval, +ve in clockwise, -ve in anti-clockwise
void modify_frequency(unsigned long new_freq, bool save_vfo, bool force_usb);
int btnDown(); //returns true if the encoder button is pressed

/* these functions are called universally to update the display */
Expand Down Expand Up @@ -220,3 +222,9 @@ void checkTouch(); //does the commands with a touch on the buttons
void si5351bx_setfreq(uint8_t clknum, uint32_t fout);
void initOscillators();
void si5351_set_calibration(int32_t cal); //calibration is a small value that is nudged to make up for the inaccuracies of the reference 25 MHz crystal frequency

/* Wait for button to be released */
void wait_released();

void updateUSB();
void setUSB(char wantUSB);
Loading