Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
BusSerial.cpp
- Committer:
- ttrist
- Date:
- 2020-11-11
- Revision:
- 4:3b347fa779b7
- Parent:
- 2:6895c7ec9db1
- Child:
- 6:496eaf58c584
File content as of revision 4:3b347fa779b7:
#include "BusSerial.h"
BusSerial::BusSerial(PinName tx, PinName rx,Timer *timer):BufferedSerial(tx,rx)
{
_timer = timer;
_timer -> start();
}
// ヘッダー照合のみの超単純な受信関数.
// 引数は(格納先配列アドレス, ヘッダー番号, データ数)
// データ数はヘッダーの後ろに続く使用するデータの個数.
// ex)255 1 0 20 72 と送信されるなら 4(個)である.
// この表現 vs 格納先配列の要素数 どちらが使いやすくなるのか?それによって今後変えるかも
// 戻り値として,通信が正常にできたらtrueを返す.
bool BusSerial::getBusSerial(uint8_t* container, uint8_t head_num, uint8_t data_quantity)
{
//格納先配列の初期化
for (uint8_t i = 0; i < data_quantity + 1; i++) container[i] = 0;
// データ格納.ヘッダーがくるまで受信し続ける
while (container[0] != head_num)
if (readable() > 0) container[0] = getc();
// 通信の中身を受信
for (uint8_t i = 1; i < data_quantity + 1; i++) {
if (readable() > 0) container[i] = getc();
else i--; // 受信できない状態なら次も同じiの値で処理
}
// 受信バッファに溜まったデータをクリア.いらないかも.
deleteBufferData();
// 受信データを正常に取得できたか?
if(container[0] == head_num) return true;
else return false;
}
// ヘッダー照合とタイムアウト処理できる受信関数.
// 引数は(格納先配列アドレス, ヘッダー番号, データ数, タイムアウト時間ms)
// タイムアウトはこの関数が呼ばれてから~ms後にfalseを返す
bool BusSerial::getTimedBusSerial(uint8_t* container, uint8_t head_num, uint8_t data_quantity, int timeout)
{
// 受信開始時間記録
int time_start = _timer->read_ms();
for (uint8_t i = 0; i < data_quantity + 1; i++) container[i] = 0;
while (container[0] != head_num) {
if (readable() > 0) container[0] = getc();
if (_timer->read_ms() - time_start > timeout) return false;
}
for (uint8_t i = 1; i < data_quantity + 1; i++) {
if (readable() > 0) container[i] = getc();
else {
i--;
if (_timer->read_ms() - time_start > timeout) return false;
}
}
deleteBufferData();
if(container[0] == head_num) return true;
else return false;
}
// ヘッダーとフッター照合の受信関数.
// 引数は(格納先配列アドレス, ヘッダー番号, データ数, フッター番号)
bool BusSerial::getBusSerial(uint8_t* container, uint8_t head_num, uint8_t data_quantity, uint8_t footer_num)
{
// フッター分が追加されるため +2 となる.
for (uint8_t i = 0; i < data_quantity + 2; i++) container[i] = 0;
while (container[0] != head_num)
if (readable() > 0) container[0] = getc();
for (uint8_t i = 1; i < data_quantity + 2; i++) {
if (readable() > 0) container[i] = getc();
else i--;
}
if(container[0] == head_num && container[data_quantity + 1] == footer_num) return true;
else return false;
}
// ヘッダーとフッター照合とタイムアウト処理できる受信関数.
// 引数は(格納先配列アドレス, ヘッダー番号, データ数, フッター番号, タイムアウト時間ms)
// タイムアウトはこの関数が呼ばれてから~ms後にfalseを返す
bool BusSerial::getTimedBusSerial
(uint8_t* container, uint8_t head_num, uint8_t data_quantity, uint8_t footer_num, int timeout)
{
int time_start = _timer->read_ms();
for (uint8_t i = 0; i < data_quantity + 2; i++) container[i] = 0;
while (container[0] != head_num) {
if (readable() > 0) container[0] = getc();
if (_timer->read_ms() - time_start > timeout) return false;
}
for (uint8_t i = 1; i < data_quantity + 2; i++) {
if (readable() > 0) container[i] = getc();
else {
i--;
if (_timer->read_ms() - time_start > timeout) return false;
}
}
deleteBufferData();
if(container[0] == head_num && container[data_quantity + 1] == footer_num) return true;
else return false;
}
// 配列のデータ送信.
// 正直中身をそのまま書いた方が楽.
void BusSerial::sendBusSerial(uint8_t *send_array, uint8_t size)
{
for(uint8_t i = 0; i<size; i++) putc(send_array[i]);
}
// バッファ中身を全部読んで消去する.
void BusSerial::deleteBufferData()
{
while (readable() > 0) getc();
}
// 旧式の通信関数.古いプロジェクト用に残す.
void BusSerial::GetBusSerial(uint8_t *Argument_Array, int myHead_ID, int RecieveData_sizeof, int BusSerialTimeout)
{
long BusSerialTimeout_start_t = _timer->read_ms(); //タイマーセット
for (int i = 0; i < RecieveData_sizeof; i++) *(Argument_Array + i) = 0; //データ初期化
//*** データ受信 ちゃんとなるまでループ(timeoutあり)***
while (*Argument_Array != myHead_ID) {
//*** 1byte読み込み ***
if (readable() > 0) *Argument_Array = getc();
if (*Argument_Array == myHead_ID ) {
int old_i = 0;
//*** データ格納エリア ***
for (int i = 1; i < RecieveData_sizeof; i++) {
//格納中のtimeout処理用時間設定
if (old_i != i) {
old_i = i;
BusSerialTimeout_start_t = _timer->read_ms(); //データ格納timeout用
}
//***データ格納部***
if (readable() > 0) {
*(Argument_Array + i) = getc();
} else {
if (_timer->read_ms() - BusSerialTimeout_start_t > BusSerialTimeout) break;
i--;
}
}
}
if (_timer->read_ms() - BusSerialTimeout_start_t > BusSerialTimeout) break;//timeout
}
}