OTA/ Remote programming of your Teensy – Step by step tutorial (Win10 & Pi0W)

Status
Not open for further replies.

valentin

Member
Hi,
If you already found this thread the chances are pretty high you are wondering if there is an easy way to program your Teensy over the air without any direct wiring over a USB-cable.
The short answer is: No, there is no officially supported way to do that, nether directly by PJRC, nor by any other third-party software or hardware provider. At least I could not find anything, at the time I am writing this up.
BUT the long answer is: Yes, you can definitely hack together a setup that will do the trick! That involves quite a bit of preparation, tho. Since I never found any detailed description on the topic, I want to fill the gap and make this mod more accessible by showing you a way how you can do this on a Windows machine with everything you will need for it to work.

Before I start, I want to clarify some things. I am clearly not the first one who tried to accomplish something like that and there are most likely more elegant, professional, reliable or whatever ways to do it. Take this as an example you can build up on, if you want to. The information is obviously already out there, and I will try to link to the work of others where I can, if I remember where I found it myself...
The hard thing is mainly to piece together the puzzle and that's where I want to help. Personally, I would have implemented the feature much sooner if I had known how to do it, without having to gather the information on my own.
If you have ideas to improve on my solution or you found a different way to do it, especially for other operating systems, feel free to comment on this thread! There are many people out there, like me, who are most of the time pretty helpless and would love to have some detailed guidance on the topic 😊
I am myself just a student who wanted to make his latest microcontroller project completely wirelessly, without having to give up the great Teensy platform and its advantages with audio and lighting projects.
If you have a workflow like me and you are continuously improving or modifying your code, not having to physically attach yourself to the controller is just a very nice thing to have. It simply makes the software development and testing much more convenient.
With that being said, for the few people I haven’t lost at this point after this terribly long introduction, let’s get into it!

Overview:
1. Hardware
2. Preparing the Raspberry Pi
3. OpenSSH and public-key-authentication
4. Optional NAS with Samba
5. Preparing the Arduino IDE
6. Command line Teensy loader
7. Bash script
8. Powershell script and batch file wrapper
9. Conclusion

1. Hardware
At First, I want to give you an overview of the parts you will need for the setup. Chances are pretty high that you will already have most of it, if you are tinkering with electronics on a regular base anyway.
The main part of the build will be a Raspberry Pi Zero W, but any other Raspberry Pi with networking capability should be probably fine too. I have chosen this particular board mainly for its really small form factor, which is perfect if your intent is to install the board together with your Teensy in a small enclosure, like I do. In addition, is it a relatively affordable model which is definitely more than capable for the purpose.
Furthermore, you will need a microSD card, some Micro-USB cables/connectors, two small resistors (~10K), a power supply and jumper wires. What exactly you will need depends of course on your own use case… Also, a little warning if you want to power both board with a battery: Be aware that the Raspberry Pi will need even in idle more power than any Teensy board. So, I would recommend some kind of mains voltage power supply.
To give you an example for how a wired-up setup could look like take mine for reference:
20190412_210410.jpg
Please excuse this mess, it’s a prototype, OK :D And Yes, under all these cables is actually a Teensy 3.6 😉 I hope you get the point, tho. Simply connect your Raspberry Pi data USB-port with your Teensy USB-port and also hock up the program and reset pin of your Teensy to two GPIO pins of your choice on your Raspberry Pi. I think also its good practice to put two resistors between the reset/ program pin and your Raspberry Pi, but it’s probably also fine without them.

2. Preparing the Raspberry Pi
If you ever had contact with a Raspberry Pi or Linux in general, you can probably skip this. For me this was a first, so I will give a quick introduction to set everything up to a point we can work on the actual OTA programming.
I found this guide to prepare my Raspberry Pi very helpful: https://desertbot.io/blog/headless-raspberry-pi-3-bplus-ssh-wifi-setup
You can get the latest version of Raspbian here: https://www.raspberrypi.org/downloads/raspbian/
I would recommend the headless version of Raspbian. In the context of what I want to show, you won’t need the GUI interface and a Raspberry Pi Zero W would be bit too slow for it, anyway. The manner we will interact with the board is via SSH over your local WiFi network and controlling it solely over the terminal.
If you have never worked this way, I would recommend you look up some starter tutorials on YouTube. As a result you will get a basic sense on how the terminal works and what simple commands are for… The first steps can be a bit hard and unfamiliar, but you will get used to it quickly.

3. OpenSSH and public-key-authentication
To establish an SSH connection we will not use a external program like the commonly recommended PuTTY. When you have an up to date version of Windows 10, there's no matter to do it, anyway. Windows supports meanwhile SSH directly from the terminal similar to Linux or macOS. We will use this feature and some other Windows functions for the automated controlling of your Raspberry Pi over SSH.
You can read more about it and how to set it up, here: https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview
To connect to your Raspberry Pi, simply open an instance of the cmd.exe or PowerShell and type the command:
Code:
C:\> ssh pi@192.168.1.2
The second part of the instruction is a combination of the user you want to log into and the unique name of your Raspberry Pi in your local WiFi network. This is just an example and you have to adapt the command to fit your Raspberry Pi. Also, make sure your computer and your Raspberry Pi are in the same WiFi network.
You should now get a message that prompts you to type in the password of the given user. If you haven’t changed the default settings Raspbian is deployed with, the password for the user pi should be raspberry. If everything went well, you are now connected with your Raspberry Pi over SSH, nice!
But there is one thing we want to get rid of. It would be quite annoying if we would have to type in the password every time, we want to upload a sketch. Fortunately, there is a convenient solution to that problem.
We will setup an automated public-key authentication between your computer and your Raspberry Pi. The authentication will work completely without the need of any interactive input of yourself, once you have set it up.
How you can do that, you can find here:
https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement
https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md
I also found this video to be somewhat helpful:
https://www.youtube.com/watch?v=gM2J2DWCTnM&t=
To try it out just type in again the command line from above and you should connect without any additional input. We can now use the configured terminal for all the following steps.

4. Optional NAS with Samba
Something you can do but you don't have to, is to set up your Raspberry Pi as network attached storage. But I would highly recommend it nevertheless, since it makes your life a whole lot easier when you want to copy files from or to your Raspberry Pi without the need to brows laboriously with the terminal. A common way to do this is by using Samba. You could also use external programs like FileZilla, but for my taste it’s a lot more intuitive to open folders over the explorer.
This is a nice guide how to setup Samba:
https://howtoraspberrypi.com/create-a-nas-with-your-raspberry-pi-and-samba/

5. Preparing the Arduino IDE
The File format your sketches are compiled into and finally uploaded to your Teensy are .hex files. This file is normally outputted to some temporary folder on your system. Since we want to grab this file and upload it by our own, you will need to configure a fixed custom output folder we can later reference to:
http://www.basic6.com/b6launch/developer-guides/arduino/customizing-hex-output
Make sure, your Arduino IDE is closed while you are making the changes. I made the experience that otherwise all changes are getting overwritten again and have no effect.
Now, If you compile a sketch it should be output to the folder you had specified.

6. Command line Teensy loader
After all this initial setup, we can get now to the core of the matter. What makes this all possible is, that there is publicly available version of the Teensy loader for Linux, the program that manages to actual uploading to your Teensy, which can be controlled through simple command line instructions. Since Raspbian is a Linux distribution, we can run this program on your Raspberry Pi.
How to install it is already well documented here: https://www.pjrc.com/teensy/loader_cli.html
However, I will give you quick guide of the necessary steps. First, download the git repository to your Raspberry Pi:
Code:
~$ git clone [url]https://github.com/PaulStoffregen/teensy_loader_cli.git[/url]
You should now have a folder with a bunch of stuff.
Next, make that folder your current working directory:
Code:
~$ cd /teensy_loader_cli
Open the Makefile with a text editor to check if the correct OS is chosen:
Code:
~$ nano Makefile
It should be already set to Linux. If for some reason not, change it and save the file.
The teensy_loader_cli is currently just a .c file which we first have to compile to make it executable. First check if you have the necessary tools to do the job:
Code:
~$ sudo apt install gcc
~$ sudo apt install libusb-dev
Then just type:
Code:
~$ make
~$ chmod +x teensy_loader_cli
Considering we are under Linux we also have to install some udev rules. You could do this manually, but a nice guy on this forum already did the work for you, so you don’t have to worry about it.
https://forum.pjrc.com/threads/45595?p=150445&viewfull=1#post150445
Just run:
Code:
~$ ( sudo rm -f /tmp/49-teensy.rules /etc/udev/rules.d/49-teensy.rules /lib/udev/rules.d/49-teensy.rules &&
wget -O /tmp/49-teensy.rules [url]https://www.pjrc.com/teensy/49-teensy.rules[/url] && 
sudo install -o root -g root -m 0664 /tmp/49-teensy.rules /lib/udev/rules.d/49-teensy.rules &&
sudo udevadm control --reload-rules &&
sudo udevadm trigger &&
echo "Success" )
Finally, reboot your Raspberry Pi ones:
Code:
~$  sudo reboot
To test the freshly installed teensy_loader_cli, I would not recommend trying it out with one of the .hex files given as an example in the git repository. For some reason these made my Teensy invisible to the teensy_loader_cli after I uploaded them once, no matter what I did afterwards. I had to upload a file directly out of the Arduino IDE from my computer to make it work again. I never had this problem with sketches I had compiled by my own. Therefore, compile your test sketch in the Arduino IDE by pressing on verify and copy the .hex file to your Raspberry Pi. To run the teensy_loader_cli you have to give a command similar to this:
Code:
~$ /home/pi/teensy_loader_cli/teensy_loader_cli -mmcu=mk66fx1m0  -w -v /home/pi/hex_output/test.hex
Again, this is just an example and you have to adapt this line to your own setup. The first position is the location of the teensy_loader_cli on your Raspberry Pi. The following first argument is an encoded ID of your Teensy generation. Which one you need, you can look up here under Required command line parameters:
https://www.pjrc.com/teensy/loader_cli.html
You can set additional flags that will influence how the teensy_louder_cli will be executed. The two I would recommend are -w and -v. The last argument will always be the location of the target .hex file itself.
Don’t worry if your teensy_loader_cli tells you it couldn't find your Teensy right away. This is normal and at this point we still have to physically press the reset button on the Teensy itself to upload the sketch. How we are handling this fact in the finished build, I will tell you soon. For now, just test if the upload works at all. If so, we can now get to the part where we are automating the steps, you had to do so far manually.

7. Bash script
There are probably many ways how to go about the automation. And my attempt has definitely some headspace, since I have no real experience with shell scripting. But it works great and I can present you at least a simple example. Do with this information what ever you want. But please don’t behead me, cause my scripts are not clean or are somewhat unconventional. I know myself that it’s probably a bit clumsy 😉. On the other hand, if I can do it, anyone can...
First of all, I have decided to split the work between my computer and my Raspberry Pi to keep the SSH communication as minimal as possible. Certainly, you could do all the commands exclusively from your computer, but I believe that would over complicate the process unnecessary. We will just copy the file and call a bash script on the Raspberry Pi, that will do rest of the work in house. First, I will explain the latter.
Before we write the script, install this library:
Code:
~$ sudo apt install wiringpi
It makes controlling the GPIO pins of your Raspberry Pi a no brainer inside the bash script. But for some reason, this library is using a different naming scheme for the pinout compared to the official BCM one of the Raspberry Pi. Therefore, don’t get desperate if the commands do not work. You are most likely just not referencing the pin you are actually intent to control. There is a simple command that shows you the number you have to use for your pin instead:
Code:
~$ gpio readall
BCM is what you would normally use, but we need the appropriate number out of the wPi column.
Open a new file with a text editor:
Code:
~$ nano programTeensy
Copy this script into the file and fill out the example variables with your own:
Code:
#!/bin/bash

#-mmcu=mk66fx1m0 :      Teensy 3.6
#-mmcu=mk64fx512 :      Teensy 3.5
#-mmcu=mk20dx256 :      Teensy 3.2 & 3.1
#-mmcu=mk20dx128 :      Teensy 3.0
#-mmcu=mkl26z64 :       Teensy LC
#-mmcu=at90usb1286 :    Teensy++ 2.0
#-mmcu=atmega32u4 :     Teensy 2.0
#-mmcu=at90usb646 :     Teensy++ 1.0
#-mmcu=at90usb162 :     Teensy 1.0

#Variables, only change here
RESETPIN=8
PROGRAMPIN=9
TEENSY=-mmcu=mk66fx1m0

SOURCEDIR=/home/pi/hex_output
TEENSYLOADERDIR=/home/pi/teensy_loader_cli

#STOP-no changes from here
FILENAME=$1
#Enable program pin
gpio mode $PROGRAMPIN out
gpio write $PROGRAMPIN 0
# Start teensy_loader_cli with given file path
$TEENSYLOADERDIR/teensy_loader_cli $TEENSY -w -v $SOURCEDIR/$FILENAME &
sleep 1
# Check exit state of teensy_loader_cli
if [ "$?" = "0" ]; then
        # If no error has occurred: Release program pin
        gpio write $PROGRAMPIN 1
        # HalfKay bootloader should be found and the hex file will be uploaded
else
        # If teensy_loader_cli has exit with any error code: Release program pin
        gpio write $PROGRAMPIN 1
        # But also reset Teensy
        gpio mode $RESETPIN out
        gpio write $RESETPIN 0
        gpio write $RESETPIN 1
        exit 1
fi
I don’t want to get into every detail of it, but I will give you a quick overview of what is roughly happening.
The script will be called with the name of the .hex as an argument. Tho, we don’t have to hardcode it into the script, and you can change the name of your sketch whenever you want.
Remember the wiring of the program and reset pin I showed in chapter one? This enables us now to set the Teensy into program mode and also to reset it if necessary directly out of the script. No need for any button pressing. 😊
After some try and error, I discovered the sequence I am showing in the script as the most reliable I could find. I haven’t tested it in every possible way, but it never failed on me so far. First, we are enabling the program pin and setting it as a low output.
If everything is wired up correctly, your Teensy should go now into program mode. Next, we are calling the teensy_loader_cli as explained in section six. After giving it a small moment to breath, we check If any error has encored so far. If not, we release the program pin and that should lead to the recognition of the HalfKay bootloader and finally the flashing of your Teensy. But if the teensy_loader_cli has exited with any kind of error, it will reset your Teensy and it can thus get back to normal operation mode. If that happens, you should probably check the variables you have set for the bash script or if the file path you gave was correct.
After saving the script, you have to give it execution rights, like in chapter six for your teensy_loader_cli:
Code:
~$ chmod +x programTeensy
You can test it now by using this command:
Code:
~$ ./programTeensy test.hex
If this works, we are now done with coding on your Raspberry Pi!

8. Powershell script and batch file wrapper
If you have made it to this point, you are now nearly done! The last thing we have to do is to automatically copy the file from your computer to your Raspberry Pi and tell it to run the bash script we have installed.
If you are not coding from a windows machine, that is probably where we are at the latest separate our ways. I can show at least what you would have to do on your operating system, but not how. I’m very sure that there equivalent commands and functions for any OS. You just need to research these on your own. What I will use for my build is a short Powershell script that I wrap it into a Windows-Batchfile to make it more user friendly.
How to create and run the script you can find here: https://www.windowscentral.com/how-create-and-run-your-first-powershell-script-file-windows-10
Create a new file and copy this script:
Code:
$SOURCEDIR="C:\Users\You\TeensyOTA\Arduino_IDE_HEX-Output\"
$DESTINATIONDIR="/home/pi/hex_output/"
$RASPBERRY="pi@192.168.1.2"
$BASHSCRIPT="programTeensy"

Get-ChildItem -Path $SOURCEDIR -Filter *.hex -File -Name| ForEach-Object {
	scp $SOURCEDIR$_ ${RASPBERRY}:$DESTINATIONDIR
	ssh ${RASPBERRY} "./$BASHSCRIPT $_"
}
Similar to the bash script, just adapt the variables to your own and you are good to go!
As far as I understand you are not able to run the script by double clicking it out of security reasons. A workaround is to wrap the scrip into a .bat file you can create similar to the .ps1 script.
Make a new file, copy these few lines into it and make it fit your own link:
Code:
@ECHO OFF
Powershell.exe -executionpolicy remotesigned -File "C:\Users\You\TeensyOTA\teensyOTA.ps1"
PAUSE
Save the file and run it by simple double clicking it. If everything went well, a terminal should pop up in which you can see the process of the copied file and the teensy_louder_cli:
Screenshot 2019-04-13 15.49.54.png
After a few seconds the script should be finished and your Teensy will run the new sketch! Pretty neat, huh? :cool:
There are ways to hide this window, but for me it is more like a welcome feature to see if everything worked how supposed to. As far as this tutorial goes, we are now finished!

9. Conclusion
I hope this walk-through was somewhat helpful for you, making your own Teensy project that little bit more awesome and especially wirelessly! If you have any suggestions to extend this solution or have ideas for improvements, let me know! 😊
To me the most obvious next step would be to implement the script directly into to Arduino IDE or Teensyduino and make it selectable as an option somewhere inside the interface.
As far as I understand you would have to mess around with the platform.local.txt to make something like that work. But after many hours of trial and mostly error, I personally gave up on it for the moment…
It seems to me quite complicated and I have personally no clue how to tackle it. Any help is very welcome!
If you want dive into it by your own, here is a thread with a quite similar topic that discusses something in that direction: https://forum.pjrc.com/threads/4279...mand-lines-for-teensy-using-PuTTy-or-the-like
Also I was heavily inspired by this post and want to thank KurtE for the initial idea!
Last, I want to point out that the combination of a Raspberry Pi Zero W and a Teensy 3.6 is absolutely awesome and the possibilities extend far beyond the wireless programming! It’s kind of the best of both worlds!
On the one side, you have your powerful Teensy microcontroller, with all its simplicity where you can easily develop your project idea without having to worry about anything else and on the other side, you have the option to extend your project with the Linux based Raspberry Pi, which can handle much more complex stuff and is particularly useful to manage all kind of networking related tasks or to preprocess data.
You just need to wire these two boards up and you have a very powerful development tool that can do pretty much anything!
But I will now make here a cut! This post has already got kind of out of hand and come out to much longer than I initially intended it to be. :D

Bye for now!
 
Status
Not open for further replies.
Back
Top