diff --git a/CMakeLists.txt b/CMakeLists.txt
index e9380b5..d59ada8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -111,7 +111,7 @@ find_package(Doxygen)
# components required to the list of GR_REQUIRED_COMPONENTS (in all
# caps such as FILTER or FFT) and change the version to the minimum
# API compatible version required.
-set(GR_REQUIRED_COMPONENTS RUNTIME)
+set(GR_REQUIRED_COMPONENTS RUNTIME FILTER)
find_package(Gnuradio "3.7.2" REQUIRED)
if(NOT CPPUNIT_FOUND)
diff --git a/grc/lora_channelizer.xml b/grc/lora_channelizer.xml
new file mode 100644
index 0000000..578ae35
--- /dev/null
+++ b/grc/lora_channelizer.xml
@@ -0,0 +1,28 @@
+
+
+ channelizer
+ lora_channelizer
+
+ import lora
+ lora.channelizer($in_samp_rate, $out_samp_rate, $center_freq, $channel_list)
+
+
+
+ in
+ complex
+
+
+
+
+ out
+ complex
+
+
diff --git a/grc/lora_controller.xml b/grc/lora_controller.xml
new file mode 100644
index 0000000..a766097
--- /dev/null
+++ b/grc/lora_controller.xml
@@ -0,0 +1,9 @@
+
+
+ controller
+ lora_controller
+
+ import lora
+ lora.controller($parent)
+
+
diff --git a/grc/lora_receiver.xml b/grc/lora_receiver.xml
index f3f2f52..0b98210 100644
--- a/grc/lora_receiver.xml
+++ b/grc/lora_receiver.xml
@@ -4,19 +4,13 @@
lora_lora_receiver[LoRa]import lora
- lora.lora_receiver($in_samp_rate, $freq, $offset, $sf, $out_samp_rate, $threshold)
+ lora.lora_receiver($in_samp_rate, $center_freq, $channel_list, $sf, $out_samp_rate, $threshold)
+ set_center_freq($freq)set_sf($sf)
- set_offset($offset)set_out_samp_rate($out_samp_rate)set_threshold($threshold)
-
- Spreading factor
- sf
- int
-
-
Sample ratein_samp_rate
@@ -24,24 +18,30 @@
float
-
- Detection threshold
- threshold
- 0.01
- float
-
-
- Frequency
- freq
+ Center frequency
+ center_freq868e6float
- Offset
- offset
- 100e3
+ Channel list
+ channel_list
+ [868.1e6]
+ float_vector
+
+
+
+ Spreading factor
+ sf
+ int
+
+
+
+ Detection threshold
+ threshold
+ 0.01float
@@ -63,10 +63,4 @@
message1
-
-
- debug
- message
- 1
-
diff --git a/include/lora/CMakeLists.txt b/include/lora/CMakeLists.txt
index 458a440..9e60420 100644
--- a/include/lora/CMakeLists.txt
+++ b/include/lora/CMakeLists.txt
@@ -24,5 +24,7 @@ install(FILES
api.h
decoder.h
message_file_sink.h
- message_socket_sink.h DESTINATION include/lora
+ message_socket_sink.h
+ channelizer.h
+ controller.h DESTINATION include/lora
)
diff --git a/include/lora/channelizer.h b/include/lora/channelizer.h
new file mode 100644
index 0000000..383ebe4
--- /dev/null
+++ b/include/lora/channelizer.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Pieter Robyns.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_LORA_CHANNELIZER_H
+#define INCLUDED_LORA_CHANNELIZER_H
+
+#include
+#include
+
+namespace gr {
+ namespace lora {
+
+ /*!
+ * \brief <+description of block+>
+ * \ingroup lora
+ *
+ */
+ class LORA_API channelizer : virtual public gr::hier_block2
+ {
+ public:
+ typedef boost::shared_ptr sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of lora::channelizer.
+ *
+ * To avoid accidental use of raw pointers, lora::channelizer's
+ * constructor is in a private implementation
+ * class. lora::channelizer::make is the public interface for
+ * creating new instances.
+ */
+ static sptr make(float in_samp_rate, float out_samp_rate, float center_freq, std::vector channel_list);
+ };
+
+ } // namespace lora
+} // namespace gr
+
+#endif /* INCLUDED_LORA_CHANNELIZER_H */
diff --git a/include/lora/controller.h b/include/lora/controller.h
new file mode 100644
index 0000000..278e91c
--- /dev/null
+++ b/include/lora/controller.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Pieter Robyns.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_LORA_CONTROLLER_H
+#define INCLUDED_LORA_CONTROLLER_H
+
+#include
+#include
+
+namespace gr {
+ namespace lora {
+
+ /*!
+ * \brief <+description of block+>
+ * \ingroup lora
+ *
+ */
+ class channelizer_impl;
+ class LORA_API controller : virtual public gr::block
+ {
+ public:
+ typedef boost::shared_ptr sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of lora::controller.
+ *
+ * To avoid accidental use of raw pointers, lora::controller's
+ * constructor is in a private implementation
+ * class. lora::controller::make is the public interface for
+ * creating new instances.
+ */
+ static sptr make(void* parent);
+ };
+
+ } // namespace lora
+} // namespace gr
+
+#endif /* INCLUDED_LORA_CONTROLLER_H */
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 5023272..b2bf736 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -29,6 +29,8 @@ list(APPEND lora_sources
decoder_impl.cc
message_file_sink_impl.cc
message_socket_sink_impl.cc
+ channelizer_impl.cc
+ controller_impl.cc
)
set(lora_sources "${lora_sources}" PARENT_SCOPE)
diff --git a/lib/channelizer_impl.cc b/lib/channelizer_impl.cc
new file mode 100644
index 0000000..f73be74
--- /dev/null
+++ b/lib/channelizer_impl.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Pieter Robyns.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include "channelizer_impl.h"
+
+namespace gr {
+ namespace lora {
+
+ channelizer::sptr
+ channelizer::make(float in_samp_rate, float out_samp_rate, float center_freq, std::vector channel_list) {
+ return gnuradio::get_initial_sptr
+ (new channelizer_impl(in_samp_rate, out_samp_rate, center_freq, channel_list));
+ }
+
+ /*
+ * The private constructor
+ */
+ channelizer_impl::channelizer_impl(float in_samp_rate, float out_samp_rate, float center_freq, std::vector channel_list)
+ : gr::hier_block2("channelizer",
+ gr::io_signature::make(1, 1, sizeof(gr_complex)),
+ gr::io_signature::make(channel_list.size(), channel_list.size(), sizeof(gr_complex))),
+ d_cfo(0.0)
+ {
+ d_lpf = gr::filter::firdes::low_pass(1.0, out_samp_rate, 86000, 20000, gr::filter::firdes::WIN_HAMMING, 6.67);
+ d_freq_offset = channel_list[0] - center_freq;
+ d_xlating_fir_filter = gr::filter::freq_xlating_fir_filter_ccf::make(1, d_lpf, d_freq_offset, out_samp_rate);
+ d_controller = gr::lora::controller::make((void*)this);
+ d_resampler = gr::filter::fractional_resampler_cc::make(0, (float)in_samp_rate / (float)out_samp_rate);
+ //self.delay = delay(gr.sizeof_gr_complex, int((len(lpf)-1) / 2.0))
+
+ //Create message ports
+ message_port_register_hier_in(pmt::intern("control"));
+
+ connect(self(), 0, d_resampler, 0);
+ connect(d_resampler, 0, d_xlating_fir_filter, 0);
+ connect(d_xlating_fir_filter, 0, self(), 0);
+
+ msg_connect(self(), pmt::intern("control"), d_controller, pmt::intern("control"));
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ channelizer_impl::~channelizer_impl() {
+ }
+
+ void channelizer_impl::apply_cfo(float cfo) {
+ d_cfo += cfo;
+ //std::cout << d_freq_offset + d_cfo << std::endl;
+ d_xlating_fir_filter->set_center_freq(d_freq_offset + d_cfo);
+ }
+
+
+ } /* namespace lora */
+} /* namespace gr */
diff --git a/lib/channelizer_impl.h b/lib/channelizer_impl.h
new file mode 100644
index 0000000..2683e1e
--- /dev/null
+++ b/lib/channelizer_impl.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Pieter Robyns.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_LORA_CHANNELIZER_IMPL_H
+#define INCLUDED_LORA_CHANNELIZER_IMPL_H
+
+#include
+#include
+#include
+#include
+#include
+
+namespace gr {
+ namespace lora {
+ class channelizer_impl : public channelizer {
+ private:
+ gr::filter::freq_xlating_fir_filter_ccf::sptr d_xlating_fir_filter;
+ gr::filter::fractional_resampler_cc::sptr d_resampler;
+ std::vector d_lpf;
+ float d_cfo;
+ uint32_t d_freq_offset;
+ gr::lora::controller::sptr d_controller;
+
+ public:
+ channelizer_impl(float in_samp_rate, float out_samp_rate, float center_freq, std::vector channel_list);
+ ~channelizer_impl();
+ void apply_cfo(float cfo);
+
+ // Where all the action really happens
+ };
+ } // namespace lora
+} // namespace gr
+
+#endif /* INCLUDED_LORA_CHANNELIZER_IMPL_H */
diff --git a/lib/controller_impl.cc b/lib/controller_impl.cc
new file mode 100644
index 0000000..846f447
--- /dev/null
+++ b/lib/controller_impl.cc
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Pieter Robyns.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include "controller_impl.h"
+#include "channelizer_impl.h"
+
+namespace gr {
+ namespace lora {
+
+ controller::sptr
+ controller::make(void* parent) {
+ return gnuradio::get_initial_sptr
+ (new controller_impl(parent));
+ }
+
+ /*
+ * The private constructor
+ */
+ controller_impl::controller_impl(void* parent)
+ : gr::block("controller",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0)) {
+ d_parent = parent;
+ d_port = pmt::intern("control");
+ message_port_register_in(d_port);
+ set_msg_handler(d_port, boost::bind(&controller_impl::handle_control, this, _1));
+ }
+
+ void controller_impl::handle_control(pmt::pmt_t msg){
+ if(pmt::symbol_to_string(pmt::car(msg)).compare("cfo") == 0) {
+ //std::cout << "Setting CFO " << pmt::to_float(pmt::cdr(msg)) << std::endl;
+ ((channelizer_impl*)d_parent)->apply_cfo(pmt::to_float(pmt::cdr(msg))); // TODO: Pretty hacky cast, can we do this in a cleaner way?
+ }
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ controller_impl::~controller_impl()
+ {
+ }
+
+
+ } /* namespace lora */
+} /* namespace gr */
diff --git a/lib/controller_impl.h b/lib/controller_impl.h
new file mode 100644
index 0000000..365da22
--- /dev/null
+++ b/lib/controller_impl.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2017 Pieter Robyns.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_LORA_CONTROLLER_IMPL_H
+#define INCLUDED_LORA_CONTROLLER_IMPL_H
+
+#include
+
+namespace gr {
+ namespace lora {
+
+ class controller_impl : public controller {
+ private:
+ void* d_parent;
+ pmt::pmt_t d_port;
+
+ void handle_control(pmt::pmt_t msg);
+
+ public:
+ controller_impl(void* parent);
+ ~controller_impl();
+
+ // Where all the action really happens
+ };
+
+ } // namespace lora
+} // namespace gr
+
+#endif /* INCLUDED_LORA_CONTROLLER_IMPL_H */
diff --git a/lib/decoder_impl.cc b/lib/decoder_impl.cc
index 071811a..cf06920 100644
--- a/lib/decoder_impl.cc
+++ b/lib/decoder_impl.cc
@@ -137,7 +137,7 @@ namespace gr {
// Register gnuradio ports
this->message_port_register_out(pmt::mp("frames"));
- this->message_port_register_out(pmt::mp("debug"));
+ this->message_port_register_out(pmt::mp("control"));
// Whitening empty file
@@ -775,7 +775,7 @@ namespace gr {
void decoder_impl::msg_raw_chirp_debug(const gr_complex *raw_samples, const uint32_t num_samples) {
pmt::pmt_t chirp_blob = pmt::make_blob(raw_samples, sizeof(gr_complex) * num_samples);
- message_port_pub(pmt::mp("debug"), chirp_blob);
+ //message_port_pub(pmt::mp("debug"), chirp_blob);
}
void decoder_impl::msg_lora_frame(const uint8_t *frame_bytes, const uint32_t frame_len) {
diff --git a/python/lora_receiver.py b/python/lora_receiver.py
index 743e429..b744f6e 100644
--- a/python/lora_receiver.py
+++ b/python/lora_receiver.py
@@ -20,76 +20,56 @@
#
from gnuradio import gr
-from gnuradio.filter import freq_xlating_fir_filter_ccf, firdes, fractional_resampler_cc
-from gnuradio.analog import quadrature_demod_cf
-from gnuradio.blocks import null_sink, delay
import lora
-import pmt
class lora_receiver(gr.hier_block2):
"""
docstring for block lora_receiver
"""
- def __init__(self, in_samp_rate, freq, offset, sf, out_samp_rate, threshold = 0.01):
+ def __init__(self, in_samp_rate, center_freq, channel_list, sf, out_samp_rate, threshold = 0.01):
gr.hier_block2.__init__(self,
"lora_receiver", # Min, Max, gr.sizeof_
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
gr.io_signature(0, 0, 0)) # Output signature
# Parameters
- self.offset = offset
- self.sf = sf
self.in_samp_rate = in_samp_rate
+ self.center_freq = center_freq
+ self.sf = sf
self.out_samp_rate = out_samp_rate
- bw = 125000
+ self.channel_list = channel_list
# Define blocks
- null1 = null_sink(gr.sizeof_float)
- null2 = null_sink(gr.sizeof_float)
- self.c_decoder = lora.decoder(out_samp_rate, sf)
+ self.channelizer = lora.channelizer(in_samp_rate, out_samp_rate, center_freq, channel_list)
+ self.decoder = lora.decoder(out_samp_rate, sf)
self.set_threshold(threshold)
- decimation = 1
-
- lpf = firdes.low_pass(1, out_samp_rate, 86000, 20000, firdes.WIN_HAMMING, 6.67)
- channelizer = freq_xlating_fir_filter_ccf(decimation, lpf, offset, out_samp_rate)
- self.channelizer = channelizer
- resampler = fractional_resampler_cc(0, float(in_samp_rate) / float(out_samp_rate))
- self.delay = delay(gr.sizeof_gr_complex, int((len(lpf)-1) / 2.0))
-
# Messages
- self.message_port_register_hier_out('debug')
self.message_port_register_hier_out('frames')
# Connect blocks
- self.connect( (self, 0), (resampler, 0) )
- self.connect( (resampler, 0), (channelizer, 0) )
- self.connect( (channelizer, 0), (self.c_decoder, 0) )
- self.connect( (resampler, 0), (self.delay, 0) )
- self.connect( (self.delay, 0), (self.c_decoder, 1) )
- self.msg_connect( (self.c_decoder, 'debug' ), (self, 'debug' ) )
- self.msg_connect( (self.c_decoder, 'frames'), (self, 'frames') )
+ self.connect((self, 0), (self.channelizer, 0))
+ self.connect((self.channelizer, 0), (self.decoder, 0))
+ self.msg_connect((self.decoder, 'frames'), (self, 'frames'))
+ self.msg_connect((self.decoder, 'control'), (self.channelizer, 'control'))
def get_sf(self):
return self.sf
def set_sf(self, sf):
self.sf = sf
- ## hier_block2 does not have a realtime attribute:
- ## http://gnuradio.org/doc/sphinx/runtime.html?highlight=hier_block2#gnuradio.gr.hier_block2
- # if self.realtime:
- self.c_decoder.set_sf(self.sf)
+ self.decoder.set_sf(self.sf)
- def get_offset(self):
- return self.offset
+ def get_center_freq(self):
+ return self.center_freq
- def set_offset(self, offset):
- self.offset = offset
- self.channelizer.set_center_freq(self.offset)
+ def set_center_freq(self, center_freq):
+ self.center_freq = center_freq
+ self.channelizer.set_center_freq(self.center_freq)
def get_threshold(self):
return self.threshold
def set_threshold(self, threshold):
self.threshold = threshold
- self.c_decoder.set_abs_threshold(self.threshold)
+ self.decoder.set_abs_threshold(self.threshold)
diff --git a/swig/lora_swig.i b/swig/lora_swig.i
index 5f01969..035db72 100644
--- a/swig/lora_swig.i
+++ b/swig/lora_swig.i
@@ -11,6 +11,8 @@
#include "lora/decoder.h"
#include "lora/message_file_sink.h"
#include "lora/message_socket_sink.h"
+#include "lora/channelizer.h"
+#include "lora/controller.h"
%}
@@ -20,3 +22,7 @@ GR_SWIG_BLOCK_MAGIC2(lora, decoder);
GR_SWIG_BLOCK_MAGIC2(lora, message_file_sink);
%include "lora/message_socket_sink.h"
GR_SWIG_BLOCK_MAGIC2(lora, message_socket_sink);
+%include "lora/channelizer.h"
+GR_SWIG_BLOCK_MAGIC2(lora, channelizer);
+%include "lora/controller.h"
+GR_SWIG_BLOCK_MAGIC2(lora, controller);