Dateien nach "/" hochladen
This commit is contained in:
commit
1a208fef0a
17
README.md
Normal file
17
README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# RIU (Remote Interface Unit)
|
||||||
|
## Setup
|
||||||
|
### Hardware
|
||||||
|
- Arduino Uno
|
||||||
|
- BMP280 breakout board (Pressure and Temperature sensor)
|
||||||
|
#### Wiring
|
||||||
|
- BMP280 VCC -> Arduino 3.3V
|
||||||
|
- BMP280 GND -> Arduino GND
|
||||||
|
- BMP280 SDA -> Arduino SDA
|
||||||
|
- BMP280 SCL -> Arduino SCL
|
||||||
|
### Software
|
||||||
|
- Arduino IDE
|
||||||
|
- Adafruit BMP280 library
|
||||||
|
## Usage
|
||||||
|
- Upload the code to the Arduino
|
||||||
|
- Open the serial monitor and type commands
|
||||||
|
- Alternatively, directly send commands to the Arduino via serial communication
|
135
RIU-datasheet.md
Normal file
135
RIU-datasheet.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
# Tübingen Instruments RIU-9000 Datasheet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Manufacturer: TI (Tübingen Instruments)
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
The RIU-9000 is a versatile Remote Interface Unit (RIU) designed for spacecraft sensor management. This device interfaces with an Adafruit BMP280 sensor to provide accurate pressure and temperature readings. The RIU-9000 allows users to configure sensor parameters and retrieve sensor data through a structured 4-step communication protocol.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- **Sensor Support**: Integrated support for BMP280 pressure and temperature sensor.
|
||||||
|
- **Configurable Parameters**: Offset and sampling rate adjustments for both pressure and temperature readings.
|
||||||
|
- **Reliable Communication**: 4-step communication protocol to ensure data integrity.
|
||||||
|
- **Error Handling**: Error messages for invalid commands or parameters.
|
||||||
|
- **Industry Standard Data Format**: Sensor data is sent in binary format representing 32 bit IEEE-754 Floating Point values.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Commands and Responses
|
||||||
|
|
||||||
|
#### General Format
|
||||||
|
Commands should be sent as strings over the serial interface at 115200 baud rate. Commands are case-sensitive and must be followed by a newline character (`\n`). Parameters and values should be separated by a space. Responses from the RIU-9000 will also be in string format.
|
||||||
|
|
||||||
|
#### STARTUP
|
||||||
|
- **Command**: `STARTUP`
|
||||||
|
- **Response**: `READY - Tübingen Instruments RIU-9000`
|
||||||
|
- **Description**: Initializes the device. This command must be sent before any other commands are accepted.
|
||||||
|
|
||||||
|
#### GET_SENSOR
|
||||||
|
- **Command**: `GET_SENSOR [COMMAND] [SENSOR]`
|
||||||
|
- **Description**: Initiates a 4-step communication process to read sensor data.
|
||||||
|
- **Steps**:
|
||||||
|
1. **REQUEST**: Command the device to read sensor value.
|
||||||
|
- **Command**: `GET_SENSOR REQUEST [SENSOR]`
|
||||||
|
- **Response**: `OK` or `ERROR`
|
||||||
|
2. **CONFIRM**: Ask if the device requested the data from the sensor.
|
||||||
|
- **Command**: `GET_SENSOR CONFIRM [SENSOR]`
|
||||||
|
- **Response**: `TRUE` or `FALSE`
|
||||||
|
3. **CHECK**: Ask if the data is present now.
|
||||||
|
- **Command**: `GET_SENSOR CHECK [SENSOR]`
|
||||||
|
- **Response**: `TRUE` or `FALSE`
|
||||||
|
4. **SEND**: Command the device to send the data to the user.
|
||||||
|
- **Command**: `GET_SENSOR SEND [SENSOR]`
|
||||||
|
- **Response**: `[DATA]` or `FALSE`
|
||||||
|
5. **CANCEL**: Cancel the sensor reading request.
|
||||||
|
- **Command**: `GET_SENSOR CANCEL [SENSOR]`
|
||||||
|
- **Response**: `OK`
|
||||||
|
|
||||||
|
#### SET_PARAMETER
|
||||||
|
- **Command**: `SET_PARAMETER [PARAM] [VALUE]`
|
||||||
|
- **Response**: `OK` or `ERROR: UNKNOWN PARAMETER`
|
||||||
|
- **Parameters**:
|
||||||
|
- `PRESSURE_OFFSET`: Sets the offset for pressure readings. (In hPa)
|
||||||
|
- `TEMPERATURE_OFFSET`: Sets the offset for temperature readings. (In °C)
|
||||||
|
- `PRESSURE_SAMPLING`: Sets the oversampling rate for the pressure sensor (`SAMPLING_NONE`, `SAMPLING_X1`, `SAMPLING_X2`, `SAMPLING_X4`, `SAMPLING_X8`, `SAMPLING_X16`).
|
||||||
|
- `TEMPERATURE_SAMPLING`: Sets the oversampling rate for the temperature sensor (`SAMPLING_NONE`, `SAMPLING_X1`, `SAMPLING_X2`, `SAMPLING_X4`, `SAMPLING_X8`, `SAMPLING_X16`).
|
||||||
|
|
||||||
|
#### GET_PARAMETER
|
||||||
|
- **Command**: `GET_PARAMETER [PARAM]`
|
||||||
|
- **Response**: `[VALUE]` or `ERROR: UNKNOWN PARAMETER`
|
||||||
|
- **Parameters**:
|
||||||
|
- `PRESSURE_OFFSET`: Retrieves the current pressure offset.
|
||||||
|
- `TEMPERATURE_OFFSET`: Retrieves the current temperature offset.
|
||||||
|
- `PRESSURE_SAMPLING`: Retrieves the current pressure oversampling rate.
|
||||||
|
- `TEMPERATURE_SAMPLING`: Retrieves the current temperature oversampling rate.
|
||||||
|
|
||||||
|
#### RESET_SENSORS
|
||||||
|
- **Command**: `RESET_SENSORS`
|
||||||
|
- **Response**: `OK`
|
||||||
|
- **Description**: Resets the request count and communication state.
|
||||||
|
|
||||||
|
#### Communication Errors
|
||||||
|
- **BUSY**: Device is busy. Every 20th request, the device will respond with `BUSY` and not process the command.
|
||||||
|
- **ERROR**: Generic error message for invalid commands or failed operations.
|
||||||
|
- **FALSE**: Response for confirmation checks that fail.
|
||||||
|
- **[NO RESPONSE]**: After 100 requests, the device will stop responding to commands until a `RESET_SENSORS` command is issued.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### Example Usage
|
||||||
|
|
||||||
|
#### Initialization
|
||||||
|
```
|
||||||
|
User: STARTUP
|
||||||
|
Device: READY
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Setting Parameters
|
||||||
|
```
|
||||||
|
User: SET_PARAMETER PRESSURE_OFFSET 10
|
||||||
|
Device: OK
|
||||||
|
|
||||||
|
User: SET_PARAMETER PRESSURE_SAMPLING SAMPLING_X4
|
||||||
|
Device: OK
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Getting Parameters
|
||||||
|
```
|
||||||
|
User: GET_PARAMETER PRESSURE_OFFSET
|
||||||
|
Device: 10
|
||||||
|
|
||||||
|
User: GET_PARAMETER PRESSURE_SAMPLING
|
||||||
|
Device: SAMPLING_X4
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Reading Sensor Data
|
||||||
|
```
|
||||||
|
User: GET_SENSOR REQUEST PRESSURE
|
||||||
|
Device: OK
|
||||||
|
|
||||||
|
User: GET_SENSOR CONFIRM PRESSURE
|
||||||
|
Device: OK
|
||||||
|
|
||||||
|
User: GET_SENSOR CHECK PRESSURE
|
||||||
|
Device: FALSE
|
||||||
|
|
||||||
|
User: GET_SENSOR CHECK PRESSURE
|
||||||
|
Device: TRUE
|
||||||
|
|
||||||
|
User: GET_SENSOR SEND PRESSURE
|
||||||
|
Device: [Binary Data]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Resetting Sensors
|
||||||
|
```
|
||||||
|
User: RESET_SENSORS
|
||||||
|
Device: OK
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
For more detailed information and troubleshooting, please refer to the official TI (Tübingen Instruments) RIU-9000 documentation.
|
||||||
|
|
||||||
|
---
|
305
RIU.ino
Normal file
305
RIU.ino
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
#include <Wire.h>
|
||||||
|
#include <Adafruit_Sensor.h>
|
||||||
|
#include <Adafruit_BMP280.h>
|
||||||
|
|
||||||
|
// BMP280 Sensor
|
||||||
|
Adafruit_BMP280 bmp; // use I2C interface
|
||||||
|
Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
|
||||||
|
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
const int MAX_REQUESTS = 100;
|
||||||
|
const int BUSY_THRESHOLD = 20;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
int pressureOffset = 0;
|
||||||
|
Adafruit_BMP280::sensor_sampling pressureSampling = Adafruit_BMP280::SAMPLING_X1;
|
||||||
|
int temperatureOffset = 0;
|
||||||
|
Adafruit_BMP280::sensor_sampling temperatureSampling = Adafruit_BMP280::SAMPLING_X1;
|
||||||
|
|
||||||
|
// State Variables
|
||||||
|
int requestCount = 0;
|
||||||
|
bool startupReceived = false;
|
||||||
|
String lastSensorValue = "";
|
||||||
|
|
||||||
|
// Communication state for 4-step process
|
||||||
|
struct CommunicationState {
|
||||||
|
bool requestConfirmed = false;
|
||||||
|
bool confirmConfirmed = false;
|
||||||
|
bool checkConfirmed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
CommunicationState commState;
|
||||||
|
|
||||||
|
// Function Prototypes
|
||||||
|
void handleCommand(String command);
|
||||||
|
void handleGetSensor(String command, String sensor);
|
||||||
|
void handleSetParameter(String param, String value);
|
||||||
|
void handleGetParameter(String param);
|
||||||
|
void resetSensors();
|
||||||
|
String getRawSensorData(String sensor);
|
||||||
|
bool randomFailure(float chance);
|
||||||
|
String* splitString(String data, char separator, int* size);
|
||||||
|
Adafruit_BMP280::sensor_sampling getSamplingFromUserInput(String value);
|
||||||
|
String samplingToString(Adafruit_BMP280::sensor_sampling sampling);
|
||||||
|
String floatToBinary(float value);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) {
|
||||||
|
; // Wait for serial port to connect.
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!startupReceived) {
|
||||||
|
if (Serial.available()) {
|
||||||
|
String command = Serial.readStringUntil('\n');
|
||||||
|
if (command.startsWith("STARTUP")) {
|
||||||
|
startupReceived = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned status = bmp.begin(0x76);
|
||||||
|
if (!status) {
|
||||||
|
Serial.println(F("Could not find a valid BMP280 sensor, check wiring or try a different address!"));
|
||||||
|
while (1) delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
|
||||||
|
temperatureSampling, /* Temp. oversampling */
|
||||||
|
pressureSampling, /* Pressure oversampling */
|
||||||
|
Adafruit_BMP280::FILTER_X16, /* Filtering. */
|
||||||
|
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
|
||||||
|
|
||||||
|
Serial.println("READY - Tübingen Instruments RIU-9000");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (Serial.available()) {
|
||||||
|
String command = Serial.readStringUntil('\n');
|
||||||
|
delay(50); // Small delay to make communication more interesting
|
||||||
|
handleCommand(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleCommand(String command) {
|
||||||
|
if (requestCount >= MAX_REQUESTS && !command.startsWith("RESET_SENSORS")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestCount > 0 && requestCount % BUSY_THRESHOLD == 0) {
|
||||||
|
Serial.println("BUSY");
|
||||||
|
requestCount++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size;
|
||||||
|
String* parts = splitString(command, ' ', &size);
|
||||||
|
|
||||||
|
if (parts[0] == "GET_SENSOR" && size == 3) {
|
||||||
|
handleGetSensor(parts[1], parts[2]);
|
||||||
|
} else if (parts[0] == "SET_PARAMETER" && size == 3) {
|
||||||
|
handleSetParameter(parts[1], parts[2]);
|
||||||
|
} else if (parts[0] == "GET_PARAMETER" && size == 2) {
|
||||||
|
handleGetParameter(parts[1]);
|
||||||
|
} else if (parts[0] == "RESET_SENSORS" && size == 1) {
|
||||||
|
resetSensors();
|
||||||
|
} else {
|
||||||
|
Serial.println("ERROR: UNKNOWN COMMAND");
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] parts;
|
||||||
|
requestCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleGetSensor(String command, String sensor) {
|
||||||
|
|
||||||
|
if (command == "REQUEST") { // request data from the RUI (which will request it from the sensor)
|
||||||
|
if (!commState.requestConfirmed && randomFailure(0.1)) {
|
||||||
|
Serial.println("ERROR");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastSensorValue = getRawSensorData(sensor);
|
||||||
|
Serial.println("OK");
|
||||||
|
commState.requestConfirmed = true;
|
||||||
|
|
||||||
|
} else if (command == "CONFIRM") { // did you request the data from the sensor?
|
||||||
|
if (!commState.confirmConfirmed && randomFailure(0.1)) {
|
||||||
|
Serial.println("FALSE");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (commState.requestConfirmed) {
|
||||||
|
Serial.println("TRUE");
|
||||||
|
commState.confirmConfirmed = true;
|
||||||
|
} else {
|
||||||
|
Serial.println("FALSE");
|
||||||
|
}
|
||||||
|
} else if (command == "CHECK") { // did you get the data from the sensor?
|
||||||
|
if (!commState.checkConfirmed && randomFailure(0.5)) {
|
||||||
|
Serial.println("FALSE");
|
||||||
|
} else {
|
||||||
|
if (commState.requestConfirmed) {
|
||||||
|
Serial.println("TRUE");
|
||||||
|
commState.checkConfirmed = true;
|
||||||
|
} else {
|
||||||
|
Serial.println("FALSE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (command == "SEND") { // send the data to the user
|
||||||
|
if (commState.requestConfirmed) {
|
||||||
|
Serial.println(lastSensorValue);
|
||||||
|
commState = CommunicationState(); // Reset communication state
|
||||||
|
} else {
|
||||||
|
Serial.println("FALSE");
|
||||||
|
}
|
||||||
|
} else if (command == "CANCEL") {
|
||||||
|
commState = CommunicationState(); // Reset communication state
|
||||||
|
Serial.println("OK");
|
||||||
|
} else {
|
||||||
|
Serial.println("ERROR: UNKNOWN COMMAND");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleSetParameter(String param, String value) {
|
||||||
|
if (param == "PRESSURE_OFFSET") {
|
||||||
|
pressureOffset = value.toInt();
|
||||||
|
Serial.println("OK");
|
||||||
|
} else if (param == "PRESSURE_SAMPLING") {
|
||||||
|
pressureSampling = getSamplingFromUserInput(value);
|
||||||
|
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
|
||||||
|
temperatureSampling, /* Temp. oversampling */
|
||||||
|
pressureSampling, /* Pressure oversampling */
|
||||||
|
Adafruit_BMP280::FILTER_X16, /* Filtering. */
|
||||||
|
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
|
||||||
|
Serial.println("OK");
|
||||||
|
} else if (param == "TEMPERATURE_OFFSET") {
|
||||||
|
temperatureOffset = value.toInt();
|
||||||
|
Serial.println("OK");
|
||||||
|
} else if (param == "TEMPERATURE_SAMPLING") {
|
||||||
|
temperatureSampling = getSamplingFromUserInput(value);
|
||||||
|
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
|
||||||
|
temperatureSampling, /* Temp. oversampling */
|
||||||
|
pressureSampling, /* Pressure oversampling */
|
||||||
|
Adafruit_BMP280::FILTER_X16, /* Filtering. */
|
||||||
|
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
|
||||||
|
Serial.println("OK");
|
||||||
|
} else {
|
||||||
|
Serial.println("ERROR: UNKNOWN PARAMETER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleGetParameter(String param) {
|
||||||
|
if (param == "PRESSURE_OFFSET") {
|
||||||
|
Serial.println(pressureOffset);
|
||||||
|
} else if (param == "PRESSURE_SAMPLING") {
|
||||||
|
Serial.println(samplingToString(pressureSampling));
|
||||||
|
} else if (param == "TEMPERATURE_OFFSET") {
|
||||||
|
Serial.println(temperatureOffset);
|
||||||
|
} else if (param == "TEMPERATURE_SAMPLING") {
|
||||||
|
Serial.println(samplingToString(temperatureSampling));
|
||||||
|
} else {
|
||||||
|
Serial.println("ERROR: UNKNOWN PARAMETER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetSensors() {
|
||||||
|
requestCount = 0;
|
||||||
|
commState = CommunicationState(); // Reset communication state
|
||||||
|
Serial.println("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
String getRawSensorData(String sensor) {
|
||||||
|
sensors_event_t temp_event, pressure_event;
|
||||||
|
|
||||||
|
if (sensor == "PRESSURE") {
|
||||||
|
bmp_pressure->getEvent(&pressure_event);
|
||||||
|
float pressure = pressure_event.pressure + pressureOffset;
|
||||||
|
return floatToBinary(pressure); // in hPa
|
||||||
|
} else if (sensor == "TEMPERATURE") {
|
||||||
|
bmp_temp->getEvent(&temp_event);
|
||||||
|
float temperature = temp_event.temperature + temperatureOffset;
|
||||||
|
return floatToBinary(temperature); // in °C
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool randomFailure(float chance) {
|
||||||
|
return random(0, 100) < (chance * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
String* splitString(String data, char separator, int* size) {
|
||||||
|
int found = 0;
|
||||||
|
int strIndex[] = {0, -1};
|
||||||
|
int maxIndex = data.length() - 1;
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
|
for (int i = 0; i <= maxIndex; i++) {
|
||||||
|
if (data.charAt(i) == separator) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String* result = new String[count];
|
||||||
|
*size = count;
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
for (int i = 0; i <= maxIndex && found < count; i++) {
|
||||||
|
if (data.charAt(i) == separator || i == maxIndex) {
|
||||||
|
strIndex[0] = strIndex[1] + 1;
|
||||||
|
strIndex[1] = (i == maxIndex) ? i + 1 : i;
|
||||||
|
result[found] = data.substring(strIndex[0], strIndex[1]);
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Adafruit_BMP280::sensor_sampling getSamplingFromUserInput(String value) {
|
||||||
|
if (value == "SAMPLING_NONE") return Adafruit_BMP280::SAMPLING_NONE;
|
||||||
|
if (value == "SAMPLING_X1") return Adafruit_BMP280::SAMPLING_X1;
|
||||||
|
if (value == "SAMPLING_X2") return Adafruit_BMP280::SAMPLING_X2;
|
||||||
|
if (value == "SAMPLING_X4") return Adafruit_BMP280::SAMPLING_X4;
|
||||||
|
if (value == "SAMPLING_X8") return Adafruit_BMP280::SAMPLING_X8;
|
||||||
|
if (value == "SAMPLING_X16") return Adafruit_BMP280::SAMPLING_X16;
|
||||||
|
return Adafruit_BMP280::SAMPLING_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
String samplingToString(Adafruit_BMP280::sensor_sampling sampling) {
|
||||||
|
switch (sampling) {
|
||||||
|
case Adafruit_BMP280::SAMPLING_NONE:
|
||||||
|
return "SAMPLING_NONE";
|
||||||
|
case Adafruit_BMP280::SAMPLING_X1:
|
||||||
|
return "SAMPLING_X1";
|
||||||
|
case Adafruit_BMP280::SAMPLING_X2:
|
||||||
|
return "SAMPLING_X2";
|
||||||
|
case Adafruit_BMP280::SAMPLING_X4:
|
||||||
|
return "SAMPLING_X4";
|
||||||
|
case Adafruit_BMP280::SAMPLING_X8:
|
||||||
|
return "SAMPLING_X8";
|
||||||
|
case Adafruit_BMP280::SAMPLING_X16:
|
||||||
|
return "SAMPLING_X16";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN_SAMPLING";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String floatToBinary(float value) {
|
||||||
|
union FloatUnion {
|
||||||
|
float value;
|
||||||
|
byte bytes[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
FloatUnion floatUnion;
|
||||||
|
floatUnion.value = value;
|
||||||
|
|
||||||
|
String binaryString = "";
|
||||||
|
for (int i = 3; i >= 0; i--) {
|
||||||
|
for (int j = 7; j >= 0; j--) {
|
||||||
|
binaryString += String((floatUnion.bytes[i] >> j) & 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return binaryString;
|
||||||
|
}
|
8
launch.json
Normal file
8
launch.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user