The Max remote receiver project described in an earlier post: https://reactivemusic.net/?p=20965 now includes support for OpenWebRx and KiwiSDR sites.
When using OpenWebRx, you need to select a “profile” that supports the receive frequency range, before you can operate within that frequency. Its an unusual system that uses an offset frequency within the selected profile, instead of a global “actual frequency” like the other platforms.
The KiwiSDR sites, in general, have very good quality reception and audio.
The next step in this project will be to consolidate a directory of sites that are useful for remote reception in the ham bands for various parts of the world.
Remote receiver project using Websdr as a remote alternative to a local receiver.
Demonstration of a Max/MSP program that connects an amateur radio transceiver to Websdr – transmitting locally from Maine (USA) while receiving remotely using a radio in the Netherlands. The Max program reads the frequency from a Elecraft K4 transceiver, to control the Websdr sites. It also loads the remote receivers, controls audio routing, mode, filter, and waterfall display settings. An iPad, running touchOSC, acts a a control panel. Up to 4 remote receivers operate at the same time. Websdr is a remarkable system, developed by PA3FWM at http://websdr.org/. It lets you control remote receivers worldwide, from your Web browser.
Components:
Max/MSP
Websdr
TouchOSC
Elecraft K4 transceiver with antenna system
Skookumlogger (logging software)
Max Patches:
websdrjweb7.maxpat : main control program. Contains [jweb] objects for launching websdr instances. Also code for injecting javascript to control parameters like frequency, filter, and volume. This patch acts as an intermediary between TouchOSC, WebSDR, and allows external MIDI control as well as getting frequency input from CAT controlled radios like the Elecraft K4.
websdrCATaudio.maxpat : handles serial port interaction for the K4. Also reads audio stream from either the K4 receiver (via USB) or the websdr receiver (via Blackhole.) I created an aggregate audio device called K4sdr to allow Max to read both devices at the same time. Audio switching and levels are handled using a Korg nanoControl2. For example to switch between the audio streams or listen to both.
Optional: arduino-ptt-detect2.maxpat : reads serial data from an Arduino, connected to the amplifier keying line, to determine whether the radio is in transmit mode, so we can switch back to the local audio stream to eliminate latency of hearing your signal via websdr. See subsequent post about this setup…
TouchOSC
websdrCW3.touchOSC : controls all 4 websdr channels, ie,., volume, mute, filter, CW offset, filtershift, – Also handles window management, loading js code, zoom in/out websdr and selecting channel waterfall views or Max code views.
CW Offset
websdr doesn’t have a control for CW pitch offset. To sync the frequency of the K4, the websdr is run in LSB mode with a frequency offset equal to the CW pitch setting in the transceiver. eg., 450 Hz. This works for most of the websdr sites, but unfortunately some of the sdr’s are off-frequency. You can usually compensate by adjusting the CWfreqOffset for that channel (in Max or TouchOSC).
Setting the offset also requires shifting the filter so it is centered over the actual signal.
Files
This is currently a work in progress, not available on Github. Local files are in max teaching examples folder.
Mapping geocoded contest log data using node.js and openlayers.
The goal was to make something that looks like the Reverse Beacon Network map, only for contest log files. I use RBN for testing antennas now. That map display gives you a pretty good idea of your actual antenna pattern.
Code is written in node.js (javascript) and html.
Part 1: Read a Cabrillo log file containing QSO: records. Look up each callsign, get latitude and longitude, and rewrite the file as json data, tagged with geo coordinates. I originally tried getting the data from hamQTH but it was not current, so ended up using the qrz.com xml callsign lookup. For callsigns “not found” I used the qrz.com dxcc prefix lookup to get general coordinates for the country. There are still a few bad/missing data issues to resolve. Like European stations with coordinates at the South Pole.
Part 2: Tried various mapping frameworks – like leaflet, arcgis, and openlayers. Wanted to use a great-circle projection (azimuthal equidistant) like the big ARRL world map. And may still figure this out. But working with map projections and coordinate transforms is way worse than doing a Smith Chart. I ended up hacking a flight tracking example from openlayers.org and basically replacing airplanes with QSO’s. That is why the lines are animated from source to destination. Also added a layer for day/night, and QSO/time status display.
It probably makes sense to get rid of the flight animation and just display the entire path in sync with the QSO data – with color code for each band (K1KP) – and speed control on the time lapse, etc., So you can get a better sense of rate and propagation.
It would be cool to have a website where you could upload a log file and generate maps.
Note: this project is not yet available
Files
local files:
generating data:
internetsensors/cabrillomap
put the cabrillo data in testdata.cbr (use QSO: records only for now) should be sorted chronologically.
run: node index.js
the output file will be: geocab.json (which is used as input to the mapping program)
mapping
internetsensors/oltest
main.js = node source with ol mapping and data processing
index.html = web page for map
geocab.json = geocoded cabrillo json test data
to run, type: npm start
Then open: http://localhost:5173/ in a browser
Additional work / current issues
Some of the qrz.com callsign data has bad geo coordinates. In particular some of the records show a latitude of -89 and longitute -179 – need to check for these numbers and replace with dxcc coordinates.
There should be an argument on the node program to pass in the datafile. Also the program should clean up any non QSO: records, like the file header info and any X-QSO recs.
Also need to clean up the async/await stuff – currently there are several methods for handling state transitions.
mapping ideas:
As mentioned above, its probably a good idea to make a version of the code without the flight animation, and have various controls to stop/start the data playback to look at individual qso’s do speed control, etc.,
azimuthal equidistant projection: there are some links to examples in leaflet, and arcgis to handle complex projections. In documents, look at: “map links for projection stuff.txt”
leaflet test version:
in the internetsensors/cabrillomap folder there’s a test file: cbworld1.html that works using websockets when you run the index.js file to generate test data. It uses a leaflet map, but the lines don’t adapt to great circle polar paths.
arcgis
I believe the arcgis examples are in internetsensors/projected geometries
And: internetsensors/pe-gs-projection
The former is a a very nice world projection with some point markers. The latter is an example that shows how to switch out various projections in realtime.
Attempts to use the X API (formerly Twitter) for projects with Max/MSP have been disappointing at best. Most of the API is behind a paywall now. The cost is $5000 per month. to implement streaming API used in projects like this: https://reactivemusic.net/?p=5786
The free tier only allows basic tweeting and user lookup. Search is not available.
I was able to find only one node example that actually worked in the free tier. By “Coding with Ado”. The code requests a token from X, and then you enter a timestamped pin number to continue. Making it worthless for programs and bots. https://youtu.be/G5ZW5j5cwHk?si=vbAtGa0bQ3T_tga9
A local copy of the source code for this is in tkzic/nodetweet3/index.js
There service sits in the middle to handle X API calls. You are charged by the number of calls. It doesn’t offer streaming either, but you can simulate it by calling a search every few seconds.
Other social media options
There are API’s for other social sites like facebook, instagram, tiktok, etc.,
In the previous version, all of the markers for each train line were deleted and redrawn in a group at the polling interval. In this version the train markers move to their new location when the data is polled.
The project uses the MBTA JSON API, to query vehicle data for each train line. the geo coordinates of the trains are sent via websockets to the client map page.
This project is a work in progress and not available yet.
Files:
node server: internetsensors/mbtanode2/index.html
html map client: internetsensors/mbtanode2/mbtatrain2.html
Instructions
// to run, type node index.js at a command line.
// then open a web browser to: http://127.0.0.1:8124/
// type 'go' into the text box below the map, and press 'send' button
// in a few seconds the train markers will magically appear
But it won’t run from that server. It only runs locally.
Instructions
Download the index.html file from the link above. start a local web server, eg., “npx http-server” and enter the server address into a Chrome browser.
When you press connect, the browser will prompt you to select a serial port for the radio. On my computer the K4 serial ports appear something like: cu2.usbserial-21100. There are 2 ports. Select either one.
Then press read. If you spin the dial on the K4, and it is autoinfo mode, you should see CAT commands in the read window.
enter a CAT command in the write window and press the write button. It is preloaded with “fa7;” which sets frequency to 7 MHz.
Sonification of Mass Ave buses, from Nubian to Harvard.
Updated for Max8 and Catalina
This patch requests data from MBTA API to get the current location of buses – using the Max js object. Latitude and Longitude data is mapped to oscillator pitch. Data is polled every 10 seconds, but it seems like the results might be more interesting to poll at a slower rate, because the updates don’t seem that frequent. And buses tend to stop a lot.
This project uses version 3 of the API. There are quality issues with the realtime data. For example, there are bus stops not associated with the route. The direction_id and stop_sequence data from the buses is often wrong. Also, buses that are not in service are not removed from the vehicle list or indicated as such.
The patch uses a [multislider] object to graph the position of the buses along the route – but due to the data problems described above, the positions don’t always reflect the current latitude/longitude coordinates or the bus stop name.
You will need to replace the API key in the message object at the top of the patch with your own key. Or you can probably just remove it. The key distributed with the patch is fake. You can request your own developer API key from MBTA. It’s free.
instructions
Open mbta.maxpat
Open the Max console window so you can see what’s happening with the data
click on the yellow [getstops] message to get the current bus stop data
Toggle the metro (at the top of the patch) to start polling
Turn on the audio (click speaker icon) and turn up the gain
Note: there will be more buses running during rush hours in Boston. Try experimenting with the polling rate and ramp length in the poly-oscillator patch. Also, you can experiment with the pitch range.
Soundcloud deleted my API credentials and is not accepting new requests. So there is really no point to using this project unless you have active credentials.
console.error() function crashes node. -fixed locally
The Soundcloud client-id is embedded in scnode.js – you will need to edit this file to replace the worthless client-id with your own. To get a client ID you will first need a Soundcloud account. Then register an app at: http://soundcloud.com/you/apps
first time instructions
Open the Max patch: sc.maxpat
In the green panel, click on [script npm init]
In the green panel , click on [script install soundcloud-api-client]
instructions
Open the Max patch sc.maxpat
open the max.console window so you can see the API data
click [script start]
click the speaker icon to start audio
type something into the search box and press <enter> or click the button to the left to search for what is already in the box.
select a track from the result menu, wait for it to start playing