Scientific Computing

Wget for website link checking

Wget can check internal website links by:

wget --spider -r -nd -nv -w1 -o mysite.log https://www.yourwebsite.com

If everything is OK, near the bottom of mysite.log will be

Found no broken links


Assuming .html or .md files, search for text in files with a program like Visual Studio Code or findtext.py

findtext https://mysite.invalid "*.html"

Wget spider options:

--spider
don’t store HTML files retrieved
-nd
put output file in the current directory
-nv
non-verbose. Minimal messages output
-w1
wait 1 second between requests (don’t get banned by your own server for false scraping detection)

Related: Python internal / external website link checker

PDF text editor Linux

Master PDF Editor is free to use for non-commercial purposes, editing PDFs. You can edit text (for example, change a word), without screwing up the formatting or images like happens when you import a PDF into a word processing program.

You want the 64-bit .deb file most likely.

$2 Bluetooth Speaker technical review

FCC ID COMES-63031BT

The SoundLogic Suction MBSS-12 Bluetooth speaker sells individually for $5, and in bulk they can be purchased for $2. The speaker is comfortably audible at a distance of several meters, even outside, so it can be a nice inexpensive gift that is considerably better (louder, fuller fidelity) than a smartphone speaker. Battery life is a couple hours and it has micro-USB charging. It has a microphone with profiles for two-way headset as well as higher fidelity A2DP audio. The speaker plays nice with Linux as just about any device would these days (better than Windows in general).

$5 Bluetooth SoundLogic speaker

Maximum range for this SoundLogic Bluetooth speaker was 10-12 meters in outdoors, line-of-sight conditions with dozens of background Wifi APs at -80 to -70 dBm. The antenna is a meander-line with 2 dBi claimed gain. Given the +1dBm conducted transmit power, about +3 dBm EIRP for this speaker.

Remember that EIRP is just one piece of the pie when it comes to maximum range. I’ll assume the transceiver is well designed, -90 dBm or better RX sensitivity.

Why then is the range of this $2 bluetooth speaker so low? Because of antenna placement–on the $2 SoundLogic, the meander line antenna is jammed in right behind the buttons, and so the theoretical donut-shaped pattern with nulls off the longways ends of the antenna are complemented with nulls front and back of the speaker. I didn’t simulate it, but it would be some weird 3-D clover-leaf like pattern. This is why better Bluetooth speakers use dual antennas placed more optimally in their devices.

Fix Dell Speaker Bar with no audio

A Dell speaker bar lost audio output shortly after going out of warranty. Not thinking to check the headphone jack, I tore it apart, and of course it started working so I couldn’t trace the failure.

Then a couple days later, I lost audio again. This time I tried headphones and I had sound, and if I jiggled the headphone jack, I would get speaker audio for a bit. Then the speakers died again with only headphone audio. I suspect this new old stock part has tarnished contacts, that the insertion of the headphone does not wipe.

So what is needed is new headphone jacks, or jumper the speakers to be always on with headphones. For now I just plug in headphones.

Dell speaker bar

The little headphone jack daughterboard has 5 wires going to it

  • gnd
  • left audio
  • right audio
  • 12V
  • mute: this line is 9.6 or 5.5 volts, can’t just cut or short it.

How Paging Coasters work

Visiting a large popular museum, they handed out coaster pagers with FCC ID “QBTLTK-P1”. The pager is a 4kHz 1200 baud FSK system running on 26.995 MHz with a 2 Watt transmitter. The coasters have a loop antenna with about 2.5uV sensitivity, so perhaps 25 m range in good conditions. The relative insensitivity of such a small antenna and high pager transmit power work against the high levels of interference at the pager frequency.

I wondered why they would use such a low frequency and hence low efficiency antenna for the coaster size. Pager companies now use UHF (400+ MHz) for these coaster pagers since an efficient quarter-wavelength PCB antenna fits readily into a hand-sized pager. A decade ago there were all-in-one Samsung S1T8513A chips available that could receive up to 50 MHz. 49 MHz transmitters are at a disadvantage in the USA as the 10000 uV/m -> -15 dBm transmit power vs. 33 dBm transmit power at 27 MHz.

Paging doesn’t require frequency hopping or direct sequence spread spectrum. The system designer should pick an RF frequency band where the pager receiver antenna will be efficient for the pager size.   For coaster pagers, the UHF band is a good choice, and the friendly ~ 5000 uV/m ~ -20 dBm power limit on UHF license-free transmission under FCC Part 15.231 leads to ~100 m pager range, using simple POCSAG modulation and hence commodity chipsets.

Efficient antenna design in a pager receiver allows for the best performance for a given size. Selecting the right frequency and antenna design enables the use of license-free power levels to achieve sufficient range. Interference-free frequencies are crucial to avoid broadband noise from PCs and lighting blocking pager messages with static. 27 / 49 MHz RF frequencies are generally not a good choice for pagers, baby monitors, etc. due to interference. Pagers operating at higher frequencies, such as 150/450 MHz, can be simple, cost-effective, and provide long-range communication. The Motorola Minitor fire pagers, which can achieve over 20 km range with powerful licensed base station transmitters, typically operate in the 150 or 450 MHz bands.

27 MHz pager antenna

RC helicopter - improving maximum control range

Previously I observed 4x increased range from repairing the antenna in the RC car. I was therefore curious what could be characterized and improved for RC helicopter maximum control range. This is a $50 unit by Interactive Toys, FCC ID RSD-50800TX for the controller and RSD-50800RX for the helicopter. It’s a 2.4 GHz controller with about 3 dBm EIRP. The antennas are non-resonant. The radio system operates under FCC Part 15.249(a), allowing 114 dBμV/m @ 3m radiation ~ +18.77 dBm ~ 75 mW EIRP peak. The battery is 3.7 V 650 mAh, good for about 10-15 minutes of use. The manual states up to 6 of these helicopters can be used within line-of-sight of each other.

Controller power-on: 33% duty cycle: 200 μs FSK(?) pulse, 600 μs period on 2406 MHz.

RC control waveform paired

Paired waveform, 2408.9 MHz for RC helicopter

Pairing beacon for RC helicopter 2406 MHz

Pairing beacon for RC helicopter 2406 MHz

Power either controller or copter on first, within a second or so of both being turned on, they pair, and they go always to 2408.9 MHz, even if there is a strong WiFi signal on channel 1. The controller antenna is appalling. They take a Ruixing 2.4 GHz daughterboard, disregard its meander antenna and solder a 6.5 cm wire near the feedpoint of the meander antenna and slather the area in rubber cement. The maximum range of the RC helicopter could use some improvement, thus the experiment below.

Three things that expected to make a significant improvement (2x to 3x) in maximum RC helicopter control range:

  1. Trim about 2cm off of the controller antenna with a wire cutter
  2. Bend the Ruixing board about 0.5 cm away from the main PCB, a large groundplane
  3. The 3 cm copter antenna was bent over in a mess of other wires just like the RC car controller, which made such a significant reduction in range. I intend to glue the plastic I cut out back in to help protect the Li Ion battery. I didn’t put the antenna vertical for better coverage, and to avoid getting the antenna caught in the copter blades.

Observations: #1 and #2 made about a 4 dB increase in transmitter EIRP. From #3 expect a 6-10dB increase in copter transmitter EIRP (and in RX gain).

These devices test well under FCC power limits. From the test reports it seems the antennas were put in the ideal position. We have just restored the FCC certified performance.

Controllability problems (weak signal -> intermittent control) when more than about 30 meters slant range to the copter, which is too short for safe operations.

From Friis free space loss equation, to go from 30 m range to 100 m range should take 10.5 dB extra. Even 60 m from 30 m (6 dB change as doubling range makes 4x weaker by inverse square law) would be an improvement.

Hosim S911 2.4 GHz RC car

These $35 - $75 toys have been cropping up in the past year or so, highly capable, repairable, and hackable for the price. I was curious as why I was getting much less than the specified 100 meter range from control to car. I found some surprises and some questions as well as answers.

The control is made by Lansu, a known manufacturer of inexpensive RC servo control systems. There are two chips inside, one had illegible labeling and was connected to handheld control inputs, while the other was connected directly to the antenna with model LT8912SRC, which I could not find on the internet. There is no FCC ID that I could find anywhere on the unit, despite copious approval logos.

One leg attaches directly to a 4.5 cm wire monopole antenna. On the remote, this wire was tucked down amongst other wires instead of sticking up into the antenna pipe–probably why I was getting 20 m range instead of 100 m range! Also, for 2.4 GHz we would expect about 3cm for a monopole antenna, so we are probably fairly non-resonant, perhaps some high > 3:1 SWR affecting range.

As compared to a helicopter controller spec’d at 3dBm output power, this controller, was about 6dB stronger, so the S911 controller may be just under 10 mW EIRP. The fix was sticking the wire up from the controller. The factory tucked the antenna wire inside because the antenna pipe was in the wrong location! Some disconnect between mechanical engineering and electrical engineering departments is apparent!

Frequencies

Hosim Car Radio beacons every 49 ms at 2404.3 MHz when in pairing mode, stops transmitting until no sync heard from control (out of range or control turned off). Looks like FSK.

Hosim S911 controller at 2404.3 MHz

Hosim S911 controller at 2404.3 MHz--long time 33ms period.

Hosim S911 controller-short time 100us preamble + 1400us message

Hosim S911 controller-short time 100us preamble + 1400us message.

Hosim Controller Radio does not transmit until receiving pairing signal from car, then transmits indefinitely even without control input

Freq (MHz) length (us) cadence (ms) Function
2404.3 1400 48 car sync / pair
2404.3 1500 33 ctrl sync
2422.7  1700  4,60 ctrl
2432.7  1700  20,28 ctrl
2442.7  1700  4,13 ctrl
2452.7  1700  4,20 ctrl
2462.7  1700  4,16 ctrl
2472.7  1700  4,20 ctrl

Secret unpopulated controller switch: all it does is reverse the left-right steering, perhaps to allow for different steering potentiometers.


Related: Increase RC Helicopter range via antenna fix

Increase ulimit number of open files

Making Matplotlib/Seaborn plots in parallel executing threads in Python is one area where one may need to increase ulimit for files. That is, increase the limit for the maximum number of open files. The default maximum number of open file limits are like 1024 for Linux and 2560 for macOS.

This can lead to problems with Matplotlib like:

Too many open files: ‘/usr/share/fonts/truetype/msttcorefonts/arial.ttf’

Fix

Platform independent ulimit -n increase “ulimit_nofile.py”

Instead of one-off or sudo-requiring system parameter setting techniques, consider platform-independent Python. This does not use sudo. It instead makes temporary setting changes where feasible or at most user-profile specific system changes. This change will be only for this instance of Python; once Python terminates even the same terminal session will have the original ulimit again.

#!/usr/bin/env python
try:
    import resource as res
except ImportError: #Windows
    res = None

def raise_nofile(nofile_atleast=4096):
    """
    sets nofile soft limit to at least 4096, useful for running matlplotlib/seaborn on
    parallel executing plot generators vs. Ubuntu default ulimit -n 1024 or OS X El Captian 256
    temporary setting extinguishing with Python session.
    """
    if res is None:
        return (None,)*2
# %% (0) what is current ulimit -n setting?
    soft,ohard = res.getrlimit(res.RLIMIT_NOFILE)
    hard = ohard
# %% (1) increase limit (soft and even hard) if needed
    if soft<nofile_atleast:
        soft = nofile_atleast

        if hard<soft:
            hard = soft

        print('setting soft & hard ulimit -n {} {}'.format(soft,hard))
        try:
            res.setrlimit(res.RLIMIT_NOFILE,(soft,hard))
        except (ValueError,res.error):
            try:
               hard = soft
               print('trouble with max limit, retrying with soft,hard {},{}'.format(soft,hard))
               res.setrlimit(res.RLIMIT_NOFILE,(soft,hard))
            except Exception:
               print('failed to set ulimit, giving up')
               soft,hard = res.getrlimit(res.RLIMIT_NOFILE)

    return soft,hard


if __name__ == '__main__':
    from argparse import ArgumentParser
    p = ArgumentParser()
    p.add_argument('-n','--nofile',help='max number of open files',type=int,default=4096)
    p = p.parse_args()

    soft,hard = raise_nofile(p.nofile)
    print('ulimit -n soft,hard: {},{}'.format(soft,hard))