-
Notifications
You must be signed in to change notification settings - Fork 387
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
Issue with APRS using AFSK on the RPi Pico #1230
Comments
Full HAL implementation
#ifndef PICO_HAL_H
#define PICO_HAL_H
// include RadioLib
#include <RadioLib.h>
// include the necessary Pico libraries
#include <pico/stdlib.h>
#include "hardware/spi.h"
#include "hardware/timer.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
#include "pico_tone.hpp"
// create a new Raspberry Pi Pico hardware abstraction
// layer using the Pico SDK
// the HAL must inherit from the base RadioLibHal class
// and implement all of its virtual methods
class PicoHal : public RadioLibHal {
public:
PicoHal(spi_inst_t *spiChannel, uint32_t misoPin, uint32_t mosiPin, uint32_t sckPin, uint32_t spiSpeed = 500 * 1000)
: RadioLibHal(GPIO_IN, GPIO_OUT, 0, 1, GPIO_IRQ_EDGE_RISE, GPIO_IRQ_EDGE_FALL),
_spiChannel(spiChannel),
_spiSpeed(spiSpeed),
_misoPin(misoPin),
_mosiPin(mosiPin),
_sckPin(sckPin) {
}
void init() override {
stdio_init_all();
spiBegin();
}
void term() override {
spiEnd();
}
// GPIO-related methods (pinMode, digitalWrite etc.) should check
// RADIOLIB_NC as an alias for non-connected pins
void pinMode(uint32_t pin, uint32_t mode) override {
if (pin == RADIOLIB_NC) {
return;
}
gpio_init(pin);
gpio_set_dir(pin, mode);
}
void digitalWrite(uint32_t pin, uint32_t value) override {
if (pin == RADIOLIB_NC) {
return;
}
gpio_put(pin, (bool)value);
}
uint32_t digitalRead(uint32_t pin) override {
if (pin == RADIOLIB_NC) {
return 0;
}
return gpio_get(pin);
}
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
if (interruptNum == RADIOLIB_NC) {
return;
}
gpio_set_irq_enabled_with_callback(interruptNum, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, (gpio_irq_callback_t)interruptCb);
}
void detachInterrupt(uint32_t interruptNum) override {
if (interruptNum == RADIOLIB_NC) {
return;
}
gpio_set_irq_enabled_with_callback(interruptNum, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false, NULL);
}
void delay(unsigned long ms) override {
sleep_ms(ms);
}
void delayMicroseconds(unsigned long us) override {
sleep_us(us);
}
unsigned long millis() override {
return to_ms_since_boot(get_absolute_time());
}
unsigned long micros() override {
return to_us_since_boot(get_absolute_time());
}
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
if (pin == RADIOLIB_NC) {
return 0;
}
this->pinMode(pin, GPIO_IN);
uint32_t start = this->micros();
uint32_t curtick = this->micros();
while (this->digitalRead(pin) == state) {
if ((this->micros() - curtick) > timeout) {
return 0;
}
}
return (this->micros() - start);
}
void set_pwm_frequency(uint gpio, unsigned int frequency) {
uint slice_num = pwm_gpio_to_slice_num(gpio);
// Calculate the PWM wrap value based on the desired frequency
pwm_config config = pwm_get_default_config();
uint32_t clock_freq = clock_get_hz(clk_sys);
float divider = clock_freq / (frequency * 65536.0);
pwm_config_set_clkdiv(&config, divider);
pwm_init(slice_num, &config, true);
uint32_t wrap = clock_freq / frequency;
// pwm_set_wrap(slice_num, wrap - 1);
// pwm_set_chan_level(slice_num, pwm_gpio_to_channel(gpio), wrap / 2); // 50% duty cycle
// pwm_set_enabled(slice_num, true);
uint16_t level = (1 << 15);
pwm_set_gpio_level(gpio, level);
}
void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) override {
printf("Using pin %d at freq %d...", pin, frequency);
gpio_set_function(pin, GPIO_FUNC_PWM);
set_pwm_frequency(pin, frequency);
if (duration > 0){
sleep_ms(duration);
pwm_set_enabled(pwm_gpio_to_slice_num(pin), false);
}
}
void noTone(uint32_t pin) override {
pwm_set_enabled(pwm_gpio_to_slice_num(pin), false);
}
void spiBegin() {
spi_init(_spiChannel, _spiSpeed);
spi_set_format(_spiChannel, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
gpio_set_function(_sckPin, GPIO_FUNC_SPI);
gpio_set_function(_mosiPin, GPIO_FUNC_SPI);
gpio_set_function(_misoPin, GPIO_FUNC_SPI);
}
void spiBeginTransaction() {}
void spiTransfer(uint8_t *out, size_t len, uint8_t *in) {
spi_write_read_blocking(_spiChannel, out, in, len);
}
void spiEndTransaction() {}
void spiEnd() {
spi_deinit(_spiChannel);
}
protected:
Tone tonePin = Tone(28);
private:
// the HAL can contain any additional private members
spi_inst_t *_spiChannel;
uint32_t _spiSpeed;
uint32_t _misoPin;
uint32_t _mosiPin;
uint32_t _sckPin;
};
#endif |
It looks like the signal is not modulated at all. That could be caused by a few things:
|
|
It might also be a good idea to check the PWM output is as expceted, i.e. a sequence of 1200 Hz and 2200 Hz tones, e.g. with an oscilloscope. |
Good call with checking with oscilloscope. It looks like my code does not work for 2200Hz; PWM outputs ~39Hz. I can sweep through 400-1200 fine though. Let me work through this error and see if I get anywhere. |
Ok, made modifications to the code, and I can transmit both 1200 and 2200 Hz tones fine. However, they're a little off-skew; so it's more like 1.21kHz and 2.21kHz. I don't think that should be a huge issue, should it? This is what I'm transmitting, yet nothing being received by my receiver (Kenwood radio). Any other thoughts? |
From the SDR software screenshot it looks like you're using wideband FM mode. Can you try with narrowband FM? |
As in 2500Hz? Unfortunately CubicSDR does not let me go that low. It exits prematurely. I don't think it can handle narrowband. Nonetheless, I am not receiving anything on my Kenwoods, which should be on narrowband. |
Hi there,
I am trying to transmit APRS packets using AFSK on the RPi Pico (RP2040) and SX1278 module. I am starting from the HAL provided in the examples/NonArduino/Pico.
My first step was to override the
tone
andnoTone
functions so that they can generate square waves at given frequencies:I have tried the AFSK_Tone and AFSK_Imperial_March examples, and they work fine with this implementation. However, when I try to transmit APRS using AFSK, it sounds like its just using FSK: like it's not using my tone generators at all. Here's my code for that"
I have tried different configurations of the SX1278, to no avail. I have checked the state at radio initialization, ax25 initialization, and aprs initialization. Nothing wrong there. This is what a waterfall plot of what I'm seeing looks like:
I know this library is targeted to more Arduino users. However, I feel like I am at the finish line with getting this to work on the RPi Pico and SX1278. Is there anything glaring I'm missing? I'll include the full HAL file as a comment to this issue so it doesn't get too unwieldy. Thanks!
The text was updated successfully, but these errors were encountered: