Showing posts with label References. Show all posts
Showing posts with label References. Show all posts

Sunday, January 28, 2024

Installing and using the Arduino Command-Line Interface (CLI)

The Arduino line of microcontrollers has become a de facto standard in the maker world. One of its main advantages is the Arduino IDE, which makes it very easy to program and debug boards.

However, in more complex projects, it’s often desirable to centralize development around a common toolset, including a general-purpose text editor or IDE. In this case a command-line interface is necessary so that Arduino sketches can be automatically compiled and uploaded from build scripts, instead of manually through the Arduino IDE.

In the past, the Arduino IDE supported command-line options for automatically running tasks such as compiling or uploading a sketch to a board. However, more recently these functionalities have been moved to a new application, the Arduino Command-Line Interface (CLI).

Installing the Arduino CLI can be easily done from the terminal. To install the tool under ~/.local/bin, make sure you have curl installed, then run the commands below:

ARDUINO_PATH="$HOME/.local/bin"
mkdir -p $ARDUINO_PATH
curl -fsSL "https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh" | BINDIR=$ARDUINO_PATH sh

For convenience, make sure that $HOME/.local/bin is in your $PATH environment variable. If not, add the following line to ~/.bashrc:

export PATH="$PATH:$HOME/.local/bin"

Then either start a new terminal session or run the command above in the current session to update the $PATH.

As initially set up, Arduino CLI is unable to communicate with any board. This requires installing “cores”, which contain information and specific tools for specific board architectures. First, download the list of available cores with:

arduino-cli core update-index

In order to know which core to install, connect your Arduino board to your computer, then run the command below:

arduino-cli board list

For example, with a single Arduino UNO connected, the output will be something like this:

Port         Protocol Type              Board Name  FQBN            Core
/dev/ttyACM0 serial   Serial Port (USB) Arduino Uno arduino:avr:uno arduino:avr

Now run the command below:

arduino-cli core install $CORE

Replacing $CORE with the value in the Core column from the output of arduino-cli board list — in the case above, arduino:avr.

If your code uses any extra libraries, they also need to be installed. For example, to install the TimerInterrupt library, enter:

arduino-cli lib install "TimerInterrupt"

Once your environment is properly set up, a sketch can be compiled with:

arduino-cli compile --fqbn $FQBN --warnings all $PATH_SKETCH

Where $FQBN is the Fully-Qualified Board Name (arduino:avr:uno in the example above). If you have your board connected to your computer, finding the FQBN can be automated with:

arduino-cli compile \
  --fqbn $(arduino-cli board list | grep -oEi 'arduino:[^ ]+:[^ ]+') \
  --warnings all \
  $PATH_SKETCH

In contrast to the Arduino IDE, the Arduino CLI does not automatically compile a sketch before upload, so make sure to run this command following any changes to the code. Also notice that we set option –warnings all to make sure we’re notified in case of any compilation warnings. This is important since warnings can often be indicative of programming mistakes, and it’s generally good practice to resolve them whenever possible.

Finally, a sketch can be uploaded to a board with:

arduino-cli upload -p $PORT --fqbn $FQBN $PATH_SKETCH

Where $PORT and $FQBN can be found from the output of arduino-cli board list as shown above. This can be automated with a little shell scripting as below:

arduino-cli upload \
  $(arduino-cli board list | perl -ne 'm/([^ ]+).+(arduino:[^ ]+:[^ ]+)/ && print "-p $1 --fqbn $2"') \
  "$PATH_SKETCH"

The above commands can be added to shell scripts for easy reuse:

#!/bin/bash

# arduino-compile.sh

arduino-cli compile \
  --fqbn $(arduino-cli board list | grep -oEi 'arduino:[^ ]+:[^ ]+') \
  --warnings all \
  "$1"
#!/bin/bash

# arduino-upload.sh

arduino-cli upload \
  $(arduino-cli board list | perl -ne 'm/([^ ]+).+(arduino:[^ ]+:[^ ]+)/ && print "-p $1 --fqbn $2"') \
  "$1"

Create the scripts under ~/.local/bin, then give them execute permission with:

chmod u+x $HOME/.local/bin/arduino-compile.sh
chmod u+x $HOME/.local/bin/arduino-upload.sh

The scripts can then be used as below:

arduino-compile.sh "$PATH_SKETCH"
arduino-upload.sh "$PATH_SKETCH"

Sunday, January 21, 2024

FFmpeg Quick Reference

FFmpeg is a powerful command-line editing tool, but sometimes it can be hard to track down how to perform certain operations. The list below is a quick command reference for common tasks:

Convert video to MP4

ffmpeg -i $INPUT_PATH -vcodec h264 -acodec mp2 $OUTPUT_PATH

Crop video

ffmpeg -i $INPUT_PATH -filter:v "crop=$WIDTH:$HEIGHT:$X:$Y" $OUTPUT_PATH

Remove audio

ffmpeg -i $INPUT_PATH -c copy -an $OUTPUT_PATH

Cut video

ffmpeg -i $INPUT_PATH -ss $START_TIMESTAMP -t $DURATION -c:v libx264 $OUTPUT_PATH

Where $START_TIMESTAMP and $DURATION are strings in the hh:mm:ss.s format.

Scale video proportionally by width

ffmpeg -i $INPUT_PATH -filter:v scale=$WIDTH:-1 -c:a copy $OUTPUT_PATH

Where $WIDTH is the output video width.

Scale video proportionally to 1080p, add black bands as appropriate to fill dimensions

ffmpeg -i $INPUT_PATH \
  "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1" \
  -c:a copy $OUTPUT_PATH

Scale video proportionally to 800 pixels width, set 15 FPS and average bit rate of 2 Mb

ffmpeg -i $INPUT_PATH -b:v 2M -maxrate 2M -bufsize 1M -vf "fps=15,scale=800:-1" $OUTPUT_PATH

git Quick Reference

The git versioning system is the de-facto standard for version control in the FOSS world and much of the software industry. However, its command-line interface can sometimes be hard to figure out, even for seasoned users. The list below is a quick command reference for common tasks:

Pulling Changes from Remote Repository

Pull repository data

git pull --rebase

Adding the --rebase option ensures that any local commits not yet pushed to the remote repo will be placed after any new pulled from it. This makes it possible to then push these commits without getting into any versioning conflicts.

Pull remote branch

git fetch origin remote_branch_name
git checkout -b remote_branch_name origin/remote_branch_name

Pushing Changes to Remote Repository

Push current branch to remote repository

git push

Push locally-created project into repository

git push --set-upstream <URL> master

Undoing Changes

Create a copy of a file’s previous version

git show HEAD^:$path_to_file > $path_to_copy

Unstage added files before commit

git reset HEAD

Restore a deleted file

Find the last commit that affected the given path. As the file isn’t in the HEAD commit, this commit must have deleted it.

git rev-list -n 1 HEAD -- <file_path>

Then checkout the version at the commit before, using the caret (^) symbol:

git checkout <deleting_commit>^ -- <file_path>

Or in one command, if $file is the file in question.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

Wipe changes since last commit

git reset --hard

Remove untracked files / directories

git clean -f -d

Rollback last commit, returning changes to uncommitted state

git reset HEAD^

Tag Management

List tags

git tag

Create tag

git tag -a tag-name -m "tag description"

Push repository data with tags

git push --follow-tags origin master

Checkout tag

git checkout -b branch-name tag-name