GoJimmyPi
Monday, July 5, 2021
Find gojimmypi at gojimmypi.github.io
Sunday, March 21, 2021
Migration from BlogSpot to GitHub Pages
As convenient as blogger.com marginally is... I've decided enough is enough with the wonky editing, complete lack of integrated source control, and always that little bit of nagging wonder if one day google will just pull the plug and decommission it.
It was several years ago I tried to migrate to my GitHub Pages site at gojimmypi.github.io. Although I consider myself rather persistent, I ended up giving up at the time due to unreconcilable issues with Jekyll. (which admittedly were not supposed to be supported in Windows, and WSL was still somewhat new).
Fast forward a few years and WOW! My Jekyll install experience was nearly trouble free.
So ok, once Jekyll is working, there's still the tiny little issue of templates. I found one I liked from jekyllthemes.io, specifically the gridster-jekyll-theme. Alas nothing is ever as easy as it is supposed to be. Of course, if it is too easy, it is no fun, eh? So the issue with this particular theme, is not only that it is old, but there are a few quirky things that need to be fixed. There are literally hundreds of forks. Which one might be of interest?
How about looking at which fork has the most likes? Unfortunately, there's no such feature on GutHub, but stackoverflow to the rescue once again. There was only one answer to the question "How to find the best changes from downstream Github forks?" and it didn't sound promising with the comment "It's 3 years old, I can't seem to get it working, but someone could fork it" - but find_forks does work!
cd /mnt/c/workspace/
git clone https://github.com/elimohl/find_forks.git
cd find_forks
pip3 install tqdm
pip3 install pygithub
./find_forks.py DigitalMindCH/gridster-jekyll-theme
It should output something list this:
# usage: find_forks.py [-h] [-u USERNAME] [-p [PASSWORD]] [-s SLEEP_INTERVAL] repo_name
0 $ ./find_forks.py DigitalMindCH/gridster-jekyll-theme
95%|| 197/208 [02:23 00:08, 1.37it/s]Forks Stars
https://github.com/pcesar65/renameme 1
https://github.com/tomer-ben-david/techblog 1
https://github.com/cristinafsanz/paintings 1
https://github.com/zirkc/appworms 0
https://github.com/bullwinkle-org/gridster-jekyll-theme 0
https://github.com/jfcorugedo/jfcorugedo.github.io 0
https://github.com/tanaphum/gridster-jekyll-theme 0
https://github.com/librarywon/librarywon.github.io 0
...
There's also brute-force method to call the GitHub API:
curl https://api.github.com/repos/DigitalMindCH/gridster-jekyll-theme/forks?sort=watchers
But that's only so useful.
So what about the most changes in a fork? I found forkizard, but nothing happened after the scan. I noticed an open issue and fortunately a PR to fix it! So the one to use is at the trufanov-nok/forkizard fork. I also created my own fork, just in case it ever gets deleted, as this could be really handy again in the future. It works really quite well:# The source code is in Go. After this operation, 324 MB of additional disk space will be used:
sudo apt-get install golang-go
git clone https://github.com/trufanov-nok/forkizard.git
go build
Run it like this:
0 $ ./forkizard "DigitalMindCH/gridster-jekyll-theme"
2021/03/21 13:14:55 208 forks
208 / 208 [============================================================] 100.00% 1m26s
done
/AwarenessOverload/AwarenessOverload +388 -0
/vikasksrivastava/gridster-jekyll-theme +293 -0
/BrunnaRosa/BrunnaRosa +227 -0
/ickc/gridster-jekyll-theme +138 -0
/NNUP/nnup.github.io +92 -0
/cett/cett.github.io +68 -0
/samyak45/Gridster +66 -0
/UntrustableRus/gridster-jekyll-theme +53 -0
/guriosam/ajudamaceio +43 -0
/thiagohersan-jekyll/gridster-jekyll-theme-simple +43 -0
I ended up choosing the ickc/gridster-jekyll-theme with a demo at ickc.github.io/gridster-jekyll-theme (my fork is located here) I have it installed to a subdirectory in my GitHub.io page like this:cd /mnt/c/workspace/gojimmypi.github.io
# the repo is over 200MB in size!
git clone https://github.com/gojimmypi/gridster-jekyll-theme.git --depth 1
cd gridster-jekyll-theme
bundle install
bundle update github-pages
bundle exec jekyll serve
The author was also kind in digging up the documentation from the wayback machine, and included it as part of the theme.
Saturday, February 27, 2021
Dual WAN OpenVPN with EdgeRouter X or RT-AX86U
This a blog about NordVPN (and networking setup in general) for the Ubiquiti EdgeRouter X. If you are interested in this topic, then you may also be interested in my notes on the Pi-Hole ad blocker.
WARNING: Before configuring your router, be sure to read until the end. TL;DR - config does not survive a reboot. This blog is a work in progress.
I have poor internet bandwidth even after load balancing two different providers. One problem I see is that once a connection is established with basic load balancing the connection is "stuck" on one ISP. So when available bandwidth drops to almost nothing, the same connection continues to be used.
I was hoping to perhaps setup a virtual tunnel using the dual WAN connections to an OpenVPN provider. That way the VPN server would aggregate the two channels and only appear to have a single public-facing IP address. Fortunately I had this idea while NordVPN was having a birthday party sale!
Download Filezilla, the EdgeOS OS User Guide, the latest EdgeRouter X Firmware, and of course putty. If things get dire, the Jounin Tftpd64 server works well. (See EdgeRouter - TFTP Recovery)
It is probably best to start with the most recent firmware image. The version used here is v2.0.9-hotfix.1. Other downloads can be found at the EdgeRouter-X download site.
Note that for a freshly factory-reset EdgeRouter, no DHCP is available so a static IP address is needed; the web GUI can be found at http://192.168.1.1/ on Eth0.
Connect via putty to the serial port. 57600, 8N1:
For a brief time, the UART TTY will allow the bootloader update from something other than flash. This is vastly simpler than the convoluted power / hold-the-reset button method:
Please choose the operation:
1: Load system code to SDRAM via TFTP.
2: Load system code then write to Flash via TFTP.
3: Boot system code via Flash (default).
4: Entr boot command line interface.
7: Load Boot Loader code then write to Flash via Serial.
9: Load Boot Loader code then write to Flash via TFTP.
r: Start TFTP recovery.
default: 3
This command will "soft" factory reset (actually just configuration reset) the router:
sudo cp /opt/vyatta/etc/config.boot.default /config/config.boot
reboot
ip route
command after a fresh basic config looks like this:default via 192.168.37.254 dev eth0 proto zebra
192.168.37.0/24 dev eth0 proto kernel scope link src 192.168.37.81
192.168.170.0/24 dev switch0 proto kernel scope link src 192.168.170.1
See the detailed EdgeRouter and Ubiquiti setup with NordVPN.
The nano editor can also be installed:.
configure
set system package repository stretch components 'main contrib non-free'
set system package repository stretch distribution stretch
set system package repository stretch url http://http.us.debian.org/debian
commit
save
exit
# DO NOT RUN UPGRADE, (unless you want to break the EdgeRouter dependencies)
sudo apt-get update
sudo apt-get install nano
#
sudo rm -R /var/lib/apt/lists
sudo rm -R /var/cache/apt/archives
# optional: put back the empty directies as we should have found them
sudo mkdir /var/lib/apt/lists/partial
sudo echo "" | sudo tee /var/cache/apt/archives/lock
sudo mkdir /var/cache/apt/archives/partial
To configure the OpenVPN service, open an ssh connection or use the TTY described above:
sudo -i
cd /config/
mkdir -p openvpn
chmod 770 openvpn
Copy your nordvpn ovpn (the ca1098 example used here is this file) and nordvpnauth.txt
(service username on line 1, password on line 2) files to the /config/openvpn
with FileZilla.
Note that resetting your password on the ndaccount page will NOT close VPN connections. It should log you out of web sites, but I saw my VPN connection stay open after a password change.If you are debugging and want to see VPN logs, add the this line to your ovpn file:
log /config/openvpn/vpn.log
You will now be generating connection logs which can be found in that directory, open them using this command through SSH:
cat /config/openvpn/vpn.log
(That's one of the many tips I received from NordVPN support; they are awesome) After copying the two files onto the EdgeRouter, apply proper permissions:
sudo chmod 600 /config/openvpn/vpn.log
sudo chmod 600 /config/openvpn/nordvpnauth.txt
# edit for your specific file name:
sudo chmod 600 /config/openvpn/ca1098.nordvpn.com.udp.ovpn
Note that when doing a "soft" factory reset, step above such as the nano install, vpn directories, and copied files are retained.
ca1098.nordvpn.com.udp.ovpn
for your own server for best performance, as well as your local desired network addresses) and configure as shown below:
configure
# Download Server file recommended by NordVPN from:
#
# https://nordvpn.com/servers/tools/
#
# Edit the next line and for your file name:
set interfaces openvpn vtun0 config-file /config/openvpn/ca1098.nordvpn.com.udp.ovpn
set interfaces openvpn vtun0 description 'OpenVPN VPN tunnel'
commit
# rule 5000 and 5002 are defaults for WAN1/WAN2
# so we will usee 5100 instead of the NoprnVPN tutorial 5000
set service nat rule 5100 description 'OpenVPN Clients'
set service nat rule 5100 log disable
set service nat rule 5100 outbound-interface vtun0
set service nat rule 5100 source address 192.168.170.0/24
set service nat rule 5100 type masquerade
commit
# we'll route all protocols for all addresses on vtun0
set protocols static table 1 interface-route 0.0.0.0/0 next-hop-interface vtun0
# each network segment (e.g. eth2, eth3, eth4, switch0) will need rules
set firewall modify SOURCE_ROUTE rule 10 description 'traffic from 192.168.170.0/24 to vtun0'
set firewall modify SOURCE_ROUTE rule 10 source address 192.168.170.0/24
set firewall modify SOURCE_ROUTE rule 10 modify table 1
# here we assume Eth0 and Eth1 are WAN ports connected to ISP
# physical ports connected to ISP are what the tunnel travels on
# the remainder of the ports, eth2, eth3, eth4 and switch zero are all routed to vtun0
set interfaces switch switch0 firewall in modify SOURCE_ROUTE
set interfaces ethernet eth2 firewall in modify SOURCE_ROUTE
set interfaces ethernet eth3 firewall in modify SOURCE_ROUTE
set interfaces ethernet eth4 firewall in modify SOURCE_ROUTE
# reminder that if there's a local DNS such as a Pi-Hole on a different network segment,
# it will NOT be reachable.
commit
save
That's it! Right? Well sorta. Um, actually no. Visit https://nord-help.com/ and confirm the top of the page shows the text "Protected":To see your actual ISP address on the EdgeRouter from commandline (thanks stackoverflow for sed tip):
curl -v --silent https://www.ipchicken.com 2>&1 | grep -A 1 "Address:" \
| sed -e 's/<[^>]*>//g'
cli-shell-api --show-commands --show-cfg1 /dev/null --show-cfg2 /config/config.boot showConfig
#!/bin/vbash
# Restart OPENVPN Tunnel
VTUN="vtun0"
if [ -f "/var/run/openvpn-$VTUN.pid" ]; then
sudo kill $(cat "/var/run/openvpn-$VTUN.pid")
echo $(cat "/var/run/openvpn-$VTUN.pid")
fi
sudo /usr/sbin/openvpn --daemon --verb 3 --writepid /var/run/openvpn-$VTUN.pid \
--status /var/run/openvpn/status/$VTUN.status 30 \
--config /config/user-data/openvpn/nordvpn.ovpn \
--dev-type tun --dev $VTUN
ls -l /var/run/openvpn*.pid
# To reset the VPN connection
sudo systemctl stop openvpn.service
sudo systemctl start openvpn.service
sudo systemctl status openvpn.service
Simply resetting the VPN connection after reboot does not resolve the problem. It seems to still be a routing problem.
The
ip address
command can be used to see what IP addresses are assigned, and which ports are active on the EdgeRouter. Using the ip route
command, you should see something like this. Here 192.168.2.x is the WAN network; 192.168.170.x is the EdgeRouter:
0.0.0.0/24 dev vtun0 proto kernel scope link
default via 192.168.2.254 dev eth0 proto zebra
10.8.3.0/24 dev vtun0 proto kernel scope link src 10.8.3.7
192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.81
192.168.170.0/24 dev switch0 proto kernel scope link src 192.168.170.1
Active: inactive (dead)
here:
ubnt@EdgeRouter-X-5-Port:~$ sudo systemctl status openvpn.service
* openvpn.service - OpenVPN service
Loaded: loaded (/lib/systemd/system/openvpn.service; disabled; vendor preset:
Active: inactive (dead)
It seems that after a period of inactivity, perhaps the connection is closed, but once more internet activity is seen, the conection is re=established:
ubnt@EdgeRouter-X-5-Port:~$ sudo systemctl status openvpn.service
* openvpn.service - OpenVPN service
Loaded: loaded (/lib/systemd/system/openvpn.service; disabled; vendor preset:
Active: active (exited) since Sun 2021-02-28 20:06:13 UTC; 32s ago
Process: 4709 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 4709 (code=exited, status=0/SUCCESS)
One method I found to re-establish a TCP/IP link to the EdgeRouter after the VPN config and reboot is to delete and recreate the interface as described here:
configure
delete interfaces ethernet eth3
set interfaces ethernet eth3 address 192.168.173.1/24
commit ; save
The above configuration commands will setup a routed segment on
Eth3
(the second port from the right, next to the PoE one). Assign a manual IP address such as 192.168.173.23 to a PC with manual DNS, and now we are back to having an operational port! This also survives a reboot! Visit your local https://192.168.170.1 to see the EdgeOS web GUI.
configure
set service dhcp-server disabled false
set service dhcp-server shared-network-name LAN1 authoritative enable
set service dhcp-server shared-network-name LAN1 subnet 192.168.173.0/24 default-router 192.168.173.1
set service dhcp-server shared-network-name LAN1 subnet 192.168.173.0/24 dns-server 192.168.173.1
set service dhcp-server shared-network-name LAN1 subnet 192.168.173.0/24 lease 86400
set service dhcp-server shared-network-name LAN1 subnet 192.168.173.0/24 start 192.168.173.38 stop 192.168.173.243
commit ; save
log /config/openvpn/vpn.log
Note that if you are using a Raspberry Pi for ad-blocking DNS with the Pi-Hole, (see also my prior blog) then that RPi needs to be separately setup to use the VPN. See http://dnsleaktest.com/
The RT-AX86U:
With some of the problems I saw with the EdgeRouter, I thought I'd try a different router. There's an online Web GUI simulator to test drive some of the Asus features in the firmware UI without actually having your own router.
I tried ASUS AX5700 WiFi 6 Gaming Router (RT-AX86U) as it supports dual WAN, however neither of my ISP devices is LACP-IEEE 802.3ad capable, which is required for ASUS WAN bonded aggregation. Yes, I tried it anyhow, and the performance was unusably poor.
Additionally, despite having a UI to setup OpenVPN and appearance of it being successfully connected to VPN server, it was not actually being used:
I tried contacting Asus support. My first email was bounced back "mailbox full".
Asus support via a web form was not very helpful. In fact, their response claimed to be "confidential and not for publication". I did not agree to a non-disclosure agreement with them, nor does their web page indicate the support response is confidential:
The folks at NordVPN are considerably more helpful and cooperative. They did confirm that sometimes traffic is not routed though OpenVPN connection, even though it is up! This is completely unacceptable. I bought the RT-AX86U specifically as it was on the recommended list of NordVPN routers. I plan to return the router. Not worth $250 to me.
Unlike Asus, NordVPN has no such "confidentiality" in their tech support. So I will share this informative message from their helpful support staff:
If you want a router that is an out-of-the-box solution for NordVPN provided security and anonymity, you should head over to our partners at https://nordvpn.com/flashrouters/ . They will provide you with a preconfigured router that will deliver top-notch security and performance.
You can also buy a router and configure it yourself. We usually recommend these routers for simple home usage and if you do not require much performance (up to 10-40Mbps respectively): Asus RT-N18U, Asus RT-AC66U, Asus RT-AC68U, Asus RT-AC87U, Asus RT-AC3200.
Please note, that while you can get many different routers from other manufacturers, we strongly recommend getting an Asus router, as it has a built-in OpenVPN client on it default firmware and requires minimal effort to set up. Most other routers require firmware flashing, which might be a troublesome procedure and is not supported on all platforms.
You can also acquire any router that supports custom firmware:
DD-WRT: https://www.dd-wrt.com/wiki/index.php/Supported_Devices
Tomato: http://tomato.groov.pl/?page_id=69
Padavan: https://wikidevi.com/wiki/List_of_Padavan_firmware_supported_devices
OpenWRT: https://wiki.openwrt.org/toh/start
Merlin: https://github.com/RMerl/asuswrt-merlin/wiki/Supported-Devices
If you want a router that provides the best performance possible (in best case scenario up to 60Mbps), please look at these ones:
Asus: RT-AC66U B1, RT-AC68U, RT-AC86U, RT-AX3000, RT-AX82U, RT-AX86U, RT-AX88U, RT-AC5300
D-Link (Would need to be flashed with DD-WRT): DIR-885L, DIR-895L
Linksys (Would need to be flashed with DD-WRT): EA8500, WRT1900ACS, WRT3200ACM
Netgear (Would need to be flashed with DD-WRT): R7500, R7800, R8500, R9000
See also:
EdgeRouter and Ubiquiti setup with NordVPN
Install OVPN on an Edgerouter (EdgeOS)
Script to periodically reset an OpenVPN tunnel for NordVPN to the fastest server on Ubiquiti EdgeRouters
EdgeRouter - WAN Load-Balancing
EdgeRouter - Interface Bonding
How to check the version of OpenVPN on an AsusWRT-running router
How to Set Up VPN on Asus Router
[WAN] How to enable WAN Aggregation on ASUS Router?
[WAN] Dual WAN introduction and setup
Force Reconnect OpenVPN client connections (commandline) on EdgeOS
Sunday, December 20, 2020
iCE40 FPGA Programming with WSL and Open Source Tools
Here are some notes on programming the Lattice Semiconductor iCE40 FPGA chip.
This is supplementary information to the awesome learn-fpga walk-through by @BrunoLevy01 that I worked on a couple of weekends ago, specifically the IceStick Tutorial, but for Windows and WSL instead of Linux.
The default Windows drivers are FTDIBUS. Unfortunately this driver will typically NOT work to program the iCE40. If later changed with Zadig, they can be returned to the Windows default by right-clicking on the item in Device Manager and selecting "Update Driver". Choosing "Search Automatically for Driver" should assign the default FTDIBUS drivers. (either that, or just wait for Windows to arbitrarily change it back when you least expected it)
It may be best to start with plugging the device directly into the computer, rather than using a hub. Sometimes there are "issues".
To program the iCE40 with iceprog
assign the libusbK drivers with Zadig:
Oddly, I found that I needed to assign the libusbK drivers to BOTH Interface 0 and Interface 1 in order to be able to successfully program the iCE40. Further, not only did the drivers need to be installed on both interfaces, but after doing so - I had to unplug (wait a few seconds) and plug in the device for successful programming when the drivers were first changed.
The drivers will almost certainly revert back to the FTDI default at Windows update time, and perhaps arbitrary other times as well.
It seems that the WinUSB drivers also work for successful programming.
Note that nether the libusbK nor the WinUSB drivers will show up as a COM port in Windows, so no TTY connection with something like putty.Program only on the first interface:
iceprog.exe -I A femtosoc.bin
Attempting to program on the second interface gets stuck here at the erase step:
$ /mnt/c/Users/gojimmypi/.icestudio/apio/packages/toolchain-ice40/bin/iceprog.exe -I A femtosoc.bin
init..
cdone: high
reset..
cdone: low
init..
cdone: high
reset..
cdone: high
Extended Device String Length is 0xFF, this is likely a read error. Ignorig...
flash ID: 0xFF 0xFF 0xFF 0xFF
file size: 32220
erase 64kB sector at 0x000000..
iceprog
cannot find the USB device:
0 $ /mnt/c/Users/gojimmypi/.icestudio/apio/packages/toolchain-ice40/bin/iceprog.exe -I A femtosoc.bin
init..
Can't find iCE FTDI USB device (vendor_id 0x0403, device_id 0x6010 or 0x6014).
ABORT.
If Zadig was used to assign the USBSER driver, the above step may not work. Assign it to something else (recommended libusbK) and then try again.
WinUSB devices show up here in Device Manager:
Changing Interface 1 appears to also change Interface 0. However the reverse is not true. Thus it is best to assign drivers to Interface 1 first.
Reminder: When assigning new drivers, it is usually best to unplug and re-plug the iCE40 stick after drivers are changed with Zadig, otherwise iceprog
may fail.
Note that for a "real" Ubuntu - in this case on a VM on a Windows host, the iCEStick shows up as 3 devices, no fussing with Zadig or anything else:
Here, the make terminal just works:
I was unable to persuade WSL, with any sort of Zadig drivers, to recognize the iCEStick in terminal mode. If it was a plain TTY terminal, it might have worked, but since I am using WSL1 and the target is /dev/ttyUSB1 - I don't this this would ever work on WSL1. Perhaps with WSL2 native USB support?
Monday, November 9, 2020
GOES17 Satellite Image Reception with Nooelec Kit and Raspberry Pi
These are my (admittedly sometimes long and rambling) thoughts and more of a "review" of my recent purchase. I'm planning a second blog with just the details on setting up. Stay tuned.
My first "full disk" image was pulled from the GOES-17 Satellite on November 8!
I've been wanting to learn about satellite reception and SDR signal processing for quite some time. I have pretty much zero experience here. I've never even owned a TV satellite dish. This is certainly not my first SDR product from Nooelec. I first received their NESDR Smart RTL-SDR as a birthday present several years ago, and really enjoyed setting up OpenWRT on EA3500 with RTL-SDR Stream.
I was inspired to buy the Nooelec kit on Amazon after reading about it on the RTL SDR blog, in particular the quite excellent online tutorial on GOES 16/17 Weather Satellite Reception. This was somewhat of a gamble, as I bought mine before any of the reviews on Amazon. (there are now several 5 star reviews!)
I first tried 137.2W GOES-S (GOES-17).
See also the reddit PSA PSA: What you need to know about GOES-13:
The hardware and software requirements for successful GOES-13 decoding are completely different from GOES-16/17 and all other L-Band geostationary weather satellites, do not expect the same setup that works for LRIT/HRIT to work with GOES-13
Update: The USRADIOGUY GOES Satellite Imagery Reception is a great place for info, that would have been quite helpful had I known about it when I started.
Note that if you go looking for those PDF files at the end in the resources section, they are no longer available. I contacted NOAA support and they responded within 24 hours and even included the files! I submitted an upstream PR, but it looks like there has not been much activity recently. I have a copy in my WIP GOES-Setup docs.
When the kit arrived, I thought the dish was all one piece, as it arrived in one of the biggest Amazon boxes I've ever received. Is the box half full or half empty? I think it is twice as big as it needs to be, just the right size for two of them:
The out-of-box experience was a bit frustrating. There was pretty much no documentation included on assembly or operation. The only thing included was a thank-you card with a link to start.nesdr.com which as of the time if this writing, just redirected to nooelec.com/store/qs with nothing more than basic information on how install the drivers.
Update: there's now a helpful Set-Up Instructions page on the Nooelec site, and they've added a setup picture on the Amazon product page:
The "driver download" is actually just an old (Version 2.3 from 2017) of Zadig, not actually the drivers. The Nooelec web site was also annoying, as well: Google Chrome would do this annoying oscillation when hovering over the little question mark icons to view the pictures. It was exceptionally frustrating to just view the web picture. Within 24 hours of my message to support, the Nooelec folks fixed that!
In any case, there's not much to do in Windows anyhow, as the XRIT Decoder for GOES Satellite is another $125, as noted on Twitter; note in particular the link to A minimal LRIT/HRIT receiver. But I wanted to at least see if everything was working in Windows.
Nooelec has several SAWbird Low Noise Amplifiers ("LNA") for NOAA, the iridium and Inmarsat and other satellites, but the one shipped in this kit was the GOES flavor with a 1688 MHz Center Frequency: specifically the "premium" version with an aluminum enclosure. Note there's another bare board version.
The kit ships with a USB to power adapter. I had no idea if I am supposed to use it or not, as their web site claims:
"Each module allows for 3 different power options, but you should only power with one option at any given time! The recommended power input through the SMA output port (for bias-tee capable SDRs like the NESDR SMArTee XTR) is 3V-5V DC".
As the NESDR SMArTee XTR was also part of the kit, I assumed the power adapter is superfluous. However the web site also states "Our recommendation is the NESDR SMArTee XTR v2, which contains a bias-tee capable of powering the SAWbird GOES module with bias power". Not a single one of the nesdr xtr items made any mention of a "V2". There's one that looks similar, a Nooelec NESDR SMArt XTR SDR - Premium RTL-SDR w/ Extended Tuning Range, Aluminum Enclosure, 0.5PPM TCXO, SMA Input and another that looks exactly the same, but is labeled as Nooelec NESDR SMArTee XTR SDR - Premium RTL-SDR w/ Extended Tuning Range, Aluminum Enclosure, Bias Tee, 0.5PPM TCXO, SMA Input. (note that it mentions the "bias tee") I'm hoping the Amazon description of "The NESDR SMArTee XTR SDR unit will automatically feed the LNA through a built-in always-on Bias-T" is accurate and this will actually power the SAWbird.
Update: yes, it does! The power adapter is not needed; it's a bonus!
"There is no need to use the external power option. We opted to include the cable as it allows for easier use for customers who might want to use a different SDR for decoding than what came in the bundle" -- Nooelec Support
The SAWbird was initially equally frustrating; an SMA connector on each end with absolutely no indication of which end is input and which is output.
Update: Apparently somehow my SAWbird snuck through QA missing the silkscreen (perhaps that makes it a Collector's Edition?)
There's a poor quality picture on the Nooelec site that shows the bare board version has the input on the USB-side of the device:
Either use low loss coax cable or a USB extension cable to get the LNA and/or RTL-SDR out to the antenna. ... We strongly recommend using as little coax as possible after the LNA too. The SAWbird LNA doesn't have enough gain to push the signal through long runs of coax. If you're forced to use long runs of coax, use a secondary LNA. Preferably use a USB extension cable to reduce coax runs
"The snipped of text from the blog website you quoted is lacking a bit in detail. As general advice (for which it was intended) it's appropriate. However, the details matter. The required level of gain from the 1st & 2nd stage amplification on the SAWbird LNA will be contingent on the signal strength from the antenna (which is higher from our custom mesh than most normal installations). Further, it assumes a lossy cable (most people at best use RG58, which has insertion loss 4x higher than the included LMR400). Without getting into all the finer details, for most installations there will be about 10dB of headroom from the SAWbird before issues should start to crop up that might require a secondary LNA. That would be about 150' or more of LMR400 :) There should be zero difference if you try to decode at the output of the SAWbird vs. after the LMR400 included other than the gain on the SDR which would be more than sufficient to compensate for it. What matters more is the noise figure, which is dominated by the signal chain at and before the first LNA in the SAWbird. That is why we use high quality LMR400 on the antenna as well, and why that length is short, and why we mention it is crucial to keep the SAWbird as close to the antenna as possible." -- Nooelec support
sudo apt-get install -y \
build-essential \
cmake \
git-core \
libopencv-dev \
zlib1g-dev \
librtlsdr-dev
# be sure librtlsdr-dev is installed *before* compiling!
git clone --recursive https://github.com/pietern/goestools
cd goestools
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
make
sudo make install
Yes, without the
sudo
for make install
, I saw this error:
Install the project...
-- Install configuration: "RelWithDebInfo"
CMake Error at cmake_install.cmake:41 (file):
file cannot create directory: /usr/local/share/goestools. Maybe need
administrative privileges.
make: *** [Makefile:140: install] Error 1
[demodulator]
# mode = "lrit"
mode = "hrit"
source = "rtlsdr"
# The section below configures the sample source to use.
#
# You can leave them commented out to use the default values for the
# demodulator mode you choose ("lrit" or "hrit"). To use and configure
# any of them, uncomment the section below, and change the demodulator
# source field to match the source you want to use.
#
# [airspy]
# frequency = 1694100000
# gain = 18
[rtlsdr]
frequency = 1694100000
sample_rate = 2000000
gain = 30
bias_tee = true
# [nanomsg]
# connect = "tcp://1.2.3.4:5005"
# receive_buffer = 2097152
# sample_rate = 2400000
[costas]
max_deviation = 200e3
# [clock_recovery.sample_publisher]
# bind = "tcp://0.0.0.0:5002"
# send_buffer = 2097152
[quantization.soft_bit_publisher]
bind = "tcp://0.0.0.0:5001"
send_buffer = 1048576
[decoder.packet_publisher]
bind = "tcp://0.0.0.0:5004"
send_buffer = 1048576
# The demodulator stats publisher sends a JSON object that describes
# the state of the demodulator (gain, frequency correction, samples
# per symbol), for every block of samples.
#[demodulator.stats_publisher]
#bind = "tcp://0.0.0.0:6001"
# The decoder stats publisher sends a JSON object for every packet it
# decodes (Viterbi corrections, Reed-Solomon corrections, etc.).
[decoder.stats_publisher]
bind = "tcp://0.0.0.0:6002"
# The monitor can log aggregated stats (counters, gauges, and
# histograms) to a statsd daemon. Because this uses UDP, you can keep
# this enabled even if you haven't setup a statsd daemon yet.
[monitor]
statsd_address = "udp4://localhost:8125"
Then run
goesrecv -c goes.conf -v -i 1
Note if you see an error:
Invalid downlink type:
then you forgot to uncomment the hrit
or lrit
in the [demodulator]
section of the config file. I opened Issue #101 to perhaps address this for others.
For reference, if the receiver is getting no data (such as the case when sitting in the house on the kitchen floor for me during initial setup), the output looks like this: pi@raspberrypi:~ $ goesrecv -c goes.conf -v -i 1
Detached kernel driver
Found Elonics E4000 tuner
Disabled direct sampling mode
[E4K] PLL not locked for 0 Hz!
Allocating 15 zero-copy buffers
2020-11-08T22:29:39Z [monitor] gain: 3.99, freq: 39.0, omega: 8.166, vit(avg): 2167, rs(sum): 0, packets: 0, drops: 6
2020-11-08T22:29:40Z [monitor] gain: 4.57, freq: -7.6, omega: 8.166, vit(avg): 2205, rs(sum): 0, packets: 0, drops: 12
2020-11-08T22:29:41Z [monitor] gain: 4.59, freq: 26.5, omega: 8.166, vit(avg): 2182, rs(sum): 0, packets: 0, drops: 11
2020-11-08T22:29:42Z [monitor] gain: 4.60, freq: 7.4, omega: 8.167, vit(avg): 2194, rs(sum): 0, packets: 0, drops: 12
2020-11-08T22:29:43Z [monitor] gain: 4.61, freq: -13.3, omega: 8.167, vit(avg): 2179, rs(sum): 0, packets: 0, drops: 11
2020-11-08T22:29:44Z [monitor] gain: 4.62, freq: -41.2, omega: 8.167, vit(avg): 2186, rs(sum): 0, packets: 0, drops: 12
2020-11-08T22:29:45Z [monitor] gain: 4.60, freq: -16.9, omega: 8.167, vit(avg): 2194, rs(sum): 0, packets: 0, drops: 11
^CSignal caught, exiting!
2020-11-08T22:29:46Z [monitor] gain: 4.58, freq: -27.7, omega: 8.167, vit(avg): 2185, rs(sum): 0, packets: 0, drops: 2
Reattached kernel driver
Many of the blogs seemed to make a big deal about leveling, having accurate compass, and other positioning issues. I don't think any of that is essential. The only thing really important is stability. I did buy an inexpensive angle locator on Amazon:
pi@raspberrypi:~ $ goesrecv -c goes.conf -v -i 1
Detached kernel driver
Found Elonics E4000 tuner
Disabled direct sampling mode
[E4K] PLL not locked for 0 Hz!
Exact sample rate is: 2000000.052982 Hz
Allocating 15 zero-copy buffers
2020-11-09T15:49:02Z [monitor] gain: 2.82, freq: 34.9, omega: 2.157, vit(avg): 1149, rs(sum): 0, packets: 0, drops: 40
2020-11-09T15:49:03Z [monitor] gain: 3.07, freq: 26.5, omega: 2.157, vit(avg): 1151, rs(sum): 0, packets: 0, drops: 54
2020-11-09T15:49:04Z [monitor] gain: 3.07, freq: 12.2, omega: 2.157, vit(avg): 1150, rs(sum): 0, packets: 0, drops: 56
2020-11-09T15:49:05Z [monitor] gain: 3.07, freq: -4.6, omega: 2.157, vit(avg): 1172, rs(sum): 0, packets: 0, drops: 54
2020-11-09T15:49:06Z [monitor] gain: 3.08, freq: -7.8, omega: 2.157, vit(avg): 1148, rs(sum): 0, packets: 0, drops: 57
2020-11-09T15:49:07Z [monitor] gain: 3.08, freq: -1.2, omega: 2.157, vit(avg): 1166, rs(sum): 0, packets: 0, drops: 57
2020-11-09T15:49:08Z [monitor] gain: 3.08, freq: 13.2, omega: 2.158, vit(avg): 1164, rs(sum): 0, packets: 0, drops: 51
2020-11-09T15:49:09Z [monitor] gain: 3.08, freq: -9.9, omega: 2.157, vit(avg): 1143, rs(sum): 0, packets: 0, drops: 52
2020-11-09T15:49:10Z [monitor] gain: 3.08, freq: 32.7, omega: 2.158, vit(avg): 1217, rs(sum): 0, packets: 0, drops: 52
2020-11-09T15:49:11Z [monitor] gain: 3.09, freq: -870.8, omega: 2.157, vit(avg): 821, rs(sum): 16, packets: 19, drops: 35
2020-11-09T15:49:12Z [monitor] gain: 3.09, freq: -2376.1, omega: 2.157, vit(avg): 199, rs(sum): 76, packets: 55, drops: 0
2020-11-09T15:49:13Z [monitor] gain: 3.09, freq: -2352.7, omega: 2.158, vit(avg): 196, rs(sum): 65, packets: 56, drops: 0
2020-11-09T15:49:14Z [monitor] gain: 3.09, freq: -2351.0, omega: 2.157, vit(avg): 196, rs(sum): 76, packets: 57, drops: 0
2020-11-09T15:49:15Z [monitor] gain: 3.09, freq: -2391.0, omega: 2.158, vit(avg): 195, rs(sum): 64, packets: 58, drops: 0
2020-11-09T15:49:16Z [monitor] gain: 3.09, freq: -2377.3, omega: 2.158, vit(avg): 199, rs(sum): 83, packets: 55, drops: 0
2020-11-09T15:49:17Z [monitor] gain: 3.10, freq: -2337.0, omega: 2.158, vit(avg): 197, rs(sum): 89, packets: 57, drops: 0
2020-11-09T15:49:18Z [monitor] gain: 3.09, freq: -2385.5, omega: 2.157, vit(avg): 195, rs(sum): 52, packets: 58, drops: 0
2020-11-09T15:49:19Z [monitor] gain: 3.09, freq: -2393.7, omega: 2.158, vit(avg): 196, rs(sum): 72, packets: 56, drops: 0
2020-11-09T15:49:20Z [monitor] gain: 3.10, freq: -2389.4, omega: 2.158, vit(avg): 196, rs(sum): 103, packets: 56, drops: 0
# Example configuration file for goesproc
#
# This tool is designed to run on streaming data (live or recorded)
# and product whatever is listed in this file. A single product can be
# processed multiple times (e.g. with different contrast curves,
# different scale, or different annotations) by listing multiple
# handlers for that same product.
#
# GOES-16 mesoscale region 1 imagery is stored at ./goes16/m1/YYYY-MM-DD
# The pattern specified in {time:XXX} is extrapolated using strftime(3).
# It can be used more than once if needed.
[[handler]]
type = "image"
origin = "goes17"
region = "m1"
dir = "./goes17/m1/{time:%Y-%m-%d}"
# GOES-17 full disk originals.
[[handler]]
type = "image"
origin = "goes17"
region = "fd"
dir = "./goes17/fd/{time:%Y-%m-%d}"
# GOES-16 full disk, channel 2, with contrast curve applied.
# The section [handler.remap] below applies to this handler.
[[handler]]
type = "image"
origin = "goes17"
region = "fd"
channels = [ "ch02" ]
directory = "./goes16/fd/{time:%Y-%m-%d}"
filename = "{filename}_contrast"
Running in a second SSH session:
sudo goesproc -c ~/goesproc.conf --subscribe tcp://127.0.0.1:5004
- rtl-sdr.com GOES 16/17 and gk 2a weather satellite reception comprehensive tutorial
- Receive GOES-16 and GOES-17 Images with a Raspberry Pi and RTL-SDR dongle
- www.dishpointer.com
- usradioguy.com
- pietern.github.io/goestools
- goestools - A minimal LRIT/HRIT receiver
- goestools installation
- goestools goesrecv; see ./etc/goesrecv.conf
- goestools goesproc
- Designing false colors for goes-r hrit
- xrit decoder
- SatNOGS Rotator v3
- CIMSS Satellite Blog - GOES-17 arrives at its GOES-West position of 137.2Âş W longitude
Sunday, November 1, 2020
EA3500 OpenWRT WiFi to WiFi STA Routing
Setting up Cisco Linksys EA3500 as WiFi to WiFi (STA mode) to have wired ethernet clients instead of WiFi clients (as opposed to the typical AP mode).
TL;DR; install OpenWRT; change Network - Interfaces IP address of EA3500; use wireless mode N, auto.
I want to connect my wired ethernet device, for example the Envox EEZ Bench Box 3 "Modular, open-source test & measurement chassis" to WiFi. Sounds simple enough...
Update: the above picture is not accurate unless router forwarding rules are manually applied.
In my prior blogs, I recorded some notes on setting up a Raspberry Pi as either a WiFi STA Router (not an AP!) to route local eth0 onto the wlan0 for WiFi-to-WiFi connection (most people do the reverse: hardwire a WiFi router to their ISP and use it as an access point routing wlan0 to eth0). The routed solution has the benefit of an arbitrary number of ethernet clients, but the disadvantage of being on a different network and requiring some manual routing configuration. An alternative solution used the clever wlan_kable app to instead bridge the local RPi eth0 onto the WiFi network. This is works much more gracefully with no manual routing config, but was limited to a single device. This was ok, as I only wanted by BenchBox3 to have WiFi network capability. However, I later experienced some oddities when downloading large automation scripts to the BB3. On to the next option: a "real" router.
I have an old Linksys EA3500 available. They can be found on ebay for around 10 bucks (cheaper than a Raspberry Pi!) Of course, the native firmware does not support using the WiFi radio as a client station. The first thing that comes to mind is WRT: either dd-wrt or OpenWRT. It seems that the dd-wrt solution will pretty much never happen, despite having support for a large number of routers. If it turns out you have one of those routers and want to use dd-wrt, be sure to read the Client Mode wiki.
The very first google search for OpenWRT EA3500 however, was a link to the OpenWRT firmware download page for the EA3500! Could it be that easy? Yes! I simply loaded the 19.07.04 Firmware OpenWRT Install and voila! OpenWRT on the EA3500!!
This is not the first time I've used OpenWRT. See my prior blog on OpenWRT on EA3500 with RTL-SDR Stream.
If you don't know the password on the router, hold down the reset button for 30 seconds to factory reset (until the LED next to the power starts to blink). The default password is: admin
Note that if you are concerned about bricking your router, there are fallback options, and in particular I think the Tigard multi-protocol, multi-voltage tool for hardware hacking could be helpful for not only unbricking, but lots of other cool hardware hacking adventures.
For reference: OpenWRT also has an excellent EA3500 feature summary, copied here as we know things on the internet sometimes just vanish:
There's a wiki guide for OpenWRT: Connect to client Wi-Fi network. Alas I followed along multiple times and simply could not get my WiFi router to connect. Lesson #1: It won't tell you if you enter the wrong WiFi password for the AP you are trying to connect to as a STA client. It just won't work. (and will appear and disappear from the Network - Wireless "Associated Stations") Beyond that, the instructions were not completely clear for this router with various firewall settings, etc. Thus my notes are here:
As described at the beginning on the WRT wiki, if your local network is 192.168.1.x then the router interface needs to be changed to a different network, say 192.168.2.x; See Network - Interfaces:
Actually, I almost never leave a network default at 192.168.1.x as there will typically be a conflict such as this. Alas for this demo I was on a test network...
In my case, my PC was connected to the target wireless AP (referred to here as "your_SSID") and the EA3500 was plugged into my ethernet port. I disabled the WiFi on my PC that was on the same network (192.168.1.0) to configure the EA3500. After editing the IPv4 device address to some other network (e.g. 192.168.2.1), notice the defined network also changes.
The wireless settings tab is also someplace that I was tripped up; Next, under Network - Wireless, click the scan button for Generic MAC80211 802.11bgn. (not the one ending in "an") Find your SSID and click the "Join Network" button and enter your SSID and pass phrase:.
When saving, there will be a bit more config: leave mode set to "N" and change channel to "Auto".
Although previously pressing "save", it is not until you press the "Save & Apply" button:
That's it! Despite the wiki mentioning firewall settings, etc. It is not needed for basic functionality (you may still with to optimize and further secure the router). It is best to restart the BB3 and exit EEZ Studio as well before connecting with the new router.
Some other details:
Note the OpenWRT has SSH enabled by default:
root@OpenWrt:~# cat /etc/config/dhcp
config dnsmasq
option domainneeded '1'
option boguspriv '1'
option filterwin2k '0'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option nonegcache '0'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'
option nonwildcard '1'
option localservice '1'
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv6 'server'
option ra 'server'
option ra_management '1'
config dhcp 'wan'
option interface 'wan'
option ignore '1'
config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'
option loglevel '4'
/etc/config/firewall
root@OpenWrt:~# cat /etc/config/firewall
config defaults
option syn_flood '1'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'
config zone
option name 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
option network 'lan'
config zone
option name 'wan'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
option network 'wan wan6 wwan'
config forwarding
option src 'lan'
option dest 'wan'
config rule
option name 'Allow-DHCP-Renew'
option src 'wan'
option proto 'udp'
option dest_port '68'
option target 'ACCEPT'
option family 'ipv4'
config rule
option name 'Allow-Ping'
option src 'wan'
option proto 'icmp'
option icmp_type 'echo-request'
option family 'ipv4'
option target 'ACCEPT'
config rule
option name 'Allow-IGMP'
option src 'wan'
option proto 'igmp'
option family 'ipv4'
option target 'ACCEPT'
config rule
option name 'Allow-DHCPv6'
option src 'wan'
option proto 'udp'
option src_ip 'fc00::/6'
option dest_ip 'fc00::/6'
option dest_port '546'
option family 'ipv6'
option target 'ACCEPT'
config rule
option name 'Allow-MLD'
option src 'wan'
option proto 'icmp'
option src_ip 'fe80::/10'
list icmp_type '130/0'
list icmp_type '131/0'
list icmp_type '132/0'
list icmp_type '143/0'
option family 'ipv6'
option target 'ACCEPT'
config rule
option name 'Allow-ICMPv6-Input'
option src 'wan'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
list icmp_type 'router-solicitation'
list icmp_type 'neighbour-solicitation'
list icmp_type 'router-advertisement'
list icmp_type 'neighbour-advertisement'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'
config rule
option name 'Allow-ICMPv6-Forward'
option src 'wan'
option dest '*'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'
config rule
option name 'Allow-IPSec-ESP'
option src 'wan'
option dest 'lan'
option proto 'esp'
option target 'ACCEPT'
config rule
option name 'Allow-ISAKMP'
option src 'wan'
option dest 'lan'
option dest_port '500'
option proto 'udp'
option target 'ACCEPT'
config include
option path '/etc/firewall.user'
(my /etc/firewall.user had nothing extra)
/etc/config/network
root@OpenWrt:~# cat /etc/firewall.user
# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.
# Internal uci firewall chains are flushed and recreated on reload, so
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.
root@OpenWrt:~# cat /etc/config/network
config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'
config globals 'globals'
option ula_prefix 'fdb2:e9f2:64b4::/48'
config interface 'lan'
option type 'bridge'
option ifname 'eth0.1'
option proto 'static'
option netmask '255.255.255.0'
option ip6assign '60'
option ipaddr '192.168.2.1'
config interface 'wan'
option ifname 'eth1.2'
option proto 'dhcp'
config interface 'wan6'
option ifname 'eth1.2'
option proto 'dhcpv6'
config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'
config switch_vlan
option device 'switch0'
option vlan '1'
option ports '0 1 2 3 5t'
config switch_vlan
option device 'switch0'
option vlan '2'
option ports '4 6t'
config interface 'wwan'
option proto 'dhcp'
/etc/config/wireless
root@OpenWrt:~# cat /etc/config/wireless
config wifi-device 'radio0'
option type 'mac80211'
option hwmode '11g'
option path 'mbus@f1000000/mbus@f1000000:pcie@82000000/pci0000:00/0000:00:01.0/0000:01:00.0'
option htmode 'HT20'
option channel 'auto'
config wifi-iface 'default_radio0'
option device 'radio0'
option network 'lan'
option mode 'ap'
option ssid 'OpenWrt'
option encryption 'none'
option disabled '1'
config wifi-device 'radio1'
option type 'mac80211'
option channel '36'
option hwmode '11a'
option path 'mbus@f1000000/mbus@f1000000:pcie@82000000/pci0000:00/0000:00:02.0/0000:02:00.0'
option htmode 'HT20'
option disabled '1'
config wifi-iface 'default_radio1'
option device 'radio1'
option network 'lan'
option mode 'ap'
option ssid 'OpenWrt'
option encryption 'none'
config wifi-iface 'wifinet2'
option ssid 'your_SSID'
option device 'radio0'
option mode 'sta'
option key 'your_SSID_password_in_plain_text'
option network 'wwan'
option encryption 'psk2'
Of course, see that line:
option mode 'sta'
near the bottom of wireless settings: The key to all of this!Sunday, October 25, 2020
Raspberry Pi Bridge eth0 to wlan0 with wlan_kabel
In my prior blog, I came up with a somewhat brute-force method of setting up a local DHCP server and using dnsmasq. However, as brute force methods go, it was also neither a very graceful nor flexible solution.
While surfing the internet looking for alternatives, there was one person that casually mentioned "you can also try wlan_kabel". This turned out to be a ridiculously cool solution!
Starting with my default headless Raspberry Pi setup, install git and clone escitalopram's wlan_kabel. You'll need the MAC address of the device to use; the BB3 shows this on the ethernet settings screen:
sudo apt-get install git
git clone https://github.com/escitalopram/wlan_kabel.git
cd wlan_kabel
make
# the magic (showing the example MAC address from the docs)
# you'll need to put your own address here:
sudo ./wlan_kabel wlan0 eth0 74:69:69:2d:30:11
That's it! It just works. There are of course limitations (one device connected to Raspberry Pi eth0 port).
To run wlan_kabel at boot time, put this in
/etc/rc.local
:
(/home/pi/wlan_kabel/wlan_kabel wlan0 eth0 74:69:69:2d:30:11 > /dev/null 2>&1) &
Don't forget to use your own MAC address, and be sure to include the training ampersand.Find gojimmypi at gojimmypi.github.io
I'm currently working on my new blog home at gojimmypi.github.io After implementing a variety of features such as dark mode , syntax hi...
-
I decided to finally learn how to program an FPGA! Here are some first impressions and notes to self for future reference. TL;DR Bla...
-
Notes and information on JTAG Debugging the ESP32 WROOM-32 (aka DevKitC, aka ESP32_Core_Board_V2) I started off my day thinking I'd ta...
-
This is a continuation of my prior blog on limit switch mounting hardware design for the CNC3018 . There are plenty of resources on various ...