Resolving “board icestick not connected” for the Lattice IceStick HX1K with Apio

The Latice iCEstick HX1K is an FPGA development board with a built in USB interface. If you are using apio with the board and follow some common instructions for preparing the board to run programs, you may encounter a failure at the upload step. When I tried, I got the error Error: board icestick not connected.

PS D:\scratchpad\icestick\leds> apio upload
Error: board icestick not connected

I thought I had improperly installed the driver, but after further examination I found that was correct. The problem is that there was a mismatch on the description for which the board presented itself and the description that apio was looking for. I can only guess that Lattice had updated the description for the board. The fix is easy. Find boards.json. For me this file was in the path C:\Users\%user%\anaconda3\Lib\site-packages\apio\resources. Look for the entry for the iCE40-HX1K. In that entry there is the object named ftdi that has a child string named desc. Compare this name to the output that you get from apio system --lsftdi. If it is different, update it to ensure it is identical.

Now if you attempt to upload your program it should work!

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

Instagram: @j2inet
Facebook: @j2inet
YouTube: @j2inet
Telegram: j2inet
Twitter: @j2inet

Baltimore Root Certificate Migration for Azure: Prepare your IoT devices

Microsoft announced back in May 2021 that they were switching root certificates used for some services. That announcement is more significant now, as devices uses Azure IoT core start their migration on 15 February. If you are using IoT core, you will want to familiarize yourself with the necessary changes. More on that migration can be found here. While updates tend to be automatic for phones and machines with desktop operating systems, your custom and embedded devices might need a manual update.

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

Instagram: @j2inet
Facebook: @j2inet
YouTube: @j2inet
Telegram: j2inet
Twitter: @j2inet

Plane Spotting with RadarBox

There are a lot of systems dedicated to safety in place for air travel. Recently, one of those systems, NOTAMS, went offline with the cause being attributed to a corrupted database file. It was a system for warning pilots about local hazards, and the loss of that system was sufficient reason to stop planes from taking off for a couple of hours. The many systems that are in place for air vehicles can be interesting, and I want to write about one of those systems that you can directly monitor, ADS-B (Automatic Data Surveillance Broadcast). Through this system, airplanes broadcast their location and heading so that other planes and ground stations can track them. This information is broadcast in the open and anyone can view it. Other aircraft use the data to help avoid collisions. It helps avoid the blind spots associated with radar, providing accurate information throughout it’s range. This information is also often used by plane spotters (a bit like birdwatching, but for planes).

Anyone can receive ADS-B information. Consumer-priced receiving equipment is available for under 100 USD. On one’s own, one can receive information from aircraft from well over 100 miles away. But many of these products also work with services that allow people with receivers to cooperate to receive a more complete and further range of data. I have a couple of receivers running that use RadarBox.

Screenshot of Radarbox Flight Tracking

Hardware Selection

You’ll generally find ADS-B receivers using one of two frequencies. 978 MHz and 1090 MHz. For RadarBox, the equipment for these two frequencies is color coded with 978 MHz being red and 1090 MHz blue. Of these two frequencies, the 1090 MHz system is in greater use. There’s not much debate to be had, 1090 MHz will be the frequency to get unless you’ve got some compelling and specific need for 978 MHz. The 978 MHz frequency is for aircraft that operate exclusively below 5,500 meters (~18,000 feet). Aircraft that operate at higher altitudes use the 1090 MHz frequency.

Having performed setup for both units, I can tell you that setup for the 1090 MHz unit was much easier. When I performed the steps on the 978 MHz unit, there were some errors in the process. On both Pis on which I performed the steps I had freshly installed the 64-bit PI OS and performed updates first. The 978 MHz setup was a lot more involved. The 1090 MHz setup was primary running some scripts and not having to figure any problems out.

Create an Account

Go to In the upper-right area you’ll see a link to login. If you are prompted to select a subscript level, stick with the free level. After completing the setup for the Pi your account will automatically be upgraded to a business account (a privilege level that normally cost 40 USD per month).


Assuming you are using a computer that you already own, the setup expense is getting an antenna and a USB ADS-B receiver. You can purchase these in a kit together for 65 to 70 USD. Connecting the hardware together is intuitive; the antenna connects to the threaded adapter on the USB. For the antenna placement, I chose a place that was up high to minimize the amount of potential obstacles attenuating the signal strength. I installed the antenna in my attic. While the system comes with u-shaped bolts for securing the antenna, I instead used zip ties and some foam to secure it on one of the beams in the attic. I didn’t install the Pis in the attic though. In the summer the temperature in the attic can become tremendously hot, and I don’t think they would survive well. Instead, I used a space through which network cable was being routed so that the connector for the antenna was in the living area of the house.

You’ll need to know the elevation at which you’ve installed the antenna in meters. This information will be necessary during the registration step.

I performed all of the steps for setup over SSH from a Mac. Installation is performed through downloading and running some scripts. The instructions can be found at The directions that I post here are derived from those. The directions have a decision point on whether you are going to use receiver dongle or have it pull information from some other program. I assume you will be use the dongle. If you are, there are only 4 commands that you need to run.

sudo bash -c "$(wget -O -"
sudo apt-get install mlat-client -y
sudo systemctl restart rbfeeder
sudo rbfeeder --showkey

The first two lines will install the software services . The third line will start the service. After the service is running, you’ll need the unique key that was generated for your device. This fourth command shows the key. You can also view the key in /etc/rbfeeder.ini. Copy this key, you’ll need it to register the device.


To register the device navigate to After logging into your account you’ll see a text box allowing you to past an identifying key with a button to “Claim” your device. After claiming, you’ll be prompted for the location information. Enter the address at which you have your device positioned to show a map of the area. Move the map around until it is centered on the precise area in which you’ve installed the antenna. You’ll be asked to enter the elevation of the antenna too. This is the elevation is the meters above ground. RadarBox will already account for the elevation of the address that you’ve entered. Once all the information is entered, the claiming process is complete. Let the system run on its own for about 20 minutes. Later, open a browser on any computer and log into your account on Once logged in, if you click on the account button . In the menu that opens there will be a group for “Stations.” Selecting that will show all of your registered devices.

Select your station. In the lower-left corner you’ll see a graph showing the status of your unit over time. Green blocks will show during times where your unit was receiving and relaying data. After your device is sending data, you’ll get a notice on a following login saying that your account has been upgraded to the Business level.

API Access

Since most of my audience is developer focused, I wanted to speak a bit about the APIs. Unlike the use of the RadarBox UI, access to the API is not free. Even some of the services that offer “free API access” keep the calls I think to be more interesting as premium (requiring payment) access. Access to the RadarBox APIs is completely independent of contributing to the data collection. The API calls consume “credits.” RadarBox sells the credits through various subscription levels, with the credits costing less-per-dollar for the highest subscription level. The least expensive subscription gives 10,000 credits for 112 USD/month. This works out to 0.012 USD per credit. When you first open a RadarBox account, you get 100 credits to start with at no cost.

There are SDKs for the API available for a variety of environments and languages, including Python, Java, TypeScript/JavaScript, C#, Swift, and more. The documentation for the API can be found at The documentation is interactive; you can make API calls from the browser. But you’ll need an access token to make calls. To get an access token navigate to and select the button to make a token. Note that the API calls that you make are rate limited. On the documentation page in the top-left of the page is an area where you can enter your token. The test calls that you make from the documentation will use this token.

To ensure that the token was working, I tried a low-cost call; I searched for information by airport code. The only parameter that this call needs is an ICAO airport code. For Atlanta, this code he KATL. The response provides information about the airport, including its name, both the ICAO and IATA code (most people in the USA will be more familiar with the IATA code), the name, and information on all of the airport’s runways.

The response for all of the calls contain a field that indicate how many credits are left. There are two API calls related to billing that cost 0 credits; you can inquire your usage statistics without accumulating some expense for having checked on it. I would suggest using that API call first if you are trying to test if your token works to avoid unnecessarily burning credits.

As with other APIs that cost actual money per call, you would probably want to put in place some measures of protection to minimize unnecessary calls. For example, if you were making a mobile app that used this functionality, instead of making calls directly to the RadarBox API, you could make a web service that caches responses for various amounts of time and have your application call that. Some information, such as information on the locations of airports and the runways, won’t change much; the last time my local airport changed in some meaningful way was in 2006 when it added a fifth runway. Information from a call such as that may be worth keeping cached until manually forced to refresh. But for some information, such as the location of a specific plane, since the information is updated frequently it may be worth caching for only a few seconds.

With all that said, let’s make a quick application that will make a call related to why what turned my mind to this. One of the API calls retrieves NOTAMS information for an airport nearby. To minimize API calls, I made a single call from the RadarBox documentation page and saved the response. Most of this program was written using the static response and then updated to make an actual API call.

The program needs a token for making its API calls. The token is not hard-coded into the program. Instead, when the program is first run it will prompt for a token to be entered. Since this value is likely being copied and pasted. the UI provides a paste button to avoid the gestures for selecting the text box, opening the clipboard, and then selecting the paste operation.

For determining the closest airport, I found a list of all the major airports in the world and their coordinates. Using the equation that was in a recent post, I checked the distance between the users position and the airports to find the one with the smallest distance.

fun findClosestAirport(latitude:Double, longitude:Double):airportCode? {
    var distance = DistanceCalculator.EarthRadiusInMeters
    var ac:airportCode? = null
    val d = DistanceCalculator()
    airportCodes.forEach {
        var newDistance = d.CalcDistance(
            this.latitude, this.longitude,
            it.coordinates.latitude, it.coordinates.longitude,
        if(newDistance < distance &&  it.iata_code != null) {
            distance = newDistance
            ac = it
    if(ac != null) closestAirportTextEdit.setText("K${ac.iata_code}")
    return ac;

There’s an SDK available for using RadarBox. But I didn’t use that. Instead, I just made the call directly. Since I only needed one SDK call I was fine calling it directly. The URL prefix to use for all of the API calls is To read the NOTAM notifications, the path is /v2/airspace/${airportCode}/notams. The response comes back formatted in JSON. Parsing the response from a JSON string to some objects is only a few lines of executable code and a few data class definitions. Here is one of the data classes.

data class notam(
    val id:String? = null,
    val number:Int,
    val notamClass:String? = null,
    val affectedFir:String? = null,
    val year:String,
    val type:String? = null,
    @Serializable(with = DateSerializer::class) val effectiveStart: LocalDateTime? = null,
    //val effectiveStart:String,
    @Serializable(with = DateSerializer::class) val effectiveEnd:LocalDateTime? = null,
    val icaoLocation:String,
    @Serializable(with = DateSerializer::class) val issued:LocalDateTime,
    //val issued:String,
    val location:String,
    val text:String,
    val minimumFlightLevel:String? = null,
    val maximumFlightLevel:String? = null,
    val radius:String? = null,
    var translations:List<translation>
    )  {

I used OkHttp for making my HTTP request. The target URL and a Bearer token header are needed for the request. When the response is returned, I deserialize it. I also filter out any results that have an effective date that makes the notice nolonger applicable. In running the code I found that less than 0.3% of the notifications that I received had expired. Filtering them out was completely optional.

    fun updateNotamsFromRadarbox(airportCode:String):Call {
        val requestUrl = "${airportCode}/notams"
        val client = OkHttpClient();
        val request = Request.Builder()
            .url(requestUrl).addHeader("Authorization", "Bearer $radarBoxToken")
        val call = client.newCall(request)
        call.enqueue(object:Callback {
           override fun onResponse(call: Call, response:Response) {
                val responseString = response.body?.string()
               if(responseString != null) {
                   var notamsResponse = Json.decodeFromString(notamResponse.serializer(),responseString)
                   var now:LocalDateTime =
                   var filteredNotams = notamsResponse.apiNotams.filter { i -> ((i.effectiveStart==null)||(i.effectiveStart<now))&&((i.effectiveEnd==null)||(i.effectiveEnd>now))  }
            override fun onFailure(call: Call, e: IOException) {
        return call;

The results come back on another thread. Before updating a ListViewAdapter with the results, I have to make sure that the code is executing on the right thread.

fun showNotams(notamList:List<notam>) {
    runOnUiThread {
        notamLVA = notamsListViewAdapter(this, ArrayList(notamList))
        val notamLV = findViewById<ListView>(
        notamLV.adapter = notamLVA

If you want to see the code for this, you can find it on GitHub ( ).

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

Instagram: @j2inet
Facebook: @j2inet
YouTube: @j2inet
Telegram: j2inet
Twitter: @j2inet

Favourites from CES 2023

Last week marked the end of CES 2023. CES (Consumer Electronics Show) is a yearly tradeshow in which various companies show off their consumer-focus technological developments for everything from the kitchen to the road. Some of the items shown are for planned products. Others are prototypes or show pieces. Many of them show the application of digital electronics to a product. Due to Covid, the show was virtual in 2021. In 2022 the show was in-person, though with a much smaller presentation. This year, 2023, the show was closer to what it had been in times past. Reviewing some of the technologies and products displayed at the show, I wanted to highlight some of my favourites.

Vive XR Elite

The VIVE XR Elite is an augmented reality headset coming later this year. It is available for preorder now for about 1100 USD. This is less expensive than the Meta Quest Pro. It functions both as a standalone unit and can use your PC for gaming via a wireless connection. If you are nearsighted, the headset allows for the projection to be refocused for nearsightedness down to -6. At CES these were presented as units with a 90 Hz refresh rate. Though on their web page they are still described as having a 60 Hz refresh rate. The display resolution per eye is 1920×1920 pixels. The unit only wears 650 grams, with the optics in front and the batter pack in the back making for a more balanced layout. While the unit has controllers, it is also capable of hand tracking.

EcoFlow Blade

EcoFlow’s primary products are solar panels and batteries. For a person looking to go off-grid, these may be great accessories. These are also great if you live in an area with an unreliable power system. The EcoFlow Blade is an all-electric automated lawnmower. Even off-grid, you might want to have a nice lawn🙂. It looks a lot more like an RC car than a lawnmower. The company says that it can both mow the grass and pickup fallen leaves. Having used electric mowers in conventional form factor, my experience thus far has been that they sometimes don’t have enough power to do the entire lawn in one session. However, if the grass cutting is automated, I’m less concerned with how many sessions it takes.

EcoFlow also showed off batteries for the entire house and a portable fridge/ice-maker also powered by their batteries. You can find more about these products here.

Ring Cameras for Car and House

Ring announced a couple of new cameras. These cameras had actually been announced before, but plans were apparently disrupted by the pandemic. One product is a Ring Camera for one’s auto-interior and exterior . The unit has cameras facing in both directions so that it records both the road and what is happening inside the car. When connected to the Internet via WiFi or LTE the owner can get alerts of events inside the car and engage in two-way conversation. With a verbal command (“Alexa, Record”). The unit is powered through the car’s OBD port. Amazon recommends for safety reasons, only use the unit in a vehicle with the OBD port on the left side of the steering wheel. This unit will be available for purchase in February.

Another is the Always Home Ring Camera. This is a drone that flies a path throughout your home on a pathway you’ve selected before flying back to its charging base. This camera solves a problem in security cameras in that they can only see from a limited angle. Withe the camera being mobile, there are more angles that it can potentially capture. Presently, Amazon is taking orders by invitation only.

Wireless 4K TV

While the 97-inch screen of the the LG M3 is eye-catching, for me the more significant attribute is that it can receive 4K signals wirelessly. Given the amount of effort I put into hiding or at least making neat the wires for the various video connections that I have, I see this as a product solving a modern day solution. The TV has a peripheral device to which video and audio sources connect. This box transmits to the TV. This solution is called “Zero Connect” and is expected to be part of their 2023 TV lineup.

Android Satellite Connectivity

Snapdragon is rolling out its chips that provide connectivity with Iridium satellites to Android devices this year. The connectivity could be used to have two-way text based communication. While the functionality it provides is simple, the ability to communicate in emergency situations is vital. Satellite connectivity may greatly reduce the situations in which one can find themselves without the ability to communicate with others.

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

Instagram: @j2inet
Facebook: @j2inet
YouTube: @j2inet
Telegram: j2inet
Twitter: @j2inet