-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fac1fe0
commit 4657322
Showing
116 changed files
with
18,475 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
#!/usr/bin/env python | ||
# encoding: utf-8 | ||
|
||
""" | ||
inspired by https://github.com/CodingGhost/DCF77-Transmitter | ||
reference | ||
https://en.wikipedia.org/wiki/DCF77 | ||
""" | ||
import argparse | ||
from ctypes import * | ||
import datetime | ||
import logging | ||
import os | ||
import struct | ||
from subprocess import call | ||
import tempfile | ||
|
||
logging.basicConfig() | ||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Sample(Structure): | ||
''' | ||
Helper for writing binary data to RFA file | ||
''' | ||
_fields_ = [("amplitude", c_double), ("timing", c_uint)] | ||
|
||
def __init__(self, amplitude, timing): | ||
self.amplitude = amplitude | ||
self.timing = timing | ||
|
||
|
||
class Dcf77(object): | ||
''' | ||
Utility for working dcf77 standard | ||
https://en.wikipedia.org/wiki/DCF77 | ||
''' | ||
|
||
BASE = [1, 2, 4, 8, 10, 20, 40, 80] | ||
|
||
@staticmethod | ||
def int_to_bcd(value, num_bits): | ||
""" | ||
""" | ||
bits = [] | ||
for base in reversed(Dcf77.BASE[:num_bits]): | ||
if value >= base: | ||
bits.append("1") | ||
value -= base | ||
else: | ||
bits.append("0") | ||
return "".join(reversed(bits)) | ||
|
||
@staticmethod | ||
def add_crc(value, odd=True): | ||
num = value.count("1") | ||
p = num % 2 | ||
if((p == 1) and odd) or (p == 0 and not odd): | ||
return "%s1" % value | ||
else: | ||
return "%s0" % value | ||
|
||
@classmethod | ||
def to_dcf77(cls, data): | ||
''' | ||
Convert datetime to list of bit in dcf77 encoding | ||
see https://en.wikipedia.org/wiki/DCF77 | ||
:param data: datetime.datetime | ||
''' | ||
time_code = ["0", # start of minute | ||
"11111111100000", # wheather, warnngs or other data | ||
"1", # Abnormal transmitter / backup antenna | ||
"0", # Summer time announcement | ||
] | ||
|
||
time_code.append("00") # cest and cet bit | ||
time_code.append("0") # leap second | ||
time_code.append("1") # start encoding time | ||
|
||
time_code.append(cls.add_crc(cls.int_to_bcd(data.minute, 7))) | ||
time_code.append(cls.add_crc(cls.int_to_bcd(data.hour, 6))) | ||
date = [cls.int_to_bcd(data.day, 6), ] | ||
date.append(cls.int_to_bcd(data.weekday() + 1, 3)) | ||
date.append(cls.int_to_bcd(data.month, 5)) | ||
date.append(cls.int_to_bcd(data.year - 2000, 8)) | ||
time_code.append(cls.add_crc("".join(date))) | ||
|
||
return "".join(time_code) | ||
|
||
@staticmethod | ||
def modulate(encoded, UP=32767, DOWN=0): | ||
''' | ||
dcf77 modulation | ||
1 bit per second | ||
0.1 sec down = 0 | ||
0.2 sec down = 1 | ||
1 sec up = end of second | ||
return generator of tuple returning (value, time in milliseconds) | ||
:param encoded: sequence of 01 representing message | ||
:param UP: value for 100% modulation | ||
:param DOWN: value for 15% modulation | ||
I do not know why, but 0 seems to work | ||
''' | ||
|
||
for value in encoded: | ||
|
||
if value in ("0", 0): | ||
yield (DOWN, 100000000) | ||
yield (UP, 900000000) | ||
elif value in ("1", 1): | ||
yield (DOWN, 200000000) | ||
yield (UP, 800000000) | ||
else: | ||
raise ValueError("Only 0|1") | ||
# last second no modulation | ||
yield (UP, 1000000000) | ||
|
||
|
||
if __name__ == "__main__": | ||
|
||
parser = argparse.ArgumentParser( | ||
description="Call rpitx to set dcf77 clock", | ||
epilog="default wire on GPIO 18 ( pin 12) and 5 minutes of transmission") | ||
parser.add_argument("-v", "--verbose", help="increase output verbosity", | ||
action="store_true") | ||
parser.add_argument("-4", "--gpio4", help="wire on GPIO 4 ( pin 7)", | ||
action="store_true") | ||
parser.add_argument("-n", "--nums", help="number of minutes of transmission", | ||
type=int, | ||
default=5) | ||
args = parser.parse_args() | ||
|
||
if args.verbose: | ||
logger.setLevel(logging.DEBUG) | ||
|
||
NUMS = args.nums # transmit for NUMS minutes | ||
now = datetime.datetime.now() | ||
# tolgo secondi per arrivare a inizio minuto | ||
# aggiungo 1 per arrivare a prossimo minuto | ||
# aggiungo 1 perchè ad ogni minuto, comunico il minuto dopo | ||
start = now - datetime.timedelta(microseconds=now.microsecond, # start of current minute | ||
seconds=now.second) + \ | ||
datetime.timedelta(minutes=1) # start of next minute | ||
|
||
if now.second >= 58: | ||
# not enougth time, add one more minute | ||
start = start + datetime.timedelta(minutes=1) | ||
|
||
filename = None | ||
with tempfile.NamedTemporaryFile("wb", delete=False) as f: | ||
filename = f.name | ||
|
||
for i in range(1, NUMS + 1): | ||
# i start with 1 because now whi transmit next minute ( now+1 | ||
# minute) | ||
data = start + datetime.timedelta(minutes=i) | ||
encoded = Dcf77.to_dcf77(data) | ||
|
||
logger.debug("%s -> %s", data, encoded) | ||
|
||
for amplitude, timing in Dcf77.modulate(encoded): | ||
sample = Sample(amplitude, timing) | ||
f.write(sample) | ||
logger.debug("%s, %s", amplitude, timing) | ||
|
||
print "waiting %s for syncronization..." % start | ||
while True: | ||
# whaiting for start of minute | ||
if datetime.datetime.now() >= start: | ||
break | ||
cmd = ["sudo", "./rpitx", "-m", "RFA", "-i", | ||
filename, "-f", "77.500"] | ||
if args.gpio4: | ||
cmd.extend(["-c", "1"]) | ||
logger.debug(cmd) | ||
|
||
ret = call(cmd) | ||
logger.debug("ret = %s", ret) | ||
if ret == 0: | ||
print "End of transmission, hope your clock is set." | ||
else: | ||
print "Something got wrong, check for errors" | ||
if filename is not None: | ||
os.remove(filename) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
"""Setup for rpitx.""" | ||
|
||
from setuptools import setup, Extension | ||
|
||
setup( | ||
name='rpitx', | ||
version='0.2', | ||
description='Raspyberry Pi radio transmitter', | ||
author='Brandon Skari', | ||
author_email='[email protected]', | ||
url='https://github.com/F5OEO/rpitx', | ||
ext_modules=[ | ||
Extension( | ||
'_rpitx', | ||
[ | ||
'src/RpiDma.c', | ||
'src/RpiGpio.c', | ||
'src/RpiTx.c', | ||
'src/mailbox.c', | ||
'src/python/_rpitxmodule.c', | ||
'src/raspberry_pi_revision.c', | ||
], | ||
extra_link_args=['-lrt', '-lsndfile'], | ||
), | ||
], | ||
packages=['rpitx'], | ||
package_dir={'': 'src/python'}, | ||
install_requires=[ | ||
'ffmpegwrapper==0.1-dev', | ||
'pypi-libavwrapper', | ||
], | ||
) |
Submodule csdr
added at
69bfc6
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#!/bin/sh | ||
|
||
status="0" | ||
OUTPUT_FREQ=434.0 | ||
LAST_ITEM="0 Tune" | ||
do_freq_setup() | ||
{ | ||
|
||
if FREQ=$(whiptail --inputbox "Choose output Frequency (in MHz) Default is 434 MHz" 8 78 $OUTPUT_FREQ --title "Rpitx transmit Frequency" 3>&1 1>&2 2>&3); then | ||
OUTPUT_FREQ=$FREQ | ||
fi | ||
|
||
} | ||
|
||
do_stop_transmit() | ||
{ | ||
sudo killall tune 2>/dev/null | ||
sudo killall pichirp 2>/dev/null | ||
sudo killall spectrumpaint 2>/dev/null | ||
sudo killall pifmrds 2>/dev/null | ||
sudo killall sendiq 2>/dev/null | ||
sudo killall pocsag 2>/dev/null | ||
sudo killall piopera 2>/dev/null | ||
sudo killall rpitx 2>/dev/null | ||
sudo killall freedv 2>/dev/null | ||
sudo killall pisstv 2>/dev/null | ||
sudo killall csdr 2>/dev/null | ||
sudo killall pirtty 2>/dev/null | ||
|
||
case "$menuchoice" in | ||
|
||
0\ *) sudo killall testvfo.sh >/dev/null 2>/dev/null ;; | ||
1\ *) sudo killall testvfo.sh >/dev/null 2>/dev/null ;; | ||
2\ *) sudo killall testspectrum.sh >/dev/null 2>/dev/null ;; | ||
3\ *) sudo killall snap2spectrum.sh >/dev/null 2>/dev/null ;; | ||
4\ *) sudo killall testfmrds.sh >/dev/null 2>/dev/null ;; | ||
5\ *) sudo killall testnfm.sh >/dev/null 2>/dev/null ;; | ||
6\ *) sudo killall testssb.sh >/dev/null 2>/dev/null ;; | ||
7\ *) sudo killall testam.sh >/dev/null 2>/dev/null ;; | ||
8\ *) sudo killall testfreedv.sh >/dev/null 2>/dev/null ;; | ||
9\ *) sudo killall testsstv.sh >/dev/null 2>/dev/null ;; | ||
10\ *) sudo killall testpocsag.sh >/dev/null 2>/dev/null ;; | ||
11\ *) sudo killall testopera.sh >/dev/null 2>/dev/null ;; | ||
12\ *) sudo killall testrtty.sh >/dev/null 2>/dev/null ;; | ||
|
||
esac | ||
} | ||
|
||
do_status() | ||
{ | ||
LAST_ITEM="$menuchoice" | ||
whiptail --title "Transmit ""$LAST_ITEM"" on ""$OUTPUT_FREQ"" MHz" --msgbox "Transmitting" 8 78 | ||
do_stop_transmit | ||
} | ||
|
||
|
||
do_freq_setup | ||
|
||
while [ "$status" -eq 0 ] | ||
do | ||
|
||
menuchoice=$(whiptail --default-item "$LAST_ITEM" --title "Rpitx on ""$OUTPUT_FREQ"" MHz" --menu "Range frequency : 50kHz-1GHz. Choose your test" 20 82 12 \ | ||
"F Set frequency" "Modify frequency (actual $OUTPUT_FREQ MHz)" \ | ||
"0 Tune" "Carrier" \ | ||
"1 Chirp" "Moving carrier" \ | ||
"2 Spectrum" "Spectrum painting" \ | ||
"3 RfMyFace" "Snap with Raspicam and RF paint" \ | ||
"4 FmRds" "Broadcast modulation with RDS" \ | ||
"5 NFM" "Narrow band FM" \ | ||
"6 SSB" "Upper Side Band modulation" \ | ||
"7 AM" "Amplitude Modulation (Poor quality)" \ | ||
"8 FreeDV" "Digital voice mode 800XA" \ | ||
"9 SSTV" "Pattern picture" \ | ||
"10 Pocsag" "Pager message" \ | ||
"11 Opera" "Like morse but need Opera decoder" \ | ||
"12 RTTY" "Radioteletype" \ | ||
3>&2 2>&1 1>&3) | ||
RET=$? | ||
if [ $RET -eq 1 ]; then | ||
exit 0 | ||
elif [ $RET -eq 0 ]; then | ||
case "$menuchoice" in | ||
F\ *) do_freq_setup ;; | ||
0\ *) "./testvfo.sh" "$OUTPUT_FREQ""e6" >/dev/null 2>/dev/null & | ||
do_status;; | ||
1\ *) "./testchirp.sh" "$OUTPUT_FREQ""e6" >/dev/null 2>/dev/null & | ||
do_status;; | ||
2\ *) "./testspectrum.sh" "$OUTPUT_FREQ""e6" >/dev/null 2>/dev/null & | ||
do_status;; | ||
3\ *) "./snap2spectrum.sh" "$OUTPUT_FREQ""e6" >/dev/null 2>/dev/null & | ||
do_status;; | ||
4\ *) "./testfmrds.sh" "$OUTPUT_FREQ" >/dev/null 2>/dev/null & | ||
do_status;; | ||
5\ *) "./testnfm.sh" "$OUTPUT_FREQ""e3" >/dev/null 2>/dev/null & | ||
do_status;; | ||
6\ *) "./testssb.sh" "$OUTPUT_FREQ""e6" >/dev/null 2>/dev/null & | ||
do_status;; | ||
7\ *) "./testam.sh" "$OUTPUT_FREQ""e3" >/dev/null 2>/dev/null & | ||
do_status;; | ||
8\ *) "./testfreedv.sh" "$OUTPUT_FREQ""e6" >/dev/null 2>/dev/null & | ||
do_status;; | ||
9\ *) "./testsstv.sh" "$OUTPUT_FREQ""e6">/dev/null 2>/dev/null & | ||
do_status;; | ||
10\ *) "./testpocsag.sh" "$OUTPUT_FREQ""e6">/dev/null 2>/dev/null & | ||
do_status;; | ||
11\ *) "./testopera.sh" "$OUTPUT_FREQ""e6">/dev/null 2>/dev/null & | ||
do_status;; | ||
12\ *) "./testrtty.sh" "$OUTPUT_FREQ""e6">/dev/null 2>/dev/null & | ||
do_status;; | ||
*) status=1 | ||
whiptail --title "Bye bye" --msgbox "Thx for using rpitx" 8 78 | ||
;; | ||
esac | ||
else | ||
exit 1 | ||
fi | ||
done | ||
exit 0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import socket | ||
import os | ||
fifo_path = "rds_ctl" | ||
if not os.path.exists(fifo_path): os.mkfifo(fifo_path) | ||
server_ip = "0.0.0.0" # Change this to the appropriate IP address | ||
server_port = 9997 # Change this to the appropriate port | ||
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | ||
server.bind((server_ip, server_port)) | ||
server.listen(1) | ||
print("R27 NRDSOS 1.1 (THIS IS A INTERNAL APP USED IN R27'S INTERNAL RDS SERVICE)") | ||
print("Listening for incoming connections...") | ||
while True: | ||
client, client_address = server.accept() | ||
print(f"Connection from {client_address}") | ||
while True: | ||
try: | ||
# Read data from the client | ||
data = client.recv(1024).decode('utf-8') | ||
if data: | ||
print(f"Received: {data}") | ||
with open(fifo_path, "w") as fifo: fifo.write(data) | ||
except Exception as e: | ||
print(f"Error: {e}") | ||
break | ||
server.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/bin/sh | ||
|
||
echo "FREQ_IN=value-in_MHz GAIN=value-0_to_45 FREQ_OUT=value-in_MHz fm2ssb" | ||
rtl_fm -f "$FREQ_IN" -s 250k -r 48k -g "$GAIN" - | csdr convert_i16_f \ | ||
| csdr fir_interpolate_cc 2 | csdr dsb_fc \ | ||
| csdr bandpass_fir_fft_cc 0.002 0.06 0.01 | csdr fastagc_ff | buffer \ | ||
| sudo ./sendiq -i /dev/stdin -s 96000 -f "$FREQ_OUT" -t float | ||
# | sox -traw -r48k -es -b16 - -c1 -r 48k -traw - |
Oops, something went wrong.