Porównaj commity

...

5 Commity

Autor SHA1 Wiadomość Data
eleccoder 09256da282 Extra parameter for aprs_pico_send_sine_wave() 2022-12-21 23:08:27 +01:00
eleccoder 5869d83de5 Testing section added 2022-12-21 22:35:41 +01:00
eleccoder ded139bd3c C++ content removed 2022-12-21 22:02:22 +01:00
eleccoder 4b59e48361 Example made more real-world 2022-12-21 22:02:06 +01:00
eleccoder 43a281861a Improved program flow 2022-12-21 22:00:47 +01:00
6 zmienionych plików z 67 dodań i 33 usunięć

Wyświetl plik

@ -6,7 +6,6 @@ include(cmake/pico_extras_import.cmake) # File copied from $PICO_SDK_PATH/../pic
project(raspi-pico-aprs-tnc VERSION 0.1)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()

Wyświetl plik

@ -48,7 +48,7 @@ cmake -S . -B build
cmake --build build
```
`build/lib/libaprs_pico.a` and `build/aprs_pico_example.uf2|.elf|.xxx` will be generated.
`build/lib/libaprs_pico.a` and `build/aprs_pico_example[.uf2|.elf|.bin]` will be generated.
## Run the example application
@ -59,12 +59,38 @@ Flash 'aprs_pico_example[.uf2|.elf|.bin]' to the Pico board as usual
The analog AFSK audio signal will be available at the filter's line-out. You can probe it by a scope, listen to it by using an audio amp, or connect it to any RF transceiver to send it on the air (ham radio license required).
## TODO (Sept. 2021)
## Test the example application using *Dire Wolf* (on LINUX)
We can use the famous [Dire Wolf](https://github.com/wb2osz/direwolf) CLI software to decode the APRS data after sampling our APRS audio signal by means of a soundcard.
1. Connect the line-out of our circuit above to the microphone input of your soundcard of your (ALSA-supported) LINUX system.
2. Check if you can hear the typical APRS 'modem-sound' on your audio output device by monitoring the input signal:
```
arecord -f cd -c 1 -t raw - | aplay -f cd -c 1 -t raw
```
3. Install [Dire Wolf](https://github.com/wb2osz/direwolf) on your system. Probably, you just have to run:
```
sudo apt install direwolf
```
4. Let's sample the APRS audio signal fed to the soundcard and forward the audio stream to *Dire Wolf*:
```
arecord -f cd -c 1 -t raw - | direwolf
```
5. Enjoy the decoded APRS message:
![Decoded APRS message by Dire Wolf](https://github.com/eleccoder/raspi-pico-aprs-tnc/blob/main/doc/img/direwolf_decoding.png)
## TODO (Dec. 2022)
- [x] Thorough evaluation, in general
- [x] Send the APRS message on the console (USB or UART) rather than hard-coding
- [x] Show how to physically connect to a Baofeng HT
- [x] PTT control for RF transceivers
- [x] Show how to physically connect to a Baofeng HT
## Ingredients / Acknowledgements

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 21 KiB

Wyświetl plik

@ -65,8 +65,9 @@ bool aprs_pico_sendAPRS(audio_buffer_pool_t* audio_buffer_pool,
*
* \param[in, out] audio_buffer_pool The pool of audio buffers to be used for rendering the sine audio signal
* \param[in] freq_in_hz The frequency of the sine wave to be generated (in Hz)
* \param[in] sample_freq_in_hz The sampling frequency of the sine wave to be generated (in Hz)
* \param[in] volume The volume level of the generated signal (0 ... 256)
*/
void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, uint16_t volume);
void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, unsigned int sample_freq_in_hz, uint16_t volume);
#endif // APRS_PICO_H

Wyświetl plik

@ -116,19 +116,23 @@ static void aprs_pico_renderAudioSamples(audio_buffer_pool_t* audio_buffer_pool,
assert(audio_buffer_pool != NULL);
assert(pcm_data != NULL);
unsigned int idx_src = 0u;
bool is_keep_going = true;
unsigned int idx_src = 0u;
bool is_all_samples_processed = num_samples == 0u;
// Write the PCM sample data into the audio buffer(s) while applying the 'volume' value
while (is_keep_going)
// Write the PCM sample data into the next audio buffer while applying the 'volume' value
while (!is_all_samples_processed)
{
audio_buffer_t* audio_buffer = take_audio_buffer(audio_buffer_pool, true);
int16_t* audio_buffer_pcm_data = (int16_t*)audio_buffer->buffer->bytes;
for (unsigned int idx_dst = 0u; idx_dst < audio_buffer->max_sample_count; idx_dst++)
unsigned int idx_dst = 0u;
while (!is_all_samples_processed && (idx_dst < audio_buffer->max_sample_count))
{
audio_buffer_pcm_data[idx_dst] = ((int32_t)volume * (int32_t)pcm_data[idx_src]) >> 8u;
idx_src++;
idx_dst++;
if (idx_src == num_samples)
{
@ -138,13 +142,15 @@ static void aprs_pico_renderAudioSamples(audio_buffer_pool_t* audio_buffer_pool,
}
else
{
is_keep_going = false;
break;
is_all_samples_processed = true;
}
}
}
audio_buffer->sample_count = audio_buffer->max_sample_count;
assert(idx_src <= num_samples);
assert(idx_dst <= audio_buffer->max_sample_count);
audio_buffer->sample_count = idx_dst;
give_audio_buffer(audio_buffer_pool, audio_buffer);
}
}
@ -177,20 +183,17 @@ audio_buffer_pool_t* aprs_pico_init()
// See the header file for documentation
void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, uint16_t volume)
void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, unsigned int sample_freq_in_hz, uint16_t volume)
{
assert(audio_buffer_pool != NULL);
// WARNING: ATTOW, the pico audio PWM lib worked only @ 22050 Hz sampling frequency and 48 MHz system clock
// This is documented here: https://github.com/raspberrypi/pico-extras
const unsigned int SAMPLE_FREQ_IN_HZ = APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB_FIXED_SAMPLE_FREQ_IN_HZ;
const unsigned int num_samples_per_period = SAMPLE_FREQ_IN_HZ / freq_in_hz;
typedef int16_t wave_table_value_t;
const wave_table_value_t WAVE_TABLE_VALUE_MAX = INT16_MAX;
aprs_pico_initClock(SAMPLE_FREQ_IN_HZ);
aprs_pico_initClock(sample_freq_in_hz);
const unsigned int num_samples_per_period = sample_freq_in_hz / freq_in_hz;
wave_table_value_t* sine_period_wave_table = malloc(num_samples_per_period * sizeof(wave_table_value_t));

Wyświetl plik

@ -31,26 +31,31 @@ int main()
#if (SINE_WAVE_TEST == 1)
const unsigned int FREQ_IN_HZ = 1000u;
const uint16_t VOLUME = 128u;
const unsigned int FREQ_IN_HZ = 1000u;
const unsigned int SAMPLE_FREQ_IN_HZ = 48000u;
const uint16_t VOLUME = 128u;
aprs_pico_send_sine_wave(audio_buffer_pool, FREQ_IN_HZ, VOLUME);
aprs_pico_send_sine_wave(audio_buffer_pool, FREQ_IN_HZ, SAMPLE_FREQ_IN_HZ, VOLUME);
#else // !SINE_WAVE_TEST
double alt_in_m = 0.0f;
while (true) // Loop forever
{
// Send an APRS test message
aprs_pico_sendAPRS(audio_buffer_pool,
"SRC", // Source call sign
"DST", // Destination call sign
"PATH1", // APRS path #1
"PATH2", // APRS path #2
"Test message", // APRS message
10.0, // Latitude (in deg)
20.0, // Longitude (in deg)
100.0, // Altitude (in m)
128u); // Volume (0 ... 256)
"DL3TG", // Source call sign
"DL3TG", // Destination call sign
"PATH1", // APRS path #1
"PATH2", // APRS path #2
"APRS by RPi-Pico - https://github.com/eleccoder/raspi-pico-aprs-tnc", // APRS message
10.0, // Latitude (in deg)
20.0, // Longitude (in deg)
alt_in_m, // Altitude (in m)
128u); // Volume (0 ... 256)
alt_in_m = (alt_in_m < 1000.0) ? alt_in_m + 100.0 : 0.0;
}
#endif // SINE_WAVE_TEST, !SINE_WAVE_TEST