case E_STATE::INIT:
brd.sns_MC3630.get_que().clear(); // clear queue in advance (just in case).
loop_more = true;
eState = E_STATE::START_CAPTURE;
break;
状態INITでは、初期化(結果格納用のキューのクリア)を行います。
case E_STATE::START_CAPTURE:
u32tick_capture = millis();
brd.sns_MC3630.begin(
// 400Hz, +/-4G range, get four samples (can be one sample)
SnsMC3630::Settings(
SnsMC3630::MODE_LP_400HZ, SnsMC3630::RANGE_PLUS_MINUS_4G, 4));
eState = E_STATE::WAIT_CAPTURE;
break;
int32_t x = 0, y = 0, z = 0;
for (auto&& v: brd.sns_MC3630.get_que()) {
x += v.x;
y += v.y;
z += v.z;
}
x /= brd.sns_MC3630.get_que().size();
y /= brd.sns_MC3630.get_que().size();
z /= brd.sns_MC3630.get_que().size();
C++ Standard Template Library のアルゴリズムを使用する例としてstd::mimmax_element紹介していますが、上述のforループ内で最大、最小を求めても構いません。
ここでキューをクリア.sns_MC3630.get_que().clear()しています。
// prepare tx packet
if (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(x)
, uint16_t(y)
, uint16_t(z)
, uint16_t(*x_minmax.first) // minimum of captured x
, uint16_t(*x_minmax.second) // maximum of captured x
);
// perform transmit
ret = pkt.transmit();
if (ret) {
Serial << "..txreq(" << int(ret.get_value()) << ')';
}
最期にパケットの生成と送信を要求を行います。パケットには X, Y, Z 軸の加速度、X軸の最小値,Y軸の最小値を含めています。
void loop() {
auto&& brd = the_twelite.board.use<PAL_MOT>();
if (!b_transmit) {
if (brd.sns_MC3630.available()) {
brd.sns_MC3630.end(); // stop now!
Serial << "..finish sensor capture." << mwx::crlf
<< " ct=" << int(brd.sns_MC3630.get_que().size());
// get all samples and average them.
int32_t x = 0, y = 0, z = 0;
for (auto&& v: brd.sns_MC3630.get_que()) {
x += v.x;
y += v.y;
z += v.z;
}
x /= brd.sns_MC3630.get_que().size();
y /= brd.sns_MC3630.get_que().size();
z /= brd.sns_MC3630.get_que().size();
Serial << format("/ave=%d,%d,%d", x, y, z) << mwx::crlf;
// just see X axis, min and max
//auto&& x_axis = get_axis_x(brd.sns_MC3630.get_que());
//auto&& x_minmax = std::minmax_element(x_axis.begin(), x_axis.end());
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()));
brd.sns_MC3630.get_que().clear(); // clean up the queue
// prepare tx packet
if (auto&& pkt = nwk.the_twelite.network.use<NWK_SIMPLE>()) {
auto&& pkt = nwk.prepare_tx_packet(); // get new packet instance.
// 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(x)
, uint16_t(y)
, uint16_t(z)
, uint16_t(*x_minmax.first) // minimum of captured x
, uint16_t(*x_minmax.second) // maximum of captured x
);
// perform transmit
MWX_APIRET ret = pkt.transmit();
if (ret) {
Serial << "..txreq(" << int(ret.get_value()) << ')';
txid = ret.get_value() & 0xFF;
} else {
sleepNow();
}
// finished tx request
b_transmit = true;
}
}
} else {
// wait until transmit completion.
if(the_twelite.tx_status.is_complete(txid)) {
sleepNow();
}
}
}
このアクトでは、サンプル取得後、すぐに加速度センサーの動作を停止します。
if (brd.sns_MC3630.available()) {
brd.sns_MC3630.end(); // stop now!
取得サンプルの平均値を計算します。
int32_t x = 0, y = 0, z = 0;
for (auto&& v: brd.sns_MC3630.get_que()) {
x += v.x;
y += v.y;
z += v.z;
}
x /= brd.sns_MC3630.get_que().size();
y /= brd.sns_MC3630.get_que().size();
z /= brd.sns_MC3630.get_que().size();
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()));
brd.sns_MC3630.get_que().clear(); // clean up the queue