kopia lustrzana https://github.com/eleccoder/raspi-pico-aprs-tnc
Porównaj commity
5 Commity
d6867e1a84
...
09256da282
Autor | SHA1 | Data |
---|---|---|
eleccoder | 09256da282 | |
eleccoder | 5869d83de5 | |
eleccoder | ded139bd3c | |
eleccoder | 4b59e48361 | |
eleccoder | 43a281861a |
|
@ -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()
|
||||
|
||||
|
|
34
README.md
34
README.md
|
@ -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 |
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue