@echo off REM ***************************************************** REM Batch script to automate process of compiling and REM uploading Arduino .ino files to Arduino Uno board REM Author: https://fotografeer.nl/index.php?/categories/blog/essays/compile-and-upload-ino-file-to-aruduino-board-via-arduino-cli/ REM REM See also: https://github.com/arduino/arduino-cli REM See also: https://dumblebots.com/2020/08/02/arduino-cli-getting-started-windows/ REM See also: https://stackoverflow.com/questions/2048509/how-to-echo-with-different-colors-in-the-windows-command-line REM See also: https://gist.githubusercontent.com/mlocati/fdabcaeb8071d5c75a2d51712db24011/raw/b710612d6320df7e146508094e84b92b34c77d48/win10colors.cmd REM ***************************************************** REM THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, REM EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, REM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS REM OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, REM WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION REM WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN THIS HOWTO. cls setlocal enableextensions enabledelayedexpansion REM See: https://arduino.github.io/arduino-cli/0.29/getting-started/ echo Compile and Upload .ino file to Aruduino board via arduino-cli set EXIT_CODE_0=0 set EXIT_CODE_2=0 set EXIT_CODE_3=0 echo: REM if "%~1" == "" ( IF [%1]==[] ( echo Please provide one argument holding a name of a .ino file. Example: echo CompileAndUpload.bat Button.ino echo Finished. exit /b %EXIT_CODE% ) REM Create a main temporary directory, if it not already exists REM See: https://stackoverflow.com/questions/4165387/create-folder-with-batch-but-only-if-it-doesnt-already-exist set TEMP_MAIN=C:\tmp if not exist %TEMP_MAIN% mkdir %TEMP_MAIN% REM Strip double quotes from 1st command line input's file path REM See: https://stackoverflow.com/questions/1964192/removing-double-quotes-from-variables-in-batch-file-creates-problems-with-cmd-en REM See: https://superuser.com/questions/1252486/how-can-i-silence-all-output-from-a-command-in-a-batch-file set INO_PATH=%1 > nul 2>&1 set INO_PATH=%INO_PATH:"=% > nul 2>&1 set INO_PATH=%INO_PATH:\\=% > nul 2>&1 REM Split on period in order to remove the .ino file type REM See: https://stackoverflow.com/questions/23600775/split-string-with-string-as-delimiter for /f "tokens=1,2 delims=." %%a in ("%INO_PATH%") do ( set BEFORE_PERIOD=%%a set AFTER_PERIOD=%%b ) REM Determine sketch name based on text after last \ REM See: https://stackoverflow.com/questions/47796707/how-to-extract-text-after-in-batch-file set "SKETCH_NAME=%BEFORE_PERIOD:\=" & set "SKETCH_NAME=%" REM Create a temporary dir with a sketch name that is the same as the file name (without .ino) REM See: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/mkdir set TMP_DIR=%TEMP_MAIN%\%SKETCH_NAME% REM echo Temp dir = %TMP_DIR% echo CREATING temporary directory %TMP_DIR% mkdir "%TMP_DIR%" REM dir "%TMP_DIR%" REM Copy original .ino file to temp dir REM See: https://stackoverflow.com/questions/33752732/xcopy-still-asking-f-file-d-directory-confirmation echo COPYING original source file to temporary directory: xcopy /F %1 "%TMP_DIR%" set EXIT_CODE_0=%ERRORLEVEL% REM See: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb491035(v=technet.10) IF "%EXIT_CODE_0%" NEQ "0" ( echo Unable to copy source file to temporary directory, due to exit code %EXIT_CODE_0%. set EXIT_CODE=%EXIT_CODE_0% goto cleanup ) echo: REM Find Available COM ports REM See 3rd answer on: https://superuser.com/questions/835848/how-to-view-serial-com-ports-but-not-through-device-manager echo LOCATING communication ports set COM_PORTS_NAMES=%TMP_DIR%\ports.txt set DEFAULT_PORT_FILE=%TMP_DIR%\default_port.txt for /f "tokens=3* delims= " %%a in ( 'reg query HKLM\HARDWARE\DEVICEMAP\SERIALCOMM' ) do ( echo %%a >> "%COM_PORTS_NAMES%" ) REM powershell -command "Get-WMIObject Win32_SerialPort | Select-Object DeviceID | foreach { $_.DeviceID }" > %COM_PORTS_NAMES% REM Count the number of lines to determine the number of com ports found REM And create string to display for com port options REM See: https://stackoverflow.com/questions/5664761/how-to-count-no-of-lines-in-text-file-and-store-the-value-into-a-variable-using REM See: https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- set /a PORT_COUNT=0 for /f %%j in ('type "%COM_PORTS_NAMES%"') do set /A PORT_COUNT=PORT_COUNT+1 for /f %%x in ('type "%COM_PORTS_NAMES%"') do set "OPTIONS_STRING=!OPTIONS_STRING!%%x," powershell -command "Get-Content -Path '%COM_PORTS_NAMES%' -TotalCount 1" > "%DEFAULT_PORT_FILE%" set /p DEFAULT_PORT=<"%DEFAULT_PORT_FILE%" set DEFAULT_PORT=%DEFAULT_PORT: =% echo Located %PORT_COUNT% communication port(s) if "%PORT_COUNT%" == "1" ( REM Put com port name into variable REM See: https://stackoverflow.com/questions/3068929/how-to-read-file-contents-into-a-variable-in-a-batch-file set /p COM_PORT=<"%COM_PORTS_NAMES%" ) ELSE ( IF "%PORT_COUNT%" == "0" ( echo Zero ports found. REM Set exit code ERROR_NOT_SUPPORTED set EXIT_CODE=50 goto cleanup ) else ( REM See: https://stackoverflow.com/questions/155932/how-do-you-loop-through-each-line-in-a-text-file-using-a-windows-batch-file echo More that one port found. Please provide the name of the com port you want to use. set /p "COM_PORT=Enter one of the available COM port names (%OPTIONS_STRING:~0,-1%) [%DEFAULT_PORT%]: " ) ) IF "%COM_PORT%"=="" ( set COM_PORT=%DEFAULT_PORT% ) >nul find "%COM_PORT%" "%COM_PORTS_NAMES%" && ( echo Using com port %COM_PORT% ) || ( echo %COM_PORT% is currently not active. set EXIT_CODE=5 goto cleanup ) echo: REM Select a board echo Currently Arduino Uno and Nano are supported by this batch file. set DEFAULT_BOARD=Nano set /p "BOARD=Enter one of the available board types (Uno, Nano) [Nano]: " IF "%BOARD%"=="" ( set BOARD=%DEFAULT_BOARD% ) IF NOT "%BOARD%"=="Nano" IF NOT "%BOARD%"=="Uno" ( echo Board '%BOARD%' currently not supported by this batch file. set EXIT_CODE=50 goto cleanup ) REM Compile the sketch REM See: https://github.com/arduino/arduino-cli REM See: https://arduino.github.io/arduino-cli/0.29/commands/arduino-cli_compile/ REM See: https://arduino.github.io/arduino-cli/0.29/commands/arduino-cli_version/ REM See: https://dumblebots.com/2020/08/02/arduino-cli-getting-started-windows/ REM See: https://www.tutorialspoint.com/batch_script/batch_script_return_code.htm echo COMPILING %TMP_DIR%: echo  arduino-cli version echo  arduino-cli compile --fqbn arduino:avr:uno "%TMP_DIR%" set EXIT_CODE_2=%ERRORLEVEL% REM If compile was successful, upload the compiled sketch. REM Otherwise print warning message and stop. REM See: https://arduino.github.io/arduino-cli/0.29/commands/arduino-cli_upload/ IF "%EXIT_CODE_2%" NEQ "0" ( echo Skipping upload %TMP_DIR% due to compile errors with exit code %EXIT_CODE_2%. echo Fix your code first. set EXIT_CODE=%EXIT_CODE_2% goto cleanup ) ELSE ( echo UPLOADING "%TMP_DIR%" to %COM_PORT% echo Expect the upload LEDs on your board to blink soon. IF "%BOARD%"=="Nano" ( REM My nano's have the old ATmega328P and require the "ATmega328P (Old Bootloader)" REM processor via option :cpu=atmega328old. arduino-cli upload -p %COM_PORT% -b arduino:avr:nano:cpu=atmega328old "%TMP_DIR%" ) ELSE ( IF "%BOARD%"=="Uno" ( arduino-cli upload -p %COM_PORT% -b arduino:avr:uno "%TMP_DIR%" ) ELSE ( echo Board %BOARD% currently not supported by this batch file. set EXIT_CODE=50 goto cleanup ) ) set EXIT_CODE_3=%ERRORLEVEL% IF "%EXIT_CODE_3%" NEQ "0" ( echo Unable to upload, due to exit code %EXIT_CODE_3%. set EXIT_CODE=%EXIT_CODE_3% goto cleanup ) ELSE ( echo Assuming upload complete. ) set EXIT_CODE=%EXIT_CODE_3% ) :cleanup echo: REM Remove the temporary directory echo REMOVING %TMP_DIR% and all its content rmdir "%TMP_DIR%" /s /q echo Finished. REM See: https://stackoverflow.com/questions/334879/how-do-i-get-the-application-exit-code-from-a-windows-command-line exit /b %EXIT_CODE%