From c347cb78e0997f542c2788138f09e636bcaaeb54 Mon Sep 17 00:00:00 2001 From: MReenen Date: Mon, 26 Feb 2024 16:25:30 +0100 Subject: [PATCH] long lasting updates --- radio/main.cpp | 72 ++++++++----- radio/test/untitled.grc | 226 ++++++++++++++++++++++++++++++++++++++++ radio/test/untitled.py | 201 +++++++++++++++++++++++++++++++++++ 3 files changed, 475 insertions(+), 24 deletions(-) create mode 100644 radio/test/untitled.grc create mode 100755 radio/test/untitled.py diff --git a/radio/main.cpp b/radio/main.cpp index b2d61d2..69a1ed2 100644 --- a/radio/main.cpp +++ b/radio/main.cpp @@ -13,17 +13,18 @@ #include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() #include "pico/bootrom.h" // reset_usb_boot() #include // RF24 radio object +#include "nRF24L01.h" // instantiate an object for the nRF24L01 transceiver RF24 radio(2, 1); // Used to control whether this node is sending or receiving -bool role = false; // true = TX role, false = RX role +bool transmit = false; // true = TX role, false = RX role // For this example, we'll be using a payload containing // a single float number that will be incremented // on every successful transmission -float payload = 0.0; +float payload = 5.6; char getCommand(char* msg, char* validCmd){ char input[2]; @@ -52,7 +53,7 @@ char getCommand(char* msg, char* validCmd){ bool setup() { // Let these addresses be used for the pair - uint8_t address[][6] = {"1Node", "2Node"}; + uint8_t address[5][6] = {"0Node", "1Node"}; // It is very helpful to think of an address as a path instead of as // an identifying device destination @@ -60,21 +61,19 @@ bool setup() // uniquely identify which address this radio will use to transmit bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - sleep_ms(1000); spi.begin(spi0, 6, 7, 4); // spi0 or spi1 bus, SCK, MOSI, MISO + sleep_ms(1000); // initialize the transceiver on the SPI bus if (!radio.begin(&spi)) { printf("radio hardware is not responding!!\n"); return false; } - // print example's introductory prompt - printf("RF24/examples_pico/gettingStarted\n"); + printf("radio transiver v0.0.1\n"); // To set the radioNumber via the Serial terminal on startup char input = getCommand("Which radio is this? [0, 1]# ", "01"); radioNumber = input == '1'; - role = radioNumber; printf("radioNumber = %d\n", (int)radioNumber); // Set the PA Level low to try preventing power supply related problems @@ -93,30 +92,53 @@ bool setup() radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 // additional setup specific to the node's role - if (role) { + if (transmit) { radio.stopListening(); // put radio in TX mode + printf("*** PRESS 'R' to begin reciveing from the other node\n"); } else { radio.startListening(); // put radio in RX mode + printf("*** PRESS 'T' to begin transmitting to the other node\n"); } // For debugging info // radio.printDetails(); // (smaller) function that prints raw register values // radio.printPrettyDetails(); // (larger) function that prints human readable data - // role variable is hardcoded to RX behavior, inform the user of this - printf("*** PRESS 'T' to begin transmitting to the other node\n"); - return true; } // setup void loop() { - if (role) { + if (transmit) { // This device is a TX node uint64_t start_timer = to_us_since_boot(get_absolute_time()); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report + + bool report = true; + //Start Writing + radio.startFastWrite(&payload, sizeof(payload), false); + + //Wait until complete or failed + uint32_t timer = millis(); + while (!(radio.get_status() & (_BV(TX_DS) | _BV(MAX_RT)))) { + if (millis() - timer > 95) { + printf("transmission problebly faild. It took more then 95 ms\n"); + report = false; + break; + } + } + + radio.ce(LOW); + radio.write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); + + if (radio.status & _BV(MAX_RT)){ + radio.flush_tx(); // Only going to be 1 packet in the FIFO at a time using this method, so just flush + printf("transmission failed!! :( reached max retries\n"); + report = false; + } + + // bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report uint64_t end_timer = to_us_since_boot(get_absolute_time()); // end the timer if (report) { @@ -126,15 +148,14 @@ void loop() // increment float payload payload += 0.01; } - else { - // payload was not delivered - printf("Transmission failed or timed out\n"); - } + // else { + // // payload was not delivered + // printf("Transmission failed or timed out\n"); + // } // to make this example readable in the serial terminal sleep_ms(1000); // slow transmissions down by 1 second - } - else { + } else { // This device is a RX node uint8_t pipe; @@ -145,23 +166,23 @@ void loop() // print the size of the payload, the pipe number, payload's value printf("Received %d bytes on pipe %d: %f\n", bytes, pipe, payload); } - } // role + } // end if (transmit) char input = getchar_timeout_us(0); // get char from buffer for user input if (input != PICO_ERROR_TIMEOUT) { // change the role via the serial terminal - if ((input == 'T' || input == 't') && !role) { + if ((input == 'T' || input == 't') && !transmit) { // Become the TX node - role = true; + transmit = true; printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n"); radio.stopListening(); } - else if ((input == 'R' || input == 'r') && role) { + else if ((input == 'R' || input == 'r') && transmit) { // Become the RX node - role = false; + transmit = false; printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n"); radio.startListening(); } @@ -170,6 +191,9 @@ void loop() radio.powerDown(); reset_usb_boot(0, 0); } + else if (input == 'i' || input == 'I'){ + radio.printPrettyDetails(); + } } } // loop diff --git a/radio/test/untitled.grc b/radio/test/untitled.grc new file mode 100644 index 0000000..d503629 --- /dev/null +++ b/radio/test/untitled.grc @@ -0,0 +1,226 @@ +options: + parameters: + author: mreenen + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: untitled + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: Not titled yet + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: freq + id: variable + parameters: + comment: '' + value: int(2.45e9) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [288, 12.0] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: int(1e6) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [184, 12] + rotation: 0 + state: enabled +- name: iio_pluto_sink_0 + id: iio_pluto_sink + parameters: + affinity: '' + alias: '' + attenuation1: '10.0' + bandwidth: '20000000' + buffer_size: '32768' + comment: '' + cyclic: 'False' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: '2400000000' + fstop: '0' + len_tag_key: '' + samplerate: samp_rate + type: fc32 + uri: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [920, 448.0] + rotation: 0 + state: disabled +- name: iio_pluto_source_0 + id: iio_pluto_source + parameters: + affinity: '' + alias: '' + bandwidth: '20000000' + bbdc: 'True' + buffer_size: '32768' + comment: '' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: freq + fstop: '0' + gain1: '''slow_attack''' + len_tag_key: packet_len + manual_gain1: '64' + maxoutbuf: '0' + minoutbuf: '0' + quadrature: 'True' + rfdc: 'True' + samplerate: samp_rate + type: fc32 + uri: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [48, 172.0] + rotation: 0 + state: disabled +- name: qtgui_freq_sink_x_0 + id: qtgui_freq_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + average: '1.0' + axislabels: 'True' + bw: samp_rate + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + ctrlpanel: 'False' + fc: '0' + fftsize: '1024' + freqhalf: 'True' + grid: 'False' + gui_hint: '' + label: Relative Gain + label1: '' + label10: '''''' + label2: '''''' + label3: '''''' + label4: '''''' + label5: '''''' + label6: '''''' + label7: '''''' + label8: '''''' + label9: '''''' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + norm_window: 'False' + showports: 'False' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_tag: '""' + type: complex + units: dB + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + wintype: window.WIN_BLACKMAN_hARRIS + ymax: '10' + ymin: '-140' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [312, 228.0] + rotation: 0 + state: true +- name: soapy_plutosdr_source_0 + id: soapy_plutosdr_source + parameters: + affinity: '' + agc: 'False' + alias: '' + bandwidth: '0.0' + center_freq: freq + comment: '' + dev_args: '' + gain: '20' + maxoutbuf: '0' + minoutbuf: '0' + samp_rate: samp_rate + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [64, 236.0] + rotation: 0 + state: true + +connections: +- [iio_pluto_source_0, '0', qtgui_freq_sink_x_0, '0'] +- [soapy_plutosdr_source_0, '0', qtgui_freq_sink_x_0, '0'] + +metadata: + file_format: 1 diff --git a/radio/test/untitled.py b/radio/test/untitled.py new file mode 100755 index 0000000..b6848f9 --- /dev/null +++ b/radio/test/untitled.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# +# SPDX-License-Identifier: GPL-3.0 +# +# GNU Radio Python Flow Graph +# Title: Not titled yet +# Author: mreenen +# GNU Radio version: 3.10.1.1 + +from packaging.version import Version as StrictVersion + +if __name__ == '__main__': + import ctypes + import sys + if sys.platform.startswith('linux'): + try: + x11 = ctypes.cdll.LoadLibrary('libX11.so') + x11.XInitThreads() + except: + print("Warning: failed to XInitThreads()") + +from PyQt5 import Qt +from gnuradio import qtgui +from gnuradio.filter import firdes +import sip +from gnuradio import gr +from gnuradio.fft import window +import sys +import signal +from argparse import ArgumentParser +from gnuradio.eng_arg import eng_float, intx +from gnuradio import eng_notation +from gnuradio import soapy + + + +from gnuradio import qtgui + +class untitled(gr.top_block, Qt.QWidget): + + def __init__(self): + gr.top_block.__init__(self, "Not titled yet", catch_exceptions=True) + Qt.QWidget.__init__(self) + self.setWindowTitle("Not titled yet") + qtgui.util.check_set_qss() + try: + self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) + except: + pass + self.top_scroll_layout = Qt.QVBoxLayout() + self.setLayout(self.top_scroll_layout) + self.top_scroll = Qt.QScrollArea() + self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) + self.top_scroll_layout.addWidget(self.top_scroll) + self.top_scroll.setWidgetResizable(True) + self.top_widget = Qt.QWidget() + self.top_scroll.setWidget(self.top_widget) + self.top_layout = Qt.QVBoxLayout(self.top_widget) + self.top_grid_layout = Qt.QGridLayout() + self.top_layout.addLayout(self.top_grid_layout) + + self.settings = Qt.QSettings("GNU Radio", "untitled") + + try: + if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): + self.restoreGeometry(self.settings.value("geometry").toByteArray()) + else: + self.restoreGeometry(self.settings.value("geometry")) + except: + pass + + ################################################## + # Variables + ################################################## + self.samp_rate = samp_rate = int(1e6) + self.freq = freq = int(2.45e9) + + ################################################## + # Blocks + ################################################## + self.soapy_plutosdr_source_0 = None + dev = 'driver=plutosdr' + stream_args = '' + tune_args = [''] + settings = [''] + + self.soapy_plutosdr_source_0 = soapy.source(dev, "fc32", 1, '', + stream_args, tune_args, settings) + self.soapy_plutosdr_source_0.set_sample_rate(0, samp_rate) + self.soapy_plutosdr_source_0.set_bandwidth(0, 0.0) + self.soapy_plutosdr_source_0.set_gain_mode(0, False) + self.soapy_plutosdr_source_0.set_frequency(0, freq) + self.soapy_plutosdr_source_0.set_gain(0, min(max(20, 0.0), 73.0)) + self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c( + 1024, #size + window.WIN_BLACKMAN_hARRIS, #wintype + 0, #fc + samp_rate, #bw + "", #name + 1, + None # parent + ) + self.qtgui_freq_sink_x_0.set_update_time(0.10) + self.qtgui_freq_sink_x_0.set_y_axis(-140, 10) + self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB') + self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "") + self.qtgui_freq_sink_x_0.enable_autoscale(False) + self.qtgui_freq_sink_x_0.enable_grid(False) + self.qtgui_freq_sink_x_0.set_fft_average(1.0) + self.qtgui_freq_sink_x_0.enable_axis_labels(True) + self.qtgui_freq_sink_x_0.enable_control_panel(False) + self.qtgui_freq_sink_x_0.set_fft_window_normalized(False) + + + + labels = ['', '', '', '', '', + '', '', '', '', ''] + widths = [1, 1, 1, 1, 1, + 1, 1, 1, 1, 1] + colors = ["blue", "red", "green", "black", "cyan", + "magenta", "yellow", "dark red", "dark green", "dark blue"] + alphas = [1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0] + + for i in range(1): + if len(labels[i]) == 0: + self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i)) + else: + self.qtgui_freq_sink_x_0.set_line_label(i, labels[i]) + self.qtgui_freq_sink_x_0.set_line_width(i, widths[i]) + self.qtgui_freq_sink_x_0.set_line_color(i, colors[i]) + self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i]) + + self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.qwidget(), Qt.QWidget) + self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win) + + + ################################################## + # Connections + ################################################## + self.connect((self.soapy_plutosdr_source_0, 0), (self.qtgui_freq_sink_x_0, 0)) + + + def closeEvent(self, event): + self.settings = Qt.QSettings("GNU Radio", "untitled") + self.settings.setValue("geometry", self.saveGeometry()) + self.stop() + self.wait() + + event.accept() + + def get_samp_rate(self): + return self.samp_rate + + def set_samp_rate(self, samp_rate): + self.samp_rate = samp_rate + self.qtgui_freq_sink_x_0.set_frequency_range(0, self.samp_rate) + self.soapy_plutosdr_source_0.set_sample_rate(0, self.samp_rate) + + def get_freq(self): + return self.freq + + def set_freq(self, freq): + self.freq = freq + self.soapy_plutosdr_source_0.set_frequency(0, self.freq) + + + + +def main(top_block_cls=untitled, options=None): + + if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): + style = gr.prefs().get_string('qtgui', 'style', 'raster') + Qt.QApplication.setGraphicsSystem(style) + qapp = Qt.QApplication(sys.argv) + + tb = top_block_cls() + + tb.start() + + tb.show() + + def sig_handler(sig=None, frame=None): + tb.stop() + tb.wait() + + Qt.QApplication.quit() + + signal.signal(signal.SIGINT, sig_handler) + signal.signal(signal.SIGTERM, sig_handler) + + timer = Qt.QTimer() + timer.start(500) + timer.timeout.connect(lambda: None) + + qapp.exec_() + +if __name__ == '__main__': + main()