diff --git a/.github/workflows/arduino_ci.yml b/.github/workflows/arduino_ci.yml index 4dcfddb..3c8c64b 100644 --- a/.github/workflows/arduino_ci.yml +++ b/.github/workflows/arduino_ci.yml @@ -111,8 +111,11 @@ jobs: version: latest - name: Adafruit BNO055 version: latest + - name: TinyGPSPlus + version: latest - source-url: https://github.com/uChip/MCP342X.git - source-url: https://github.com/core-rocket/CCP.git + - source-url: https://github.com/core-rocket/Opener.git - source-url: https://github.com/coryjfowler/MCP_CAN_lib.git - source-url: https://github.com/771-8bit/W25Q512.git - source-url: https://github.com/sdesalas/Arduino-Queue.h.git diff --git a/Ground/Ground.ino b/Ground/Ground.ino new file mode 100644 index 0000000..577b0bb --- /dev/null +++ b/Ground/Ground.ino @@ -0,0 +1,103 @@ +#define Serial_ES920 Serial1 +bool need_uplink = false; +String uplink_string = ""; +typedef enum { + SENDING, + FREE +} MODE; +MODE mode = FREE; +uint32_t send_millis = millis(); +uint32_t timeout_ms = 3000; + +void setup() { + //Serial.setFIFOSize(64); + Serial.begin(115200); + + Serial_ES920.begin(115200); + while (Serial_ES920.available()) { + Serial_ES920.read(); + } +} + +void loop() { + while (Serial.available()) { + uplink_string = Serial.readStringUntil('\n'); + uplink_string.trim(); + need_uplink = true; + } + + if ((mode == FREE) && Serial_ES920.available()) { + String downlink = Serial_ES920.readStringUntil('\n'); + // Serial.print("raw:"); + // Serial.println(downlink); + downlink.trim(); + + char rssi_char[] = "FFFF"; + downlink.substring(0, 4).toCharArray(rssi_char, 5); + int16_t rssi_long = rssi(rssi_char); + + String downlink_ASCII = downlink.substring(4, downlink.length()); + + Serial.print(rssi_long); + Serial.print(","); + Serial.println(downlink_ASCII); + + if (need_uplink) { + delay(50); + need_uplink = false; + Serial_ES920.println(uplink_string); + mode = SENDING; + send_millis = millis(); + Serial.print("uplink "); + Serial.println(uplink_string); + } + } + + if (mode == SENDING) { + if (Serial_ES920.available()) { + String response = Serial_ES920.readStringUntil('\n'); + response.trim(); + mode = FREE; + Serial.print("response from ES920LR:"); + Serial.println(response); + } + if (millis() - send_millis > timeout_ms) { + mode = FREE; + Serial.print("timeout"); + } + } +} + +int16_t rssi(char *_rssi_char) { + char *e; + return strtol(_rssi_char, &e, 16) - 65536; +} + +// GROUND +// configuration setting is below. +// ------------------------------------- +// Node : EndDevice +// Band Width : 125kHz +// Spreading Factor : 11 +// Effective Bitrate : 537bps +// Channel : 2 +// PAN ID : 0001 +// Own Node ID : 0001 +// Destination ID : 0000 +// Acknowledge : OFF +// Retry count : 3 +// Transfer Mode : Payload +// Receive Node ID information : OFF +// RSSI information : ON +// Config/Operation : Operation +// UART baudrate : 115200 +// Sleep Mode : No Sleep +// Sleep Time : 50 +// Output Power : 13dBm +// Format : ASCII +// Send Time : 0 +// Send Data : +// AES Key : 00000000000000000000000000000000 +// RF Mode : TxRx +// Protocol Type : Private LoRa +// Rx Boosted : ON diff --git a/Main/Main.ino b/Main/Main.ino index 0d5e8e7..39c47d3 100644 --- a/Main/Main.ino +++ b/Main/Main.ino @@ -7,6 +7,28 @@ float data_bme_temperature_degC = 0; float data_bme_altitude_m = 0; uint32_t data_gnss_latitude_udeg = 0; uint32_t data_gnss_longitude_udeg = 0; +float data_bat_v = 0; +float data_ext_v = 0; +bool data_key_sw_active = false; + +// pinout +const pin_size_t BNO_SDA = 4; +const pin_size_t BNO_SCL = 5; +const pin_size_t VALVE_TX = 6; +const pin_size_t VALVE_RX = 7; +const pin_size_t ES920_TX = 8; +const pin_size_t ES920_RX = 9; +const pin_size_t BME_SDA = 10; +const pin_size_t BME_SCL = 11; +const pin_size_t E220_TX = 12; +const pin_size_t E220_RX = 13; +const pin_size_t GNSS_TX = 14; +const pin_size_t GNSS_RX = 15; +const pin_size_t KEY_SW = 20; +// const pin_size_t SERVO_1 = 21; +// const pin_size_t SERVO_2 = 22; +const pin_size_t EXT_V = 26; +const pin_size_t BAT_V = 27; // Servo @@ -15,68 +37,91 @@ uint32_t data_gnss_longitude_udeg = 0; // BNO055 - #include "MedianFilterLib.h" - #include - #include - #include - #include - - double z = 0; - float medianaccel = 0; //加速度中央値計算 - float medianaltitude = 0; //高度中央値計算 - int phase_now = 0; //現在のフェーズを区別(0=CHEAK,1=READY,2=FLIGHT,3=OPENED) - int Openjudge = 1; //開放禁止コマンド用状態表示用(0=NOT_OPEN,1=OPEN) - unsigned long time_data = 0; //離床判定タイマー(燃焼終了検知) - bool altitudeJudge = 0; //高度による離床・開放のフェーズ区別変数(0=離床, 1=開放) //ここでフェーズ移行用の変数を2つ用意したのは、開放動作の終了を指示するためである - bool accelJudge = 0; //加速度による離床・開放のフェーズ区別変数(0=離床, 1=開放) - const int Count = 10; //1度の中央値計算で要するデータ数 - float altitude[10]; //高度データを格納する配列 - float accel[10]; //加速度データを格納する配列 - int altitudeIndex = 0; //高度データ配列内の現在のインデックス数 - int accelIndex = 0; //加速度データ配列内の現在のインデックス数 - int consecutivealtitudeCount = 0; //高度による離床・開放判定の閾値超過連続回数の記録変数 - int cosecutiveaccelCount = 0; //加速度による離床・開放判定の閾値超過連続回数の記録変数 - float altitudeReleseThreshold = 2.00; //高度による離床判定の閾値 - float accelReleseThreshold = 20; //加速度による離床判定の閾値 - float altitudeOpenThreshold = 0.50; //高度による開放判定の閾値 - float accelOpenThreshold = 5.00; //加速度による開放判定の閾値 - //BNO設定 - /* Set the delay between fresh samples */ - uint16_t BNO055_SAMPLERATE_DELAY_MS = 100; - - // Check I2C device address and correct line below (by default address is 0x29 or 0x28) - // id, address - Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28, &Wire); +#include +#include +#include +#include +Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28, &Wire); +sensors_event_t accelerometerData; // BME280 - +#include +Adafruit_BME280 bme; +const float SEALEVELPRESSURE_HPA = 1013.25; // SAM-M8Q - +#include +TinyGPSPlus gps; +SerialPIO Serial_GNSS(GNSS_TX, GNSS_RX, 512); +// https://arduino-pico.readthedocs.io/en/latest/piouart.html // ES920LR - +#define Serial_ES920 Serial2 +// https://moyoi-memo.hatenablog.com/entry/2022/02/15/112100 +String downlink = ""; +String response = ""; +bool need_response_usb = false; +bool need_response_es920 = false; // W25Q128 +// Opener +#include "myOpener.h" +MY_OPENER opener(OPENER::SHINSASYO); + +// Valve +char valve_mode = '/'; +SerialPIO Serial_Valve(VALVE_TX, VALVE_RX, 32); // setup()ではdelay()使用可 void setup() { + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); + delay(500); // デバッグ出力 Serial.begin(115200); - //BNO055 - if (!bno.begin()) { - /* There was a problem detecting the BNO055 ... check your connections */ - Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!"); - while (1) - ; + + Wire.setSDA(BNO_SDA); + Wire.setSCL(BNO_SCL); + while (!bno.begin()) { + Serial.print("BNO055 ERR"); + delay(100); + } + + Wire1.setSDA(BME_SDA); + Wire1.setSCL(BME_SCL); + while (!bme.begin(0x76, &Wire1)) { + Serial.print("BME280 ERR"); + delay(100); + } + bme.setSampling( + Adafruit_BME280::MODE_NORMAL, + Adafruit_BME280::SAMPLING_X1, + Adafruit_BME280::SAMPLING_X2, + Adafruit_BME280::SAMPLING_NONE, + Adafruit_BME280::FILTER_X16, + Adafruit_BME280::STANDBY_MS_0_5); + + analogReadResolution(12); + pinMode(KEY_SW, INPUT); + + Serial_ES920.setTX(ES920_TX); + Serial_ES920.setRX(ES920_RX); + Serial_ES920.setFIFOSize(64); + Serial_ES920.begin(115200); + while (Serial_ES920.available()) { + Serial_ES920.read(); } + + Serial_GNSS.begin(9600); + Serial_Valve.begin(115200); + + opener.init(); } // loop()と,ここから呼び出される関数ではdelay()使用禁止 void loop() { - static uint32_t time_100Hz = 0; if (millis() - time_100Hz >= 10) { time_100Hz += 10; @@ -88,201 +133,210 @@ void loop() { // 10Hzで実行する処理 + data_bat_v = analogRead(BAT_V) * 3.3 * 11 / (1 << 12); + data_ext_v = analogRead(EXT_V) * 3.3 * 11 / (1 << 12); + + // フライト = 回路としてOPEN = LOW + // バッテリー駆動でなくUSB駆動の場合常にLOWなので除外 + data_key_sw_active = (digitalRead(KEY_SW) == LOW) && data_bat_v > 1; + static bool last_data_key_sw_active = false; + if (data_key_sw_active && !last_data_key_sw_active && opener.mode == OPENER::CHECK) { + opener.goREADY(); + } + if (!data_key_sw_active && last_data_key_sw_active) { + if (opener.open_judge.prohibitOpen) { + opener.goCHECK(); + } else { + opener.goCHECK(); + opener.clear_prohibitOpen(); + } + } + last_data_key_sw_active = data_key_sw_active; + // デバッグ出力 - Serial.print("BNO055, "); - Serial.print(data_bno_accel_x_mss); - Serial.print(", "); - Serial.print(data_bno_accel_y_mss); - Serial.print(", "); - Serial.print(data_bno_accel_z_mss); - Serial.print(", "); - - Serial.print("BNO055, "); - Serial.print(data_bme_pressure_hPa); - Serial.print(", "); - Serial.print(data_bme_temperature_degC); - Serial.print(", "); - Serial.print(data_bme_altitude_m); - Serial.print(", "); - - Serial.print("GNSS, "); - Serial.print(data_gnss_latitude_udeg); - Serial.print(", "); - Serial.print(data_gnss_latitude_udeg); - Serial.print(", "); + if (need_response_usb) { + Serial.println("response:" + response); + need_response_usb = false; + } else { + Serial.println(downlink); + } + // Serial.print("BNO055, "); + // Serial.print(data_bno_accel_x_mss); + // Serial.print(", "); + // Serial.print(data_bno_accel_y_mss); + // Serial.print(", "); + // Serial.print(data_bno_accel_z_mss); + // Serial.print(", "); + + // Serial.print("BME280, "); + // Serial.print(data_bme_pressure_hPa); + // Serial.print(", "); + // Serial.print(data_bme_temperature_degC); + // Serial.print(", "); + // Serial.print(data_bme_altitude_m); + // Serial.print(", "); + + // Serial.print("GNSS, "); + // Serial.print(data_gnss_latitude_udeg); + // Serial.print(", "); + // Serial.print(data_gnss_longitude_udeg); + // Serial.print(", "); + + // Serial.print("voltage, "); + // Serial.print(data_bat_v); + // Serial.print(", "); + // Serial.print(data_ext_v); + // Serial.print(", "); + // Serial.print("\n"); } // 100Hzで実行する処理 // BNO055から100Hzで測定 - // ~測定処理~ - // data_bno_accel_x_mss = ~; - // data_bno_accel_y_mss = ~; - // data_bno_accel_z_mss = ~; - + bno.getEvent(&accelerometerData, Adafruit_BNO055::VECTOR_ACCELEROMETER); + data_bno_accel_x_mss = accelerometerData.acceleration.x; + data_bno_accel_y_mss = accelerometerData.acceleration.y; + data_bno_accel_z_mss = accelerometerData.acceleration.z; // BME280から100Hzで測定 - // ~測定処理~ - // data_bme_pressure_hPa = ~; - // data_bme_temperature_degC = ~; - // data_bme_altitude_m = ~; + data_bme_pressure_hPa = bme.readPressure() / 100.0F; + data_bme_temperature_degC = bme.readTemperature(); + data_bme_altitude_m = bme.readAltitude(SEALEVELPRESSURE_HPA); + + bool new_judge = opener.opener_100Hz(-data_bno_accel_z_mss, data_bme_altitude_m); } + // 常に実行する処理 - //could add VECTOR_ACCELEROMETER, VECTOR_MAGNETOMETER,VECTOR_GRAVITY... - sensors_event_t accelerometerData; - //CHEACK・NOTOPEN・READYコマンド受信 - if (Serial.available() > 0) { - String input = Serial.readStringUntil('\n'); // 改行までの入力を読み取る - Serial.println(input); - if (input.substring(0, input.length() - 1) == "CHECK") { //CHECKコマンド - phase_now = 0; // "CHECK"が入力された場合、phaseに0を代入 - Serial.println("CHECK_transitioned"); - } else if (input.substring(0, input.length() - 1) == "NOTOPEN") { //開放禁止コマンド - Openjudge = 0; // "NOTOPEN"が入力された場合、Openjudgeに0(開放禁止)を代入 - Serial.println("NOTOPEN_Openjudge=0"); - } else if (input.substring(0, input.length() - 1) == "OPEN") { //開放禁止取り消しコマンド - Openjudge = 1; // "OPEN"が入力された場合、Openjudgeに1を代入 - Serial.println("OPEN_Openjudge=1"); - } - } - //READYコマンド(CHECKphaseであることが条件) - if (Serial.available() > 0) { - String input = Serial.readStringUntil('\n'); // 改行までの入力を読み取る - if (phase_now == 0) { - if (input.substring(0, input.length() - 1) == "READY") { //READYコマンド - phase_now = 1; // "READY"が入力された場合、phase_nowに1を代入する - Serial.println("READY_transitioned"); - } - } - } - //離床判定 - if (phase_now == 1 && altitudeJudge == 0 && accelJudge == 0) { //READYフェーズに移行かつ、離床フェーズである場合 - //高度による離床判定 - //高度のデータを配列に格納 - altitude[altitudeIndex] = altitudeValue; //BMEによって取得した値を代入する - altitudeIndex = (altitudeIndex + 1) % Count; - - //高度データが10回読み取られたら中央値を計算 - if (altitudeIndex == 0) { - medianaltitude = MedianFilter(altitude, Count); - altitudeIndex = 0; - } - - //高度の中央値が閾値を超えた場合、連続回数に+1 - if (medianaltitude > altitudeReleseThreshold) { - consecutivealtitudeCount++; - } else { - consecutivealtitudeCount = 0; //閾値を下回ったら連続回数を0へリセット - } - - //加速度による離床判定 - //加速度のデータを配列に格納 - bno.getEvent(&accelerometerData, Adafruit_BNO055::VECTOR_ACCELEROMETER); - accel[accelIndex] = bnoEvent(&accelerometerData); - accelIndex = (accelIndex + 1) % Count; - - //加速度データが10回読み取られたら中央値を計算 - if (altitudeIndex == 0) { - medianaccel = MedianFilter(accel, Count); - accelIndex = 0; - } - - //加速度の中央値が閾値を超えた場合、連続回数に+1 - if (medianaccel > accelReleaseThreshold) { - cosecutiveaccelCount++; - } else { - cosecutiveaccelCount = 0; //閾値を下回ったら連続回数を0へリセット - } - - //高度・加速度による離床判定 - if (consecutivealtitudeCount == 5) { //高度と加速度の閾値超過連続回数がどちらか5回以上になった場合 - altitudeJudge = 1; //高度によって開放フェーズへ移行 //"Judge = 0"を実行条件とするif文の中で"Judge = 1"としたらどうなる? - consecutivealtitudeCount = 0; //高度の連続閾値超過回数をリセット - phase_now = 2; - Serial.println("FLIGHT_transitioned"); //シリアルモニタに状態移行を表示 - accelOpenThreshold = -10; //開放判定に用いる加速度の閾値変(上回る閾値から下回る閾値へ) - time_data = millis(); //離床判定タイマー - //後々、CAN通信で”離床判定”とダウンリンクするように設定 - } else if (cosecutiveaccelCount == 5) { - accelJudge = 1; //加速度によって開放フェーズ平行 - cosecutiveaccelCount = 0; //加速度の連続閾値超過回数をリセット - phase_now = 2; - Serial.println("FLIGHT_transitioned"); //シリアルモニタに状態移行を表示 - accelOpenThreshold = -10; //開放判定に用いる加速度の閾値変(上回る閾値から下回る閾値へ) - time_data = millis(); //離床判定タイマー - //後々、CAN通信で”離床判定”とダウンリンクするように設定 - } - } - - //開放判定 - if (phase_now == 2) { - //高度による開放判定 - //高度のデータを配列に格納 - altitude[altitudeIndex] = altitudeValue; //BMEによって取得した値を代入する - altitudeIndex = (altitudeIndex + 1) % Count; - - //高度データが10回読み取られたら中央値を計算 - if (altitudeIndex == 0) { - medianaltitude = MedianFilter(altitude, Count); - altitudeIndex = 0; - } - - //高度の中央値が閾値を超えた場合、連続回数に+1 - if (medianaltitude > altitudeOpenThreshold) { - consecutivealtitudeCount++; - } else { - consecutivealtitudeCount = 0; //閾値を下回ったら連続回数を0へリセット - } - - //加速度による開放判定 - //加速度のデータを配列に格納 - bno.getEvent(&accelerometerData, Adafruit_BNO055::VECTOR_ACCELEROMETER); - accel[accelIndex] = bnoEvent(&accelerometerData); - accelIndex = (accelIndex + 1) % Count; - - //加速度データが10回読み取られたら中央値を計算 - if (altitudeIndex == 0) { - medianaccel = MedianFilter(accel, Count); - accelIndex = 0; - } - - //加速度の中央値が閾値を下回った場合、連続回数に+1 - if (medianaccel < accelOpenThreshold) { - cosecutiveaccelCount++; - } else { - cosecutiveaccelCount = 0; //閾値を下回ったら連続回数を0へリセット - } - - //高度・加速度による開放判定 - if (((consecutivealtitudeCount == 5) || (time_data > 5000 /*とりあえず燃焼時間5秒設定*/)) && ((cosecutiveaccelCount == 5) && (time_data > 5000 /*とりあえず燃焼時間5秒設定*/)) && Openjudge == 1) { //高度と加速度の閾値超過連続回数がともに5回以上かつ開放禁止コマンドが入力されていないとき - phase_now = 3; - Serial.println("OPENED_transitioned"); - altitudeJudge = 0; //高度によって開放フェーズを終了 - accelJudge = 1; //加速度によって開放フェーズを終了 - consecutivealtitudeCount = 0; - cosecutiveaccelCount = 0; - digitalWrite(2, HIGH); //MosFetに電圧を印加 - delay(HeatingTime); //ニクロム線を規定時間加熱(8s) - digitalWrite(2, LOW); //MosFetへの電圧印加を停止 - //後々、CAN通信で”開放判定”とダウンリンクするように設定 - } - } // SAM-M8QのUARTを常に読み出し - // ~測定処理~ - // data_gnss_latitude_udeg = ~; - // data_gnss_longitude_udeg = ~; -} -//BNO055データ取得用関数 -double bnoEvent(sensors_event_t* event) { - double x = -1000000, y = -1000000; // 問題を見つけやすいダミーの値 + while (Serial_GNSS.available()) { + gps.encode(Serial_GNSS.read()); + if (gps.location.isUpdated()) { + data_gnss_latitude_udeg = gps.location.lat() * 1000000; + data_gnss_longitude_udeg = gps.location.lng() * 1000000; + } + } + + // バルブ電装状態受信 + while (Serial_Valve.available()) { + valve_mode = Serial_Valve.read(); + } + + + // テレメトリ生成 + downlink = ""; + switch (opener.mode) { + case OPENER::CHECK: + downlink += 'C'; + break; + case OPENER::READY: + downlink += 'R'; + break; + case OPENER::FLIGHT: + downlink += 'F'; + break; + case OPENER::OPENED: + downlink += 'O'; + break; + } + downlink += opener.open_judge.prohibitOpen ? 'E' : '/'; // Emergency + downlink += opener.open_judge.apogee_time ? 'T' : '/'; // Time + downlink += opener.open_judge.apogee_descending ? 'P' : '/'; // Pressure + downlink += opener.open_judge.meco_time ? 'T' : '/'; // Time + downlink += opener.open_judge.meco_acc ? 'A' : '/'; // Acceleration + if (opener.lift_off_judge == OPENER::NONE) { + downlink += '/'; + } + if (opener.lift_off_judge == OPENER::ACCSEN) { + downlink += 'A'; + } + if (opener.lift_off_judge == OPENER::ALTSEN) { + downlink += 'P'; + } + downlink += valve_mode; + downlink += String(data_key_sw_active ? 'K' : '/') + ','; // Key + downlink += String(data_bno_accel_z_mss, 1) + ','; + downlink += String(data_bme_temperature_degC, 1) + ','; + downlink += String(data_bme_altitude_m, 1) + ','; + downlink += String(data_gnss_latitude_udeg % 1000000) + ','; + downlink += String(data_gnss_longitude_udeg % 1000000) + ','; + downlink += String(data_bat_v, 1) + ','; + downlink += String(static_cast(data_ext_v)); - if (event->type == SENSOR_TYPE_ACCELEROMETER) { - if (event->acceleration.z != 0) {//データ取得エラーを排除 - z = event->acceleration.z; + // テレメトリダウンリンク + const uint32_t downlink_rate_ms = 2500; + static uint32_t last_downlink_ms = 0; + if (millis() - last_downlink_ms > downlink_rate_ms) { + last_downlink_ms = millis(); + if (need_response_es920) { + Serial_ES920.print("response:" + response + "\r\n"); + need_response_es920 = false; + } else { + Serial_ES920.print(downlink + "\r\n"); } } - return z; + + + // コマンドアップリンク + String uplink = ""; + if (Serial.available()) { + uplink = Serial.readStringUntil('\n'); + } + if (Serial_ES920.available()) { + uplink = Serial_ES920.readStringUntil('\n'); + } + uplink.trim(); + // if (uplink != "") { + // Serial.print("uplink:"); + // Serial.println(uplink); + // } + + if (uplink.indexOf("NG") == 0) { + Serial.println(uplink); + } + + if (uplink == "emst") { + opener.prohibitOpen(); + } + if (uplink == "clr") { + opener.clear_prohibitOpen(); + } + if (uplink == "open") { + opener.goCHECK(); + opener.clear_prohibitOpen(); + opener.manualOpen(); + } + if (uplink == "close") { + opener.goCHECK(); + opener.manualClose(); + } + if (uplink == "check") { + opener.goCHECK(); + } + if (uplink == "ready") { + opener.goREADY(); + } + + if (uplink == "drain-start") { + Serial_Valve.print("drain-start\n"); + } + if (uplink == "drain-stop") { + Serial_Valve.print("drain-stop\n"); + } + if (uplink == "valve") { + Serial_Valve.print("valve\n"); + } + if (uplink == "valve-check") { + Serial_Valve.print("valve-check\n"); + } + + float uplink_float = uplink.toFloat(); + if (uplink_float != 0) { + opener.set_open_threshold_time_ms(uplink_float * 1000); + response = "open:" + String(static_cast(opener.get_open_threshold_time_ms()) / 1000.0, 2); + need_response_usb = true; + need_response_es920 = true; + } } diff --git a/Main/myOpener.cpp b/Main/myOpener.cpp new file mode 100644 index 0000000..1ee1067 --- /dev/null +++ b/Main/myOpener.cpp @@ -0,0 +1,24 @@ +#include +#include "myOpener.h" + +#include +const pin_size_t SERVO_1 = 21; +const pin_size_t SERVO_2 = 22; +Servo servo1; +Servo servo2; + +void MY_OPENER::init() { + servo1.attach(SERVO_1); + servo2.attach(SERVO_2); + OPENER::init(); +} + +void MY_OPENER::open() { + servo1.write(120); + servo2.write(120); +} + +void MY_OPENER::close() { + servo1.write(30); + servo2.write(30); +} diff --git a/Main/myOpener.h b/Main/myOpener.h new file mode 100644 index 0000000..fb2c008 --- /dev/null +++ b/Main/myOpener.h @@ -0,0 +1,54 @@ +#ifndef MY_OPENER_H +#define MY_OPENER_H + +#include +#include + +class MY_OPENER : public OPENER { +protected: + //! 開放機構を開く + void open(); + //! 開放機構を閉じる + void close(); + +public: + /*! コンストラクタ + * @param setting 閾値をフライト用に設定するか,審査書用に設定するか + */ + MY_OPENER(OPENER::SETTING setting) { + //! 頂点判定に使われる,0.1秒間の高度変化の閾値 + open_threshold_altitude_m = 0.5; + //! 燃焼終了に使われる,加速度の閾値 + open_threshold_ac_mss = 5; + //! opener_10Hz()が適切なタイミングで呼ばれているかの判定に使われる,10Hzの周期 + period_10Hz_ms = 150; // 10Hz+50ms + //! opener_100Hz()が適切なタイミングで呼ばれているかの判定に使われる,100Hzの周期 + period_100Hz_ms = 20; // 100Hz+10ms + //! 閾値以上の加速度が何回連続したときに離床判定・燃焼終了判定を行うかという回数 + ACC_threshold_count = 5; + //! 離床判定にかかる時間 + flight_judgement_duration_ms = ACC_threshold_count * 100; + + fm_lift_off_threshold_altitude_m = 1.0; + fm_lift_off_threshold_ac_mss = 25.0; + fm_ALT_oversampling_count = 1; + fm_ALT_threshold_count = ACC_threshold_count; + + shinsasyo_lift_off_threshold_altitude_m = 0.5; + shinsasyo_lift_off_threshold_ac_mss = 9.0; + shinsasyo_ALT_oversampling_count = 5.0; + shinsasyo_ALT_threshold_count = 2; + + //! 離床判定後,燃焼中と判断し開放判定を行わない時間[ms] + meco_threshold_time_ms = 5000; + //! 開放機構の動作にかかる時間を引いた,離床から開放までの時間のシム値[ms]の初期値 + open_threshold_time_ms = 13000; + + //! パラメータをFMと審査書で切り替える + switch_parameter(setting); + } + + void init(); +}; + +#endif // MY_OPENER_H diff --git a/test/Main_ES920/Main_ES920.ino b/test/Main_ES920/Main_ES920.ino new file mode 100644 index 0000000..cf41b19 --- /dev/null +++ b/test/Main_ES920/Main_ES920.ino @@ -0,0 +1,54 @@ +#define Serial_ES920 Serial2 +const pin_size_t ES920_TX = 8; +const pin_size_t ES920_RX = 9; + +void setup() { + // put your setup code here, to run once: + //Serial.setFIFOSize(64); + Serial.begin(115200); + + Serial_ES920.setTX(ES920_TX); + Serial_ES920.setRX(ES920_RX); + Serial_ES920.setFIFOSize(64); + Serial_ES920.begin(115200); + while (Serial_ES920.available()) { + Serial_ES920.read(); + } +} + +void loop() { + // put your main code here, to run repeatedly: + if (Serial.available()) { + Serial_ES920.write(Serial.read()); + } + + if (Serial_ES920.available()) { + Serial.write(Serial_ES920.read()); + } +} + +// ROCKET +// configuration setting is below. +// ------------------------------------- +// Node : Coordinator +// Band Width : 125kHz +// Spreading Factor : 11 +// Effective Bitrate : 538bps +// Channel : 2 +// PAN ID : 0001 +// Own Node ID : 0000 +// Destination ID : FFFF +// Acknowledge : OFF +// Retry count : 3 +// Transfer Mode : Payload +// Receive Node ID information : OFF +// RSSI information : OFF +// Config/Operation : Operation +// UART baudrate : 115200 +// Sleep Mode : No Sleep +// Sleep Time : 50 +// Output Power : 13dBm +// Format : ASCII +// Send Time : 0 +// Send Data : +// AES Key : 00000000000000000000000000000000