/// load board and settings objectsauto&& brd =the_twelite.board.use BRDC (); // load board supportauto&& set =the_twelite.settings.use<STG_STD>(); // load save/load settings(interactive mode) supportauto&& nwk =the_twelite.network.use<NWK_SIMPLE>(); // load network support
ボード、設定、ネットワークの各ビヘイビアオブジェクトの登録を行います。
インタラクティブモード
// settings: configure itemsset << SETTINGS::appname("MOT");set << SETTINGS::appid_default(DEFAULT_APP_ID); // set default appIDset << SETTINGS::ch_default(DEFAULT_CHANNEL); // set default channelset << SETTINGS::lid_default(0x1); // set default LIDset.hide_items(E_STGSTD_SETID::OPT_DWORD2, E_STGSTD_SETID::OPT_DWORD3, E_STGSTD_SETID::OPT_DWORD4, E_STGSTD_SETID::ENC_KEY_STRING, E_STGSTD_SETID::ENC_MODE);
// if SET=LOW is detected, start with intaractive mode.if (digitalRead(brd.PIN_SET) == PIN_STATE::LOW) { set << SETTINGS::open_at_start();brd.set_led(LED_TIMER::BLINK,300); // slower blinkstep.next(STATE::INTERACTIVE);return;}// load settingsset.reload(); // load from EEPROM.OPT_BITS =set.u32opt1(); // this value is not used in this example.
voidbegin() { auto&& set =the_twelite.settings.use<STG_STD>();if (!set.is_screen_opened()) { // sleep immediately, waiting for the first capture.sleepNow(); }}
case STATE::INIT:brd.sns_MC3630.get_que().clear(); // clear queue in advance (just in case).memset(&sensor,0,sizeof(sensor)); // clear sensor datastep.next(STATE::START_CAPTURE);break;
case STATE::START_CAPTURE:brd.sns_MC3630.begin( // 400Hz, +/-4G range, get four samples and will average them. SnsMC3630::Settings( SnsMC3630::MODE_LP_400HZ, SnsMC3630::RANGE_PLUS_MINUS_4G, N_SAMPLES)); step.set_timeout(100);step.next(STATE::WAIT_CAPTURE);break;
// get all samples and average them.for (auto&& v:brd.sns_MC3630.get_que()) {sensor.x_ave +=v.x;sensor.y_ave +=v.y;sensor.z_ave +=v.z;}if (sensor.n_samples == N_SAMPLES) { // if N_SAMPLES == 2^n, division is much faster.sensor.x_ave /= N_SAMPLES;sensor.y_ave /= N_SAMPLES;sensor.z_ave /= N_SAMPLES;}...
すべてのサンプルデータに対して読み出し、平均値をとる処理をします。
// can also be:// int32_t x_max = -999999, x_min = 999999;// for (auto&& v: brd.sns_MC3630.get_que()) {// if (v.x >= x_max) x_max = v.x;// if (v.y <= x_min) x_min = v.x;// ...// } auto&& x_minmax = std::minmax_element(get_axis_x_iter(brd.sns_MC3630.get_que().begin()),get_axis_x_iter(brd.sns_MC3630.get_que().end()));sensor.x_min =*x_minmax.first;sensor.x_max =*x_minmax.second;...
ここでは取得されたサンプルに対して、各軸に対応するイテレータを用い最大・最小を得ています。
C++ Standard Template Library のアルゴリズムを使用する例としてstd::mimmax_element紹介していますが、コメント内のようにforループ内で最大、最小を求めても構いません。
if (brd.sns_MC3630.available()) { ...brd.sns_MC3630.get_que().clear(); // clean up the queuestep.next(STATE::REQUEST_TX); // next state} elseif (step.is_timeout()) { Serial << crlf <<"!!!FATAL: SENSOR CAPTURE TIMEOUT.";step.next(STATE::EXIT_FATAL);}break;
MWX_APIRETTxReq() {auto&& brd =the_twelite.board.use<PAL_MOT>(); MWX_APIRET ret =false; // prepare tx packetif (auto&& pkt =the_twelite.network.use<NWK_SIMPLE>().prepare_tx_packet()) { // set tx packet behavior pkt <<tx_addr(0x00) // 0..0xFF (LID 0:parent, FE:child w/ no id, FF:LID broad cast), 0x8XXXXXXX (long address)<<tx_retry(0x1) // set retry (0x1 send two times in total)<<tx_packet_delay(0,0,2); // send packet w/ delay // prepare packet (first)pack_bytes(pkt.get_payload() // set payload data objects.,make_pair(FOURCHARS,4) // just to see packet identification, you can design in any.,uint16_t(sensor.n_seq),uint8_t(sensor.n_samples),uint16_t(sensor.x_ave),uint16_t(sensor.y_ave),uint16_t(sensor.z_ave),uint16_t(sensor.x_min),uint16_t(sensor.y_min),uint16_t(sensor.z_min),uint16_t(sensor.x_max),uint16_t(sensor.y_max),uint16_t(sensor.z_max) ); // perform transmit ret =pkt.transmit();if (ret) { Serial <<"..txreq("<<int(ret.get_value()) <<')'; } }return ret;}
voidsleepNow() { Serial << crlf <<"..sleeping now.."<< crlf;Serial.flush();step.on_sleep(false); // reset state machine.the_twelite.sleep(3000,false); // set longer sleep (PAL must wakeup less than 60sec.)}