diff --git a/README.md b/README.md index 4b7af0fa..af147f58 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ This extension provides several commands in the Command Palette (F1 o | `arduino.commandPath` | Path to an executable (or script) relative to `arduino.path`. The default value is `arduino_debug.exe` for windows,`Contents/MacOS/Arduino` for Mac and `arduino` for Linux, You also can use a custom launch script to run Arduino by modifying this setting. (Requires a restart after change) Example: `run-arduino.bat` for Windows, `Contents/MacOS/run-arduino.sh` for Mac and `bin/run-arduino.sh` for Linux. | | `arduino.additionalUrls` | Additional Boards Manager URLs for 3rd party packages. You can have multiple URLs in one string with a comma(`,`) as separator, or have a string array. The default value is empty. | | `arduino.logLevel` | CLI output log level. Could be info or verbose. The default value is `"info"`. | -| `arduino.allowPDEFiletype` | Allow the VSCode Arduino extension to open .pde files from pre-1.0.0 versions of Ardiuno. Note that this will break Processing code. Default value is `false`. | +| `arduino.allowPDEFiletype` | Allow the VSCode Arduino extension to open .pde files from pre-1.0.0 versions of Ardiuno. Note that this will break Processing code. Default value is `false`. | | `arduino.enableUSBDetection` | Enable/disable USB detection from the VSCode Arduino extension. The default value is `true`. When your device is plugged in to your computer, it will pop up a message "`Detected board ****, Would you like to switch to this board type`". After clicking the `Yes` button, it will automatically detect which serial port (COM) is connected a USB device. If your device does not support this feature, please provide us with the PID/VID of your device; the code format is defined in `misc/usbmapping.json`.To learn more about how to list the vid/pid, use the following tools: https://github.com/EmergingTechnologyAdvisors/node-serialport `npm install -g serialport` `serialport-list -f jsonline`| | `arduino.disableTestingOpen` | Enable/disable automatic sending of a test message to the serial port for checking the open status. The default value is `false` (a test message will be sent). | | `arduino.skipHeaderProvider` | Enable/disable the extension providing completion items for headers. This functionality is included in newer versions of the C++ extension. The default value is `false`.| @@ -75,7 +75,7 @@ The following Visual Studio Code settings are available for the Arduino extensio "arduino.path": "C:/Program Files (x86)/Arduino", "arduino.commandPath": "arduino_debug.exe", "arduino.logLevel": "info", - "arduino.allowPDEFiletype": false, + "arduino.allowPDEFiletype": false, "arduino.enableUSBDetection": true, "arduino.disableTestingOpen": false, "arduino.skipHeaderProvider": false, @@ -95,6 +95,8 @@ The following settings are as per sketch settings of the Arduino extension. You { "sketch": "example.ino", "port": "COM5", + "baud": 115200, + "ending": "No line ending", "board": "adafruit:samd:adafruit_feather_m0", "output": "../build", "debugger": "jlink", @@ -103,6 +105,8 @@ The following settings are as per sketch settings of the Arduino extension. You ``` - `sketch` - The main sketch file name of Arduino. - `port` - Name of the serial port connected to the device. Can be set by the `Arduino: Select Serial Port` command. For Mac users could be "/dev/cu.wchusbserial1420". +- `baud` - Baud rate for the serial port connected to the device, defaults to 115200. Can be any of the supported rates: 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000. +- `ending` - Line ending used for the serial monitor. Can be any of the following: "No line ending", "Newline", "Carriage return", "Both NL & CR" - `board` - Currently selected Arduino board alias. Can be set by the `Arduino: Change Board Type` command. Also, you can find the board list there. - `output` - Arduino build output path. If not set, Arduino will create a new temporary output folder each time, which means it cannot reuse the intermediate result of the previous build leading to long verify/upload time, so it is recommended to set the field. Arduino requires that the output path should not be the workspace itself or in a subfolder of the workspace, otherwise, it may not work correctly. By default, this option is not set. It's worth noting that the contents of this file could be deleted during the build process, so pick (or create) a directory that will not store files you want to keep. - `debugger` - The short name of the debugger that will be used when the board itself does not have a debugger and there is more than one debugger available. You can find the list of debuggers [here](https://github.com/Microsoft/vscode-arduino/blob/master/misc/debuggerUsbMapping.json). By default, this option is not set. @@ -158,6 +162,11 @@ To *run and develop*, do the following: To *test*, press F5 in VS Code with the "Launch Tests" debug configuration. +Debugging: + +- Logger outputs messages higher than info to the file `arduino.log` in the root of your git repository. +- `console.log("message")` will output messages to the Debug Console of the initial Visual Studio Code instance. + ## Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct). For more information please see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/#howadopt) or contact opencode@microsoft.com with any additional questions or comments. diff --git a/package.json b/package.json index 8c3b9587..521196d4 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "onCommand:arduino.selectProgrammer", "onCommand:arduino.selectSerialPort", "onCommand:arduino.changeBaudRate", + "onCommand:arduino.changeEnding", "onCommand:arduino.addLibPath", "onCommand:arduino.openSerialMonitor", "onCommand:arduino.sendMessageToSerialPort", @@ -101,6 +102,10 @@ "command": "arduino.changeBaudRate", "title": "Arduino: Change Baud Rate" }, + { + "command": "arduino.changeEnding", + "title": "Arduino: Change Line Ending" + }, { "command": "arduino.openSerialMonitor", "title": "Arduino: Open Serial Monitor" diff --git a/src/arduino/arduinoSettings.ts b/src/arduino/arduinoSettings.ts index 58419519..f098b7e0 100644 --- a/src/arduino/arduinoSettings.ts +++ b/src/arduino/arduinoSettings.ts @@ -6,6 +6,7 @@ import * as path from "path"; import * as vscode from "vscode"; import * as WinReg from "winreg"; import * as util from "../common/util"; +import * as constants from "../common/constants"; import { resolveArduinoPath, validateArduinoPath } from "../common/platform"; @@ -219,9 +220,8 @@ export class ArduinoSettings implements IArduinoSettings { } private async tryGetDefaultBaudRate(): Promise { - const supportBaudRates = [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000]; const configValue = VscodeSettings.getInstance().defaultBaudRate; - if (!configValue || supportBaudRates.indexOf(configValue) === -1) { + if (!configValue || constants.SUPPORTED_BAUD_RATES.indexOf(configValue) === -1) { this._defaultBaudRate = 0; } else { this._defaultBaudRate = configValue; diff --git a/src/common/constants.ts b/src/common/constants.ts index acdfbf78..2c4447cb 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -33,11 +33,15 @@ export const messages = { }; export const statusBarPriority = { - PORT: 20, - OPEN_PORT: 30, - BAUD_RATE: 40, - BOARD: 60, - ENDING: 70, + ENDING: 20, + BAUD_RATE: 21, + PORT: 22, + OPEN_PORT: 23, + BOARD: 70, SKETCH: 80, PROGRAMMER: 90, }; + +export const DEFAULT_BAUD_RATE: number = 115200; +export const SUPPORTED_BAUD_RATES: number[] = [ 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000 ]; +export const DEFAULT_LINE_ENDING = "No line ending"; \ No newline at end of file diff --git a/src/deviceContext.ts b/src/deviceContext.ts index 2e7f18e3..97b64356 100644 --- a/src/deviceContext.ts +++ b/src/deviceContext.ts @@ -10,6 +10,7 @@ import * as Logger from "./logger/logger"; import { ARDUINO_CONFIG_FILE } from "./common/constants"; import { ArduinoWorkspace } from "./common/workspace"; +import { SerialPortEnding } from "./serialmonitor/serialportctrl"; /** * Interface that represents the arduino context information. @@ -22,6 +23,18 @@ export interface IDeviceContext { */ port: string; + /** + * Baud Rate connect to the device + * @property {number} + */ + baud: number; + + /** + * Line ending + * @property {SerialPortEnding} + */ + ending: SerialPortEnding; + /** * Current selected Arduino board alias. * @property {string} @@ -74,6 +87,10 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { private _port: string; + private _baud: number; + + private _ending: SerialPortEnding; + private _board: string; private _sketch: string; @@ -141,11 +158,15 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { return vscode.workspace.findFiles(ARDUINO_CONFIG_FILE, null, 1) .then((files) => { let deviceConfigJson: any = {}; + let baud: number = null; + let ending: string = null; if (files && files.length > 0) { const configFile = files[0]; deviceConfigJson = util.tryParseJSON(fs.readFileSync(configFile.fsPath, "utf8")); if (deviceConfigJson) { this._port = deviceConfigJson.port; + baud = deviceConfigJson.baud; + ending = deviceConfigJson.ending; this._board = deviceConfigJson.board; this._sketch = deviceConfigJson.sketch; this._configuration = deviceConfigJson.configuration; @@ -157,8 +178,25 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { } else { Logger.notifyUserError("arduinoFileError", new Error(constants.messages.ARDUINO_FILE_ERROR)); } + Logger.info(`baud is ${baud}`); + Logger.info(`ending is ${ending}`); + // Sanitize line ending + if ((ending) && (ending !== SerialPortEnding[SerialPortEnding[ending]])) { + vscode.window.showErrorMessage(`Unsupported ending ${ending}, using default.`); + ending = null; + } + // Sanitize baud rate + if ((baud) && (constants.SUPPORTED_BAUD_RATES.indexOf(baud) === -1)) { + vscode.window.showErrorMessage(`Unsupported baud rate ${baud}, using default.`); + baud = null; + } + this._baud = baud; + this._ending = (ending) ? SerialPortEnding[ending] : null; + } else { this._port = null; + this._baud = null; + this._ending = null; this._board = null; this._sketch = null; this._configuration = null; @@ -177,6 +215,8 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { // Workaround for change in API, populate required props for arduino.json this._port = null; + this._baud = null; + this._ending = null; this._board = null; this._sketch = null; this._configuration = null; @@ -214,6 +254,8 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { } deviceConfigJson.sketch = this.sketch; deviceConfigJson.port = this.port; + deviceConfigJson.baud = this.baud; + deviceConfigJson.ending = (this.ending != null) ? SerialPortEnding[this.ending] : undefined; deviceConfigJson.board = this.board; deviceConfigJson.output = this.output; deviceConfigJson["debugger"] = this.debugger_; @@ -242,6 +284,24 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { this.saveContext(); } + public get baud() { + return this._baud; + } + + public set baud(value: number) { + this._baud = value; + this.saveContext(); + } + + public get ending() { + return this._ending; + } + + public set ending(value: SerialPortEnding) { + this._ending = value; + this.saveContext(); + } + public get board() { return this._board; } diff --git a/src/serialmonitor/serialMonitor.ts b/src/serialmonitor/serialMonitor.ts index c47a30c3..c478a421 100644 --- a/src/serialmonitor/serialMonitor.ts +++ b/src/serialmonitor/serialMonitor.ts @@ -19,12 +19,12 @@ export class SerialMonitor implements vscode.Disposable { public static SERIAL_MONITOR: string = "Serial Monitor"; - public static DEFAULT_BAUD_RATE: number = 115200; + public static DEFAULT_BAUD_RATE: number = constants.DEFAULT_BAUD_RATE; - public static DEFAULT_ENDING: SerialPortEnding = SerialPortEnding["No line ending"]; + public static DEFAULT_ENDING: SerialPortEnding = SerialPortEnding[constants.DEFAULT_LINE_ENDING]; public static listBaudRates(): number[] { - return [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000]; + return constants.SUPPORTED_BAUD_RATES; } public static getInstance(): SerialMonitor { @@ -67,9 +67,15 @@ export class SerialMonitor implements vscode.Disposable { } public initialize() { - const defaultBaudRate = ArduinoContext.arduinoApp.settings.defaultBaudRate || SerialMonitor.DEFAULT_BAUD_RATE; + const dc = DeviceContext.getInstance(); + const dcending: SerialPortEnding = dc.ending || SerialMonitor.DEFAULT_ENDING; + + const defaultBaudRate = ((ArduinoContext.arduinoApp) ? ArduinoContext.arduinoApp.settings.defaultBaudRate : null) || + SerialMonitor.DEFAULT_BAUD_RATE; + this._outputChannel = vscode.window.createOutputChannel(SerialMonitor.SERIAL_MONITOR); - this._currentBaudRate = defaultBaudRate; + this._currentBaudRate = dc.baud || defaultBaudRate; + this._portsStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, constants.statusBarPriority.PORT); this._portsStatusBar.command = "arduino.selectSerialPort"; this._portsStatusBar.tooltip = "Select Serial Port"; @@ -85,13 +91,16 @@ export class SerialMonitor implements vscode.Disposable { this._baudRateStatusBar.command = "arduino.changeBaudRate"; this._baudRateStatusBar.tooltip = "Baud Rate"; this._baudRateStatusBar.text = defaultBaudRate.toString(); - this.updatePortListStatus(null); + this._baudRateStatusBar.show(); this._endingStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, constants.statusBarPriority.ENDING); - this._ending = SerialMonitor.DEFAULT_ENDING; + this._ending = dcending; this._endingStatusBar.command = "arduino.changeEnding"; this._endingStatusBar.tooltip = "Serial Port Line Ending"; - this._endingStatusBar.text = `No line ending`; + this._endingStatusBar.text = SerialPortEnding[dcending]; + this._endingStatusBar.show(); + + this.updatePortListStatus(null); } public get initialized(): boolean { return !!this._outputChannel; @@ -195,18 +204,18 @@ export class SerialMonitor implements vscode.Disposable { Logger.warn("No rate is selected, keep baud rate no changed."); return; } - if (!parseInt(chosen, 10)) { + const selectedRate: number = parseInt(chosen, 10); + if (!parseInt(chosen, 10) || (constants.SUPPORTED_BAUD_RATES.indexOf(selectedRate) === -1)) { Logger.warn("Invalid baud rate, keep baud rate no changed.", { value: chosen }); return; } - if (!this._serialPortCtrl) { - Logger.warn("Serial Monitor have not been started."); - return; - } - const selectedRate: number = parseInt(chosen, 10); - await this._serialPortCtrl.changeBaudRate(selectedRate); + const dc = DeviceContext.getInstance(); + dc.baud = selectedRate; this._currentBaudRate = selectedRate; this._baudRateStatusBar.text = chosen; + if (this._serialPortCtrl) { + await this._serialPortCtrl.changeBaudRate(selectedRate); + } } public async changeEnding() { @@ -217,9 +226,13 @@ export class SerialMonitor implements vscode.Disposable { if (!chosen) { return; } + const dc = DeviceContext.getInstance(); + dc.ending = SerialPortEnding[chosen]; this._ending = SerialPortEnding[chosen]; - this._serialPortCtrl.changeEnding(this._ending); this._endingStatusBar.text = chosen; + if (this._serialPortCtrl) { + this._serialPortCtrl.changeEnding(this._ending); + } } public async closeSerialMonitor(port: string, showWarning: boolean = true): Promise { @@ -256,14 +269,14 @@ export class SerialMonitor implements vscode.Disposable { this._openPortStatusBar.command = "arduino.closeSerialMonitor"; this._openPortStatusBar.text = `$(x)`; this._openPortStatusBar.tooltip = "Close Serial Monitor"; - this._baudRateStatusBar.show(); - this._endingStatusBar.show(); + //this._baudRateStatusBar.show(); + //this._endingStatusBar.show(); } else { this._openPortStatusBar.command = "arduino.openSerialMonitor"; this._openPortStatusBar.text = `$(plug)`; this._openPortStatusBar.tooltip = "Open Serial Monitor"; - this._baudRateStatusBar.hide(); - this._endingStatusBar.hide(); + //this._baudRateStatusBar.hide(); + //this._endingStatusBar.hide(); } } diff --git a/src/serialmonitor/serialportctrl.ts b/src/serialmonitor/serialportctrl.ts index a989f641..80614194 100644 --- a/src/serialmonitor/serialportctrl.ts +++ b/src/serialmonitor/serialportctrl.ts @@ -50,6 +50,7 @@ export class SerialPortCtrl { this._currentBaudRate = baudRate; this._currentPort = port; this._ending = ending; + } public get isActive(): boolean { @@ -61,7 +62,8 @@ export class SerialPortCtrl { } public open(): Promise { - this._outputChannel.appendLine(`[Starting] Opening the serial port - ${this._currentPort}`); + this._outputChannel.appendLine(`[Starting] Opening the serial port - ${this._currentPort} @ ${this._currentBaudRate} baud.`); + this._outputChannel.appendLine(`[Info] Line Ending is ${SerialPortEnding[this._ending]}`); return new Promise((resolve, reject) => { if (this._currentSerialPort && this._currentSerialPort.isOpen()) { this._currentSerialPort.close((err) => { @@ -101,7 +103,7 @@ export class SerialPortCtrl { }); this._currentSerialPort.on("error", (_error) => { - this._outputChannel.appendLine("[Error]" + _error.toString()); + this._outputChannel.appendLine("[Error] " + _error.toString()); }); } }); @@ -154,7 +156,7 @@ export class SerialPortCtrl { } this._currentSerialPort.close((err) => { if (this._outputChannel) { - this._outputChannel.appendLine(`[Done] Closed the serial port ${os.EOL}`); + this._outputChannel.appendLine(`[Done] Closed the serial port ${this._currentPort} ${os.EOL}`); } this._currentSerialPort = null; if (err) { @@ -166,6 +168,8 @@ export class SerialPortCtrl { }); } public changeBaudRate(newRate: number): Promise { + + this._outputChannel.appendLine(`[Info] Baud Rate set to ${newRate}`); return new Promise((resolve, reject) => { this._currentBaudRate = newRate; if (!this._currentSerialPort || !this.isActive) { @@ -182,6 +186,7 @@ export class SerialPortCtrl { }); } public changeEnding(newEnding: SerialPortEnding) { + this._outputChannel.appendLine(`[Info] Line Endings set to ${SerialPortEnding[newEnding]}`); this._ending = newEnding; } }