From c5d9b58fab6e4c3335d7b2975a3b537e8fb47fce Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Fri, 29 Nov 2024 12:58:58 -0800 Subject: [PATCH 01/14] had chatGPT create a readme.md for interfacing (even though the Android device does all the work) (#118) * had chatGPT create an readme.md This is an ICD that was generated by ChatGPT * Update readme.md Fixed detail on squelch, from being binary off and on (0-1) to be a range of 0-8 based on feedback from author --- .../kv4p_ht_esp32_wroom_32/readme.md | 296 ++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 microcontroller-src/kv4p_ht_esp32_wroom_32/readme.md diff --git a/microcontroller-src/kv4p_ht_esp32_wroom_32/readme.md b/microcontroller-src/kv4p_ht_esp32_wroom_32/readme.md new file mode 100644 index 00000000..16e58d9e --- /dev/null +++ b/microcontroller-src/kv4p_ht_esp32_wroom_32/readme.md @@ -0,0 +1,296 @@ +# KV4P-HT Serial Interface Documentation + +This document provides detailed instructions on how to interact with the KV4P-HT device via its serial console. It covers the serial connection setup, communication protocol, and command usage, including changing frequencies, controlling Push-To-Talk (PTT), and configuring filters. + +--- + +## Table of Contents + +1. [Serial Connection Setup](#1-serial-connection-setup) +2. [Communication Protocol](#2-communication-protocol) + - [2.1. Delimiter](#21-delimiter) + - [2.2. Command Structure](#22-command-structure) +3. [Commands](#3-commands) + - [3.1. COMMAND_PTT_DOWN (0x01)](#31-command_ptt_down-0x01) + - [3.2. COMMAND_PTT_UP (0x02)](#32-command_ptt_up-0x02) + - [3.3. COMMAND_TUNE_TO (0x03)](#33-command_tune_to-0x03) + - [3.4. COMMAND_FILTERS (0x04)](#34-command_filters-0x04) + - [3.5. COMMAND_STOP (0x05)](#35-command_stop-0x05) + - [3.6. COMMAND_GET_FIRMWARE_VER (0x06)](#36-command_get_firmware_ver-0x06) +4. [Examples](#4-examples) + - [4.1. Changing Frequencies](#41-changing-frequencies) + - [4.2. Starting Transmission](#42-starting-transmission) + - [4.3. Stopping Transmission](#43-stopping-transmission) + - [4.4. Configuring Filters](#44-configuring-filters) + - [4.5. Retrieving Firmware Version](#45-retrieving-firmware-version) +5. [Additional Notes](#5-additional-notes) + +--- + +## 1. Serial Connection Setup + +To interact with the KV4P-HT device, establish a serial connection using the following parameters: + +- **Port**: The serial port connected to the KV4P-HT device (e.g., `COM3`, `/dev/ttyUSB0`). +- **Baud Rate**: `921600` bits per second. +- **Data Bits**: `8` bits. +- **Parity**: `None`. +- **Stop Bits**: `1` bit. +- **Flow Control**: `None`. + +**Note**: Ensure that your serial communication software or terminal emulator supports the high baud rate of 921600 bps. + +--- + +## 2. Communication Protocol + +### 2.1. Delimiter + +All commands sent to the KV4P-HT device must be preceded by an 8-byte delimiter. This delimiter signals the start of a new command and helps synchronize communication. + +**Delimiter Byte Sequence**: + +```plaintext +0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 +``` + +### 2.2. Command Structure + +After the delimiter, send a single-byte command code followed by any required parameters. The general structure is as follows: + +```plaintext +[Delimiter][Command Code][Parameters (if any)] +``` + +- **Delimiter**: 8 bytes (as specified above). +- **Command Code**: 1 byte (see the list of commands below). +- **Parameters**: Varies by command. + +--- + +## 3. Commands + +Below is a list of commands supported by the KV4P-HT device, along with their descriptions and parameter requirements. + +### 3.1. COMMAND_PTT_DOWN (0x01) + +- **Description**: Initiates transmission mode. The device expects audio data to follow, which will be transmitted over the radio. +- **Parameters**: None. +- **Usage**: + - Send the delimiter. + - Send the command code `0x01`. + +### 3.2. COMMAND_PTT_UP (0x02) + +- **Description**: Stops transmission and returns the device to receive mode. +- **Parameters**: None. +- **Usage**: + - Send the delimiter. + - Send the command code `0x02`. + +### 3.3. COMMAND_TUNE_TO (0x03) + +- **Description**: Changes the transmit and receive frequencies, as well as the tone and squelch settings. +- **Parameters**: 19 bytes total. + - **Transmit Frequency**: 8 ASCII characters (e.g., `146.5200`). + - **Receive Frequency**: 8 ASCII characters. + - **Tone**: 2 ASCII characters representing an integer (e.g., `00` for none). + - **Squelch**: 1 ASCII character (`0` thru `8`). +- **Usage**: + - Send the delimiter. + - Send the command code `0x03`. + - Send the parameters concatenated as a string. + +**Parameter Details**: + +| Parameter | Length | Description | +|-----------------------|--------|------------------------------------------------------| +| Transmit Frequency | 8 | Frequency in MHz (e.g., `146.5200`) | +| Receive Frequency | 8 | Frequency in MHz | +| Tone | 2 | CTCSS tone frequency code (`00` for none) | +| Squelch | 1 | `0` through `8` (off through maximum squelch) | + +### 3.4. COMMAND_FILTERS (0x04) + +- **Description**: Configures the emphasis, high-pass, and low-pass filters. +- **Parameters**: 3 bytes. + - Each byte is either `0` (disable) or `1` (enable). + - Order: `[Emphasis][High-Pass][Low-Pass]`. +- **Usage**: + - Send the delimiter. + - Send the command code `0x04`. + - Send the 3-byte parameter string. + +### 3.5. COMMAND_STOP (0x05) + +- **Description**: Stops all operations and resets the device to standby mode, waiting for the next command. +- **Parameters**: None. +- **Usage**: + - Send the delimiter. + - Send the command code `0x05`. + +### 3.6. COMMAND_GET_FIRMWARE_VER (0x06) + +- **Description**: Requests the firmware version from the device. +- **Parameters**: None. +- **Response**: The device will send back the string `VERSION` followed by an 8-character firmware version (e.g., `00000002`). +- **Usage**: + - Send the delimiter. + - Send the command code `0x06`. + +--- + +## 4. Examples + +### 4.1. Changing Frequencies + +**Objective**: Set the transmit frequency to `146.5200` MHz, receive frequency to `146.5200` MHz, no tone, and squelch off. + +**Command Sequence**: + +1. **Delimiter**: + + ```plaintext + 0xFF 0x00 0xFF 0x00 0xFF 0x00 0xFF 0x00 + ``` + +2. **Command Code**: + + ```plaintext + 0x03 (COMMAND_TUNE_TO) + ``` + +3. **Parameters**: + + - Transmit Frequency: `146.5200` (ASCII) + - Receive Frequency: `146.5200` (ASCII) + - Tone: `00` (ASCII) + - Squelch: `0` (ASCII) + +**Full Byte Sequence** (in hexadecimal): + +```plaintext +FF 00 FF 00 FF 00 FF 00 03 31 34 36 2E 35 32 30 30 31 34 36 2E 35 32 30 30 30 30 30 +``` + +**Explanation**: + +- `31 34 36 2E 35 32 30 30` is ASCII for `146.5200`. +- Tone `00`: `30 30`. +- Squelch `0`: `30`. + +### 4.2. Starting Transmission + +**Objective**: Begin transmitting audio data. + +**Command Sequence**: + +1. **Delimiter**: + + ```plaintext + 0xFF 0x00 0xFF 0x00 0xFF 0x00 0xFF 0x00 + ``` + +2. **Command Code**: + + ```plaintext + 0x01 (COMMAND_PTT_DOWN) + ``` + +**Following Data**: + +- Send the audio data bytes immediately after the command. +- Audio data should be raw 8-bit PCM audio sampled at **44.1 kHz**. + +### 4.3. Stopping Transmission + +**Objective**: Stop transmitting and return to receive mode. + +**Command Sequence**: + +1. **While in transmission mode**, send the delimiter and the `COMMAND_PTT_UP` code. + + ```plaintext + 0xFF 0x00 0xFF 0x00 0xFF 0x00 0xFF 0x00 0x02 + ``` + +**Note**: There may be a brief delay (~40 ms) to allow final audio data to be transmitted. + +### 4.4. Configuring Filters + +**Objective**: Enable emphasis and disable high-pass and low-pass filters. + +**Command Sequence**: + +1. **Delimiter**: + + ```plaintext + 0xFF 0x00 0xFF 0x00 0xFF 0x00 0xFF 0x00 + ``` + +2. **Command Code**: + + ```plaintext + 0x04 (COMMAND_FILTERS) + ``` + +3. **Parameters**: + + - Emphasis: `1` + - High-Pass: `0` + - Low-Pass: `0` + +**Full Byte Sequence** (in hexadecimal): + +```plaintext +FF 00 FF 00 FF 00 FF 00 04 31 30 30 +``` + +### 4.5. Retrieving Firmware Version + +**Objective**: Get the firmware version from the device. + +**Command Sequence**: + +1. **Delimiter**: + + ```plaintext + 0xFF 0x00 0xFF 0x00 0xFF 0x00 0xFF 0x00 + ``` + +2. **Command Code**: + + ```plaintext + 0x06 (COMMAND_GET_FIRMWARE_VER) + ``` + +**Expected Response**: + +- The device will send back `VERSION00000002` (assuming the firmware version is `00000002`). + +--- + +## 5. Additional Notes + +- **Audio Data Format**: + - When transmitting (after `COMMAND_PTT_DOWN`), send raw 8-bit PCM audio data sampled at **44.1 kHz**. + - Ensure continuous data flow to prevent underruns or audio glitches. + +- **Runaway Transmission Prevention**: + - The device has a built-in safeguard that limits continuous transmission to **200 seconds** to prevent unintended prolonged transmissions. + +- **Squelch Behavior**: + - When in receive mode, the device handles squelch transitions smoothly using fade-in and fade-out effects to prevent audio pops. + +- **Buffer Sizes**: + - The device uses internal buffers to manage audio data. Avoid sending data exceeding buffer capacities in a single burst. + +- **Watchdog Timer (WDT)**: + - The device resets its watchdog timer regularly. If unresponsive, it may automatically reboot to recover from potential lock-ups. + +- **Error Handling**: + - Unexpected commands or malformed data may be ignored. Ensure that commands and parameters are correctly formatted according to the protocol. + +--- + +**Disclaimer**: Always test commands in a controlled environment to prevent unintended behavior. This documentation assumes familiarity with serial communication protocols and the KV4P-HT device's operational context. From 6fc36e1058650e24becd4f26e308b927c5882926 Mon Sep 17 00:00:00 2001 From: programmin1 Date: Tue, 3 Dec 2024 07:26:24 -0800 Subject: [PATCH 02/14] Set the ability to call a memory setting from intent, offset/tone/name included also, prevent nullpointer-exception. (#124) --- .../kv4pht/ui/AddEditMemoryActivity.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java index 724a9d34..73d16124 100644 --- a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java +++ b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java @@ -27,6 +27,7 @@ kv4p HT (see http://kv4p.com) import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; +import androidx.lifecycle.ViewModelProvider; import com.google.android.material.textfield.TextInputEditText; import com.vagell.kv4pht.R; @@ -122,6 +123,25 @@ public void run() { AutoCompleteTextView editMemoryGroupTextInputEditText = findViewById(R.id.editMemoryGroupTextInputEditText); editMemoryGroupTextInputEditText.setText(selectedMemoryGroup, false); } + + String offset = extras.getString("offset"); + if (offset != null) { + AutoCompleteTextView editOffset = findViewById(R.id.editOffsetTextView); + editOffset.setText(offset, false); + } + + String tone = extras.getString("tone"); + if (tone != null) { + AutoCompleteTextView editTone = findViewById(R.id.editToneTextView); + editTone.setText(tone, false); + } + + String name = extras.getString("name"); + if (name != null) { + TextInputEditText editNameTextInputEditText = findViewById(R.id.editNameTextInputEditText); + editNameTextInputEditText.setText(name); + } + } } @@ -160,6 +180,13 @@ private void populateMemoryGroups() { threadPoolExecutor.execute(new Runnable() { @Override public void run() { + if( MainViewModel.appDb == null ) { + //For example direct call other app intent. + //If app is not already open do not nullpointer-exception. + MainViewModel preloader = new MainViewModel(); + preloader.setActivity(activity); + preloader.loadData(); + } List memoryGroups = MainViewModel.appDb.channelMemoryDao().getGroups(); // Remove any blank memory groups from the list (shouldn't have been saved, ideally). From cb20bece24ebbd78d823131f21a3efd3a76c3854 Mon Sep 17 00:00:00 2001 From: Vance Vagell Date: Tue, 3 Dec 2024 12:36:46 -0500 Subject: [PATCH 03/14] Make screen stay on while using the app (user can always hit their power button to turn it off manually). Addresses issue #76. --- .../main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java | 3 +++ .../app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java | 3 +++ .../src/main/java/com/vagell/kv4pht/ui/SettingsActivity.java | 3 +++ 3 files changed, 9 insertions(+) diff --git a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java index 73d16124..25c83a6f 100644 --- a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java +++ b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/AddEditMemoryActivity.java @@ -21,6 +21,7 @@ kv4p HT (see http://kv4p.com) import android.app.Activity; import android.os.Bundle; import android.view.View; +import android.view.WindowManager; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.EditText; @@ -52,6 +53,8 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_edit_memory); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + threadPoolExecutor = new ThreadPoolExecutor(2, 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); diff --git a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java index 979a9fae..3d7007fa 100644 --- a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java +++ b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java @@ -50,6 +50,7 @@ kv4p HT (see http://kv4p.com) import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.ImageButton; @@ -161,6 +162,8 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + threadPoolExecutor = new ThreadPoolExecutor(2, 10, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); diff --git a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/SettingsActivity.java b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/SettingsActivity.java index 6b8a5edf..b260d7e0 100644 --- a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/SettingsActivity.java +++ b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/SettingsActivity.java @@ -28,6 +28,7 @@ kv4p HT (see http://kv4p.com) import android.text.TextWatcher; import android.view.KeyEvent; import android.view.View; +import android.view.WindowManager; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.CompoundButton; @@ -58,6 +59,8 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + threadPoolExecutor = new ThreadPoolExecutor(2, 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); From b4ba69a9faaf30378025bc98857df69ce82076a6 Mon Sep 17 00:00:00 2001 From: Vance Vagell Date: Tue, 3 Dec 2024 12:41:16 -0500 Subject: [PATCH 04/14] Fix bug where rx audio indicator was still visible even in the collapsed version of the text chat view, when the frequency is hidden. Addresses issue #102. --- .../app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java index 3d7007fa..6b59f0db 100644 --- a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java +++ b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java @@ -1003,6 +1003,7 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { final View rootView = findViewById(android.R.id.content); final View frequencyView = findViewById(R.id.frequencyContainer); final EditText activeFrequencyEditText = findViewById(R.id.activeFrequency); + final View rxAudioCircleView = findViewById(R.id.rxAudioCircle); // Track if keyboard is likely visible (and/or screen got short for some reason), so we can // make room for critical UI components that must be visible. @@ -1033,9 +1034,11 @@ public void onGlobalLayout() { if (heightDiff > screenHeight * 0.25) { // If more than 25% of the screen height is reduced // Keyboard is visible, hide the top view frequencyView.setVisibility(View.GONE); + rxAudioCircleView.setVisibility(View.GONE); } else { // Keyboard is hidden, show the top view frequencyView.setVisibility(View.VISIBLE); + rxAudioCircleView.setVisibility(View.VISIBLE); } } }); From 236cf49f7ab728f2028ff883914575fded238cda Mon Sep 17 00:00:00 2001 From: Vance Vagell Date: Tue, 3 Dec 2024 12:56:19 -0500 Subject: [PATCH 05/14] Fix bug #125 by making the Add/Edit Memory screen scrollable so the buttons can always be reached. --- .../KV4PHT/.idea/deploymentTargetDropDown.xml | 15 +- .../com/vagell/kv4pht/ui/MainActivity.java | 1 + .../res/layout/activity_add_edit_memory.xml | 288 +++++++++--------- 3 files changed, 161 insertions(+), 143 deletions(-) diff --git a/android-src/KV4PHT/.idea/deploymentTargetDropDown.xml b/android-src/KV4PHT/.idea/deploymentTargetDropDown.xml index 9a986ae3..1fbd213c 100644 --- a/android-src/KV4PHT/.idea/deploymentTargetDropDown.xml +++ b/android-src/KV4PHT/.idea/deploymentTargetDropDown.xml @@ -3,7 +3,20 @@ - + + + + + + + + + + + + + + diff --git a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java index 6b59f0db..9d9d07e9 100644 --- a/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java +++ b/android-src/KV4PHT/app/src/main/java/com/vagell/kv4pht/ui/MainActivity.java @@ -614,6 +614,7 @@ private void showScreen(ScreenType screenType) { } else if (screenType == ScreenType.SCREEN_VOICE){ hideKeyboard(); findViewById(R.id.frequencyContainer).setVisibility(View.VISIBLE); + findViewById(R.id.rxAudioCircle).setVisibility(View.VISIBLE); if (callsignSnackbar != null) { callsignSnackbar.dismiss(); diff --git a/android-src/KV4PHT/app/src/main/res/layout/activity_add_edit_memory.xml b/android-src/KV4PHT/app/src/main/res/layout/activity_add_edit_memory.xml index cc8a4c14..960932f6 100644 --- a/android-src/KV4PHT/app/src/main/res/layout/activity_add_edit_memory.xml +++ b/android-src/KV4PHT/app/src/main/res/layout/activity_add_edit_memory.xml @@ -35,157 +35,161 @@ android:layout_height="wrap_content" android:orientation="vertical"> - - - - - + android:orientation="vertical"> - - - - - - - - + + + + + + - - - - - - + + + + + - - - + + + + + + + + + + + + + + + + + + - - + +