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.
Revision 0:a33375289d79, committed 2021-12-22
- Comitter:
- kikuchi8810
- Date:
- Wed Dec 22 11:15:12 2021 +0000
- Child:
- 1:6633661058ec
- Commit message:
- CommunicationMonitoring Class
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Wed Dec 22 11:15:12 2021 +0000 @@ -0,0 +1,4 @@ +.build +.mbed +projectfiles +*.py*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CONTRIBUTING.md Wed Dec 22 11:15:12 2021 +0000 @@ -0,0 +1,5 @@ +# Contributing to Mbed OS + +Mbed OS is an open-source, device software platform for the Internet of Things. Contributions are an important part of the platform, and our goal is to make it as simple as possible to become a contributor. + +To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/mbed-os/latest/contributing/index.html).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CommunicationMonitoring.cpp Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,35 @@
+#include "CommunicationMonitoring.h"
+
+CommunicationMonitoring::CommunicationMonitoring()
+{
+ device_num = 0;
+}
+
+int CommunicationMonitoring::init(int _time_out_ms, int _int_time_ms)
+{
+ comminfo[device_num].time_out_ms = _time_out_ms;
+ comminfo[device_num].int_time_ms = _int_time_ms;
+ comminfo[device_num].Available = false;
+ comminfo[device_num].count_ms = _time_out_ms;
+ comminfo[device_num].pre_count_ms = 0;
+
+ return device_num;
+
+ if(device_num < 9) device_num++;
+}
+
+void CommunicationMonitoring::Monitoring(bool commCheck, int _device_num)
+{
+ comminfo[_device_num].count_ms += comminfo[_device_num].int_time_ms;
+
+ if(commCheck) comminfo[_device_num].pre_count_ms = comminfo[_device_num].count_ms - comminfo[_device_num].int_time_ms;
+
+ comminfo[_device_num].Available = comminfo[_device_num].time_out_ms > (comminfo[_device_num].count_ms - comminfo[_device_num].pre_count_ms);
+
+ if(comminfo[_device_num].count_ms > comminfo[_device_num].time_out_ms * 1000) comminfo[_device_num].count_ms = comminfo[_device_num].time_out_ms; //オーバーフロー対策
+}
+
+bool CommunicationMonitoring::getAvailable(int _device_num)
+{
+ return comminfo[_device_num].Available;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CommunicationMonitoring.h Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,33 @@
+#ifndef COMMUNICATIONMONITORING_H
+#define COMMUNICATIONMONITORING_H
+
+#include "mbed.h"
+
+struct Comminfo
+{
+ int time_out_ms;
+ int int_time_ms;
+ bool Available;
+ int count_ms;
+ int pre_count_ms;
+};
+
+
+class CommunicationMonitoring
+{
+ public:
+ CommunicationMonitoring();
+
+ int init(int _time_out_ms, int _int_time_ms);
+ void Monitoring(bool commCheck, int _device_num);
+ bool getAvailable(int _device_num);
+
+ private:
+
+ Comminfo comminfo[10];
+ int device_num;
+
+};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Controller.cpp Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,332 @@
+// DS4のみ通信が確認できているバージョンで,プロジェクトに公開しているクラス
+#include "Controller.h"
+
+Controller::Controller(PinName tx, PinName rx, int baudrate) : serial(tx, rx, baudrate)
+{
+ conData.ButtonState = 0;
+ conData.RJoyX = 127, conData.RJoyY = 127, conData.LJoyX = 127, conData.LJoyY = 127;
+
+ lastButtonState = 0;
+
+ comCheck = false;
+ conAvailable = false;
+ time_out_ms = -1;
+}
+
+void Controller::init(int _time_out_ms, int _int_time_ms)
+{
+ time_out_ms = _time_out_ms;
+ int_time_ms = _int_time_ms;
+ //serial.attach(this, &Controller::update, Serial::RxIrq);
+ //timer.start();
+}
+
+bool Controller::update()
+{
+ //receptionTime = timer.read();
+ static int count_ms = time_out_ms, pre_count_ms = 0; //受信時刻と前回の受信時刻
+ count_ms += int_time_ms;
+
+ char receive_data[10];
+ unsigned int loop_count = 0, checksum = 0x00;
+ comCheck = false;
+
+#if CON_TYPE == CON_ADACHI // 安達君開発のコントローラを使う場合の処理(どのコントローラを使うかはdefine.hで設定)
+ while (loop_count < 10 && serial.readable())
+ {
+ if (serial_recieve() == '\n')
+ {
+ for (int i = 0; i < 8; i++)
+ receive_data[i] = serial_recieve();
+ for (int i = 0; i < 8; i++)
+ receive_data[i] -= 0x20;
+ for (int i = 0; i < 7; i++)
+ checksum ^= receive_data[i];
+
+ if (receive_data[7] == checksum & 0xFF)
+ {
+ comCheck = true;
+
+ //pre_conData.ButtonState = conData.ButtonState;
+ lastButtonState = ((receive_data[0] & 0x3F) << 2) | ((receive_data[1] & 0x30) >> 4);
+ conData.ButtonState |= lastButtonState;
+
+ conData.RJoyX = ((receive_data[1] & 0x0F) << 4) | ((receive_data[2] & 0x3C) >> 2);
+ conData.RJoyY = ((receive_data[2] & 0x03) << 6) | (receive_data[3] & 0x3F);
+ conData.LJoyX = ((receive_data[4] & 0x3F) << 2) | ((receive_data[5] & 0x30) >> 4);
+ conData.LJoyY = ((receive_data[5] & 0x0F) << 4) | (receive_data[6] & 0x0F);
+
+ break;
+ }
+
+ pre_count_ms = count_ms; //受信時間の更新
+ }
+ loop_count++;
+ }
+#elif CON_TYPE == CON_ELECOM // ELECOMのコントローラを使う場合の処理(どのコントローラを使うかはdefine.hで設定)
+ // コントローラデータを取得する部分
+ static int recv_num = 0;
+ char c;
+ while (serial.readable())
+ {
+ c = serial.getc();
+ if (c == '\n')
+ {
+ if (recv_num == 10)
+ { // チェックサムは無く,9個受信したら値を格納
+ for (int i = 0; i < 9; i++)
+ checksum += (unsigned int)(receive_data[i] - 0x20); // チェックサムの計算
+ if ((checksum & 0x3F) == (receive_data[9] - 0x20))
+ { // チェックサムの計算が合っていた場合のみ値を格納
+ comCheck = true;
+
+ //conData.ButtonState = 0;
+ conData.LJoyX = 0, conData.LJoyY = 0, conData.RJoyX = 0, conData.RJoyY = 0;
+ lastButtonState = (unsigned int)(receive_data[0] - 0x20);
+ lastButtonState |= (unsigned int)(receive_data[1] - 0x20) << 6;
+ lastButtonState |= (unsigned int)(receive_data[2] - 0x20) << 12;
+
+ conData.LJoyX |= (unsigned int)(receive_data[3] - 0x20);
+ conData.LJoyX |= (unsigned int)((receive_data[4] - 0x20) & 0x03) << 6;
+ conData.LJoyX = abs(conData.LJoyX - 0xFF);
+
+ conData.LJoyY |= (unsigned int)((receive_data[4] - 0x20) & 0x3C) >> 2;
+ conData.LJoyY |= (unsigned int)((receive_data[5] - 0x20) & 0x0F) << 4;
+ conData.LJoyY = abs(conData.LJoyY - 0xFF);
+
+ conData.RJoyX |= (unsigned int)((receive_data[5] - 0x20) & 0x30) >> 4;
+ conData.RJoyX |= (unsigned int)((receive_data[6] - 0x20) & 0x3F) << 2;
+ conData.RJoyX = abs(conData.RJoyX - 0xFF);
+
+ conData.RJoyY |= (unsigned int)(receive_data[7] - 0x20);
+ conData.RJoyY |= (unsigned int)((receive_data[8] - 0x20) & 0x03) << 6;
+ conData.RJoyY = abs(conData.RJoyY - 0xFF);
+
+ int buttonPushNum = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ buttonPushNum += (conData.ButtonState >> i) & 0x0001;
+ }
+ if (buttonPushNum > 5)
+ {
+ //conData.ButtonState = pre_conData.ButtonState;
+ comCheck = false;
+ }
+ else
+ {
+ conData.ButtonState |= lastButtonState;
+ }
+
+ pre_count_ms = count_ms; //受信時間の更新
+ }
+ }
+ recv_num = 0;
+ }
+ else
+ {
+ receive_data[recv_num] = c;
+ recv_num++;
+ }
+ }
+#elif CON_TYPE == CON_DS4 // DualShock4を使う場合の処理(どのコントローラを使うかはdefine.hで設定)
+ // コントローラデータを取得する部分
+ static int recv_num = 0;
+ char c;
+ while (serial.readable())
+ {
+ c = serial.getc();
+ //Serial.print(c);
+ if (c == '\n')
+ {
+ if (recv_num == 10)
+ { // データ数はチェックサム含めて10個(0~9)
+ checksum = 0;
+ for (int i = 0; i < 9; i++)
+ checksum ^= (unsigned int)(receive_data[i] - 0x20); // チェックサムの計算
+ if ((checksum & 0x3F) == (receive_data[9] - 0x20))
+ { // チェックサムの計算が合っていた場合のみ値を格納
+ comCheck = true;
+
+ //conData.ButtonState = 0;
+ conData.LJoyX = 0, conData.LJoyY = 0, conData.RJoyX = 0, conData.RJoyY = 0;
+ lastButtonState = (unsigned int)(receive_data[0] - 0x20) & 0x3F;
+ lastButtonState |= (unsigned int)((receive_data[1] - 0x20) & 0x3F) << 6;
+ lastButtonState |= (unsigned int)((receive_data[2] - 0x20) & 0x0F) << 12;
+
+ conData.LJoyX |= (unsigned int)(receive_data[3] - 0x20);
+ conData.LJoyX |= (unsigned int)((receive_data[4] - 0x20) & 0x03) << 6;
+ conData.LJoyX = abs(conData.LJoyX - 0xFF);
+
+ conData.LJoyY |= (unsigned int)((receive_data[4] - 0x20) & 0x3C) >> 2;
+ conData.LJoyY |= (unsigned int)((receive_data[5] - 0x20) & 0x0F) << 4;
+ conData.LJoyY = abs(conData.LJoyY - 0xFF);
+
+ conData.RJoyX |= (unsigned int)((receive_data[5] - 0x20) & 0x30) >> 4;
+ conData.RJoyX |= (unsigned int)((receive_data[6] - 0x20) & 0x3F) << 2;
+ conData.RJoyX = abs(conData.RJoyX - 0xFF);
+
+ conData.RJoyY |= (unsigned int)(receive_data[7] - 0x20);
+ conData.RJoyY |= (unsigned int)((receive_data[8] - 0x20) & 0x03) << 6;
+ conData.RJoyY = abs(conData.RJoyY - 0xFF);
+
+ // 通信ミスであり得ない数のボタン数押されていた場合に無視する処理
+ int buttonPushNum = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ buttonPushNum += (lastButtonState >> i) & 0x0001;
+ }
+ if (buttonPushNum > 5)
+ {
+ //conData.ButtonState = pre_conData.ButtonState;
+ comCheck = false;
+ }
+ else
+ {
+ conData.ButtonState = lastButtonState & 0xFFFF;
+ }
+
+ pre_count_ms = count_ms - int_time_ms; //受信時間の更新
+ }
+ }
+ recv_num = 0;
+ }
+ else
+ {
+ receive_data[recv_num] = c;
+ recv_num++;
+ }
+ }
+
+#endif
+
+ if(!(time_out_ms == -1)) conAvailable = (time_out_ms > (count_ms - pre_count_ms)); //タイムアウトとインターバルの比較
+ else conAvailable = true;
+ if(count_ms > time_out_ms * 1000) count_ms = time_out_ms; //オーバーフロー対策
+
+ return comCheck;
+}
+
+bool Controller::getComCheck(void)
+{
+ return comCheck;
+}
+
+bool Controller::available(void)
+{
+ return conAvailable;
+}
+
+bool Controller::readButton_bin(unsigned int ButtonNum)
+{ //放しているときは0,押しているときは1
+ return ((conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1))) ? true : false;
+}
+
+int Controller::readButton(unsigned int ButtonNum)
+{ //放しているときは0,押しているときは1,押した瞬間は2,放した瞬間は-1
+ int result = 0;
+ if ((conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1)))
+ result += 2;
+ if ((pre_conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1)))
+ result -= 1;
+ return result;
+}
+
+unsigned int Controller::getButtonState()
+{
+ return conData.ButtonState;
+}
+
+void Controller::clearButtonState()
+{
+ pre_conData.ButtonState = conData.ButtonState;
+}
+
+ControllerData Controller::getConData()
+{
+ return conData;
+}
+
+double Controller::readJoyRX()
+{
+ if (conData.RJoyX == 127)
+ return 0;
+ return ((double)conData.RJoyX - 127.5) / 127.5;
+}
+
+double Controller::readJoyRY()
+{
+ if (conData.RJoyY == 127)
+ return 0;
+ return ((double)conData.RJoyY - 127.5) / 127.5;
+}
+
+double Controller::readJoyLX()
+{
+ if (conData.LJoyX == 127)
+ return 0;
+ return ((double)conData.LJoyX - 127.5) / 127.5;
+}
+
+double Controller::readJoyLY()
+{
+ if (conData.LJoyY == 127)
+ return 0;
+ return ((double)conData.LJoyY - 127.5) / 127.5;
+}
+
+uint8_t Controller::readJoyRXbyte()
+{
+ return conData.RJoyX;
+}
+
+uint8_t Controller::readJoyRYbyte()
+{
+ return conData.RJoyY;
+}
+
+uint8_t Controller::readJoyLXbyte()
+{
+ return conData.LJoyX;
+}
+
+uint8_t Controller::readJoyLYbyte()
+{
+ return conData.LJoyY;
+}
+
+unsigned int Controller::getButtonFlagRise()
+{
+ // 立ち上がり,立下りのフラッギング処理 (フラグクリアは別関数で)
+ unsigned int buttonFlagRise = 0;
+ if (pre_conData.ButtonState != conData.ButtonState)
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ int mask = 0x01 << i;
+ if ((conData.ButtonState & mask) != (pre_conData.ButtonState & mask))
+ {
+ if ((conData.ButtonState & mask) == mask)
+ buttonFlagRise |= (conData.ButtonState & mask);
+ }
+ }
+ }
+ return buttonFlagRise;
+}
+
+unsigned int Controller::getButtonFlagFall()
+{
+ unsigned int buttonFlagFall = 0;
+ if (pre_conData.ButtonState != conData.ButtonState)
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ int mask = 0x01 << i;
+ if ((conData.ButtonState & mask) != (pre_conData.ButtonState & mask))
+ {
+ if ((pre_conData.ButtonState & mask) == mask)
+ buttonFlagFall |= (pre_conData.ButtonState & mask);
+ }
+ }
+ }
+ return buttonFlagFall;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Controller.h Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,74 @@
+// DS4のみ通信が確認できているバージョンで,プロジェクトに公開しているクラス
+#ifndef CONTROLLER_H
+#define CONTROLLER_H
+
+#include "mbed.h"
+#include "RawSerial.h"
+#include "define.h"
+/*
+struct ControllerData{
+ unsigned int ButtonState;
+ uint8_t RJoyX, RJoyY, LJoyX, LJoyY;
+};
+*/
+class Controller{
+ public:
+ Controller(PinName tx, PinName rx, int baudrate);
+ int count_ms, pre_count_ms; //受信時刻と前回の受信時刻
+
+ bool readButton_bin(unsigned int ButtonNum); //押していない時はfalse(0),押してるときはtrue(1)を返す. ButtonNumはデータの欲しいボタンの名前を
+ int readButton(unsigned int ButtonNum); //上にプラスして 押した瞬間は2,放した瞬間は-1を返す. define.hを参考に数字を入力しても良い
+ bool getComCheck(void); //値が更新されたときにtrueを返す.
+ bool update(); //受信の処理+ボタンの情報の更新.受信割込みで処理
+
+ void init(int _time_out_ms, int _int_time_ms); //コントローラの通信速度と通信のタイムアウト時間を設定
+ bool available(void);
+
+ unsigned int getButtonState(); //分解する前のButtonStateの情報をprint 0~255の値をとる
+ void clearButtonState();
+ ControllerData getConData();
+ unsigned int getButtonFlagRise();
+ unsigned int getButtonFlagFall();
+
+ // X
+ double readJoyRX(); // ^
+ double readJoyRY(); // |
+ double readJoyLX(); // Y<---+----
+ double readJoyLY(); // |
+ // |
+ // 1.0 ~ -1.0
+
+ // X
+ uint8_t readJoyRXbyte(); // ^
+ uint8_t readJoyRYbyte(); // |
+ uint8_t readJoyLXbyte(); // Y<---+----
+ uint8_t readJoyLYbyte(); // |
+ // |
+ // 255 ~ 0
+
+ private:
+
+ RawSerial serial;
+ //Timer timer;
+
+ bool comCheck;
+ ControllerData conData;
+ ControllerData pre_conData;
+ unsigned int lastButtonState;
+
+ int time_out_ms;
+ double int_time_ms;
+ bool conAvailable;
+
+ uint8_t serial_recieve(){
+ char temp;
+ do{
+ temp = serial.getc();
+ }
+ while(temp==-1);
+ //CONTROL.write(temp); //受け取ったデータをTXピンからそのまま送っている.他のマイコンにも流したいとき用.
+ return temp;
+ }
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ControllerForMbed.cpp Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,348 @@
+//宇井コンとの通信をmbedで行えるように変更を加えたクラスでプロジェクトに公開していない.
+#include "ControllerForMbed.h"
+
+ControllerForMbed::ControllerForMbed(PinName tx, PinName rx, int baudrate) : serial(tx, rx, baudrate)
+{
+ conData.ButtonState = 0;
+ conData.RJoyX = 127, conData.RJoyY = 127, conData.LJoyX = 127, conData.LJoyY = 127;
+
+ lastButtonState = 0;
+
+ comCheck = false;
+ conAvailable = false;
+ time_out_ms = -1;
+}
+
+void ControllerForMbed::init(int _time_out_ms, int _int_time_ms)
+{
+ time_out_ms = _time_out_ms;
+ int_time_ms = _int_time_ms;
+ //serial.attach(this, &Controller::update, Serial::RxIrq);
+ //timer.start();
+}
+
+bool ControllerForMbed::update()
+{
+ //receptionTime = timer.read();
+ static int count_ms = time_out_ms, pre_count_ms = 0; //受信時刻と前回の受信時刻
+
+ char receive_data[10];
+ unsigned int checksum = 0x00;
+ comCheck = false;
+
+#if CON_TYPE == CON_ADACHI // 安達君開発のコントローラを使う場合の処理(どのコントローラを使うかはdefine.hで設定)
+
+ //while (loop_count < 10 && serial.readable())
+ while (serial.readable())
+ {
+ static int recv_num = 0;
+ char c = serial.getc();
+
+ //if (serial_recieve() == '\n')
+ if (c == '\n')
+ {
+ if(recv_num == 8)
+ {
+ //for (int i = 0; i < 8; i++)
+ // receive_data[i] = serial_recieve();
+ for (int i = 0; i < 8; i++)
+ receive_data[i] -= 0x20;
+ for (int i = 0; i < 7; i++)
+ checksum ^= receive_data[i];
+
+ if (receive_data[7] == checksum & 0xFF)
+ {
+ comCheck = true;
+
+ //pre_conData.ButtonState = conData.ButtonState;
+ lastButtonState = ((receive_data[0] & 0x3F) << 2) | ((receive_data[1] & 0x30) >> 4);
+ conData.ButtonState |= lastButtonState;
+
+ conData.RJoyX = ((receive_data[1] & 0x0F) << 4) | ((receive_data[2] & 0x3C) >> 2);
+ conData.RJoyY = ((receive_data[2] & 0x03) << 6) | (receive_data[3] & 0x3F);
+ conData.LJoyX = ((receive_data[4] & 0x3F) << 2) | ((receive_data[5] & 0x30) >> 4);
+ conData.LJoyY = ((receive_data[5] & 0x0F) << 4) | (receive_data[6] & 0x0F);
+
+ pre_count_ms = count_ms; //受信時間の更新
+ if(pre_count_ms > int_time_ms * 1000) pre_count_ms = count_ms = 0; //オーバーフロー対策
+ }
+ }
+ recv_num = 0;
+ }
+ else
+ {
+ receive_data[recv_num] = c;
+ recv_num++;
+ }
+
+ }
+
+#elif CON_TYPE == CON_ELECOM // ELECOMのコントローラを使う場合の処理(どのコントローラを使うかはdefine.hで設定)
+ // コントローラデータを取得する部分
+ static int recv_num = 0;
+ char c;
+ while (serial.readable())
+ {
+ c = serial.getc();
+ if (c == '\n')
+ {
+ if (recv_num == 10)
+ { // チェックサムは無く,9個受信したら値を格納
+ for (int i = 0; i < 9; i++)
+ checksum += (unsigned int)(receive_data[i] - 0x20); // チェックサムの計算
+ if ((checksum & 0x3F) == (receive_data[9] - 0x20))
+ { // チェックサムの計算が合っていた場合のみ値を格納
+ comCheck = true;
+
+ //conData.ButtonState = 0;
+ conData.LJoyX = 0, conData.LJoyY = 0, conData.RJoyX = 0, conData.RJoyY = 0;
+ lastButtonState = (unsigned int)(receive_data[0] - 0x20);
+ lastButtonState |= (unsigned int)(receive_data[1] - 0x20) << 6;
+ lastButtonState |= (unsigned int)(receive_data[2] - 0x20) << 12;
+
+ conData.LJoyX |= (unsigned int)(receive_data[3] - 0x20);
+ conData.LJoyX |= (unsigned int)((receive_data[4] - 0x20) & 0x03) << 6;
+ conData.LJoyX = abs(conData.LJoyX - 0xFF);
+
+ conData.LJoyY |= (unsigned int)((receive_data[4] - 0x20) & 0x3C) >> 2;
+ conData.LJoyY |= (unsigned int)((receive_data[5] - 0x20) & 0x0F) << 4;
+ conData.LJoyY = abs(conData.LJoyY - 0xFF);
+
+ conData.RJoyX |= (unsigned int)((receive_data[5] - 0x20) & 0x30) >> 4;
+ conData.RJoyX |= (unsigned int)((receive_data[6] - 0x20) & 0x3F) << 2;
+ conData.RJoyX = abs(conData.RJoyX - 0xFF);
+
+ conData.RJoyY |= (unsigned int)(receive_data[7] - 0x20);
+ conData.RJoyY |= (unsigned int)((receive_data[8] - 0x20) & 0x03) << 6;
+ conData.RJoyY = abs(conData.RJoyY - 0xFF);
+
+ int buttonPushNum = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ buttonPushNum += (conData.ButtonState >> i) & 0x0001;
+ }
+ if (buttonPushNum > 5)
+ {
+ //conData.ButtonState = pre_conData.ButtonState;
+ comCheck = false;
+ }
+ else
+ {
+ conData.ButtonState |= lastButtonState;
+ }
+
+ pre_count_ms = count_ms; //受信時間の更新
+ if(pre_count_ms > int_time_ms * 1000) pre_count_ms = count_ms = 0; //オーバーフロー対策
+ }
+ }
+ recv_num = 0;
+ }
+ else
+ {
+ receive_data[recv_num] = c;
+ recv_num++;
+ }
+ }
+#elif CON_TYPE == CON_DS4 // DualShock4を使う場合の処理(どのコントローラを使うかはdefine.hで設定)
+ // コントローラデータを取得する部分
+ static int recv_num = 0;
+ char c;
+ while (serial.readable())
+ {
+ c = serial.getc();
+ //Serial.print(c);
+ if (c == '\n')
+ {
+ if (recv_num == 10)
+ { // データ数はチェックサム含めて10個(0~9)
+ checksum = 0;
+ for (int i = 0; i < 9; i++)
+ checksum ^= (unsigned int)(receive_data[i] - 0x20); // チェックサムの計算
+ if ((checksum & 0x3F) == (receive_data[9] - 0x20))
+ { // チェックサムの計算が合っていた場合のみ値を格納
+ comCheck = true;
+
+ //conData.ButtonState = 0;
+ conData.LJoyX = 0, conData.LJoyY = 0, conData.RJoyX = 0, conData.RJoyY = 0;
+ lastButtonState = (unsigned int)(receive_data[0] - 0x20) & 0x3F;
+ lastButtonState |= (unsigned int)((receive_data[1] - 0x20) & 0x3F) << 6;
+ lastButtonState |= (unsigned int)((receive_data[2] - 0x20) & 0x0F) << 12;
+
+ conData.LJoyX |= (unsigned int)(receive_data[3] - 0x20);
+ conData.LJoyX |= (unsigned int)((receive_data[4] - 0x20) & 0x03) << 6;
+ conData.LJoyX = abs(conData.LJoyX - 0xFF);
+
+ conData.LJoyY |= (unsigned int)((receive_data[4] - 0x20) & 0x3C) >> 2;
+ conData.LJoyY |= (unsigned int)((receive_data[5] - 0x20) & 0x0F) << 4;
+ conData.LJoyY = abs(conData.LJoyY - 0xFF);
+
+ conData.RJoyX |= (unsigned int)((receive_data[5] - 0x20) & 0x30) >> 4;
+ conData.RJoyX |= (unsigned int)((receive_data[6] - 0x20) & 0x3F) << 2;
+ conData.RJoyX = abs(conData.RJoyX - 0xFF);
+
+ conData.RJoyY |= (unsigned int)(receive_data[7] - 0x20);
+ conData.RJoyY |= (unsigned int)((receive_data[8] - 0x20) & 0x03) << 6;
+ conData.RJoyY = abs(conData.RJoyY - 0xFF);
+
+ // 通信ミスであり得ない数のボタン数押されていた場合に無視する処理
+ int buttonPushNum = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ buttonPushNum += (lastButtonState >> i) & 0x0001;
+ }
+ if (buttonPushNum > 5)
+ {
+ //conData.ButtonState = pre_conData.ButtonState;
+ comCheck = false;
+ }
+ else
+ {
+ conData.ButtonState = lastButtonState & 0xFFFF;
+ }
+
+ pre_count_ms = count_ms; //受信時間の更新
+ if(pre_count_ms > int_time_ms * 1000) pre_count_ms = count_ms = 0; //オーバーフロー対策
+ }
+ }
+ recv_num = 0;
+ }
+ else
+ {
+ receive_data[recv_num] = c;
+ recv_num++;
+ }
+ }
+
+#endif
+ if(!(time_out_ms == -1)) conAvailable = (time_out_ms > (count_ms - pre_count_ms)); //タイムアウトとインターバルの比較
+ else conAvailable = true;
+ count_ms += int_time_ms; //経過時間の更新
+
+ return comCheck;
+}
+
+bool ControllerForMbed::getComCheck(void)
+{
+ return comCheck;
+}
+
+bool ControllerForMbed::available(void)
+{
+ return conAvailable;
+}
+
+bool ControllerForMbed::readButton_bin(unsigned int ButtonNum)
+{ //放しているときは0,押しているときは1
+ return ((conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1))) ? true : false;
+}
+
+int ControllerForMbed::readButton(unsigned int ButtonNum)
+{ //放しているときは0,押しているときは1,押した瞬間は2,放した瞬間は-1
+ int result = 0;
+ if ((conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1)))
+ result += 2;
+ if ((pre_conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1)))
+ result -= 1;
+ return result;
+}
+
+unsigned int ControllerForMbed::getButtonState()
+{
+ return conData.ButtonState;
+}
+
+void ControllerForMbed::clearButtonState()
+{
+ pre_conData.ButtonState = conData.ButtonState;
+}
+
+ControllerData ControllerForMbed::getConData()
+{
+ return conData;
+}
+
+double ControllerForMbed::readJoyRX()
+{
+ if (conData.RJoyX == 127)
+ return 0;
+ return ((double)conData.RJoyX - 127.5) / 127.5;
+}
+
+double ControllerForMbed::readJoyRY()
+{
+ if (conData.RJoyY == 127)
+ return 0;
+ return ((double)conData.RJoyY - 127.5) / 127.5;
+}
+
+double ControllerForMbed::readJoyLX()
+{
+ if (conData.LJoyX == 127)
+ return 0;
+ return ((double)conData.LJoyX - 127.5) / 127.5;
+}
+
+double ControllerForMbed::readJoyLY()
+{
+ if (conData.LJoyY == 127)
+ return 0;
+ return ((double)conData.LJoyY - 127.5) / 127.5;
+}
+
+uint8_t ControllerForMbed::readJoyRXbyte()
+{
+ return conData.RJoyX;
+}
+
+uint8_t ControllerForMbed::readJoyRYbyte()
+{
+ return conData.RJoyY;
+}
+
+uint8_t ControllerForMbed::readJoyLXbyte()
+{
+ return conData.LJoyX;
+}
+
+uint8_t ControllerForMbed::readJoyLYbyte()
+{
+ return conData.LJoyY;
+}
+
+unsigned int ControllerForMbed::getButtonFlagRise()
+{
+ // 立ち上がり,立下りのフラッギング処理 (フラグクリアは別関数で)
+ unsigned int buttonFlagRise = 0;
+ if (pre_conData.ButtonState != conData.ButtonState)
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ int mask = 0x01 << i;
+ if ((conData.ButtonState & mask) != (pre_conData.ButtonState & mask))
+ {
+ if ((conData.ButtonState & mask) == mask)
+ buttonFlagRise |= (conData.ButtonState & mask);
+ }
+ }
+ }
+ return buttonFlagRise;
+}
+
+unsigned int ControllerForMbed::getButtonFlagFall()
+{
+ unsigned int buttonFlagFall = 0;
+ if (pre_conData.ButtonState != conData.ButtonState)
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ int mask = 0x01 << i;
+ if ((conData.ButtonState & mask) != (pre_conData.ButtonState & mask))
+ {
+ if ((pre_conData.ButtonState & mask) == mask)
+ buttonFlagFall |= (pre_conData.ButtonState & mask);
+ }
+ }
+ }
+ return buttonFlagFall;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ControllerForMbed.h Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,74 @@
+//宇井コンとの通信をmbedで行えるように変更を加えたクラスでプロジェクトに公開していない.
+#ifndef CONTROLLERFORMBED_H
+#define CONTROLLERFORMBED_H
+
+#include "mbed.h"
+#include "RawSerial.h"
+#include "define.h"
+/*
+struct ControllerData{
+ unsigned int ButtonState;
+ uint8_t RJoyX, RJoyY, LJoyX, LJoyY;
+};
+*/
+class ControllerForMbed{
+ public:
+ ControllerForMbed(PinName tx, PinName rx, int baudrate);
+
+ bool readButton_bin(unsigned int ButtonNum); //押していない時はfalse(0),押してるときはtrue(1)を返す. ButtonNumはデータの欲しいボタンの名前を
+ int readButton(unsigned int ButtonNum); //上にプラスして 押した瞬間は2,放した瞬間は-1を返す. define.hを参考に数字を入力しても良い
+ bool getComCheck(void); //値が更新されたときにtrueを返す.
+ bool update(); //受信の処理+ボタンの情報の更新.受信割込みで処理
+
+ void init(int _time_out_ms, int _int_time_ms); //コントローラの通信速度と通信のタイムアウト時間を設定
+ bool available(void); //コントローラーと通信できていたらtrueを返す.
+
+ unsigned int getButtonState(); //分解する前のButtonStateの情報をprint 0~255の値をとる
+ void clearButtonState();
+ ControllerData getConData();
+ unsigned int getButtonFlagRise();
+ unsigned int getButtonFlagFall();
+
+ // X
+ double readJoyRX(); // ^
+ double readJoyRY(); // |
+ double readJoyLX(); // Y<---+----
+ double readJoyLY(); // |
+ // |
+ // 1.0 ~ -1.0
+
+ // X
+ uint8_t readJoyRXbyte(); // ^
+ uint8_t readJoyRYbyte(); // |
+ uint8_t readJoyLXbyte(); // Y<---+----
+ uint8_t readJoyLYbyte(); // |
+ // |
+ // 255 ~ 0
+
+ private:
+
+ RawSerial serial;
+ //Timer timer;
+
+ bool comCheck;
+ ControllerData conData;
+ ControllerData pre_conData;
+ unsigned int lastButtonState;
+
+ int time_out_ms; //通信のタイムアウト[ms]
+ double int_time_ms; //update関数の呼び出し周期[ms]
+ bool conAvailable; //コントローラ接続確認
+
+ uint8_t serial_recieve(){
+ char temp;
+ do{
+ temp = serial.getc();
+ }
+ while(temp==-1);
+ //CONTROL.write(temp); //受け取ったデータをTXピンからそのまま送っている.他のマイコンにも流したいとき用.
+ return temp;
+ }
+};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Wed Dec 22 11:15:12 2021 +0000 @@ -0,0 +1,64 @@ + +# Blinky Mbed OS example + +The example project is part of the [Arm Mbed OS Official Examples](https://os.mbed.com/code/) and is the [getting started example for Mbed OS](https://os.mbed.com/docs/mbed-os/v5.14/quick-start/index.html). It contains an application that repeatedly blinks an LED on supported [Mbed boards](https://os.mbed.com/platforms/). + +You can build the project with all supported [Mbed OS build tools](https://os.mbed.com/docs/mbed-os/latest/tools/index.html). However, this example project specifically refers to the command-line interface tool [Arm Mbed CLI](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli). +(Note: To see a rendered example you can import into the Arm Online Compiler, please see our [import quick start](https://os.mbed.com/docs/mbed-os/latest/quick-start/online-with-the-online-compiler.html#importing-the-code).) + +1. [Install Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/quick-start/offline-with-mbed-cli.html). + +1. Clone this repository on your system, and change the current directory to where the project was cloned: + + ```bash + $ git clone git@github.com:armmbed/mbed-os-example-blinky && cd mbed-os-example-blinky + ``` + + Alternatively, you can download the example project with Arm Mbed CLI using the `import` subcommand: + + ```bash + $ mbed import mbed-os-example-blinky && cd mbed-os-example-blinky + ``` + + +## Application functionality + +The `main()` function is the single thread in the application. It toggles the state of a digital output connected to an LED on the board. + +## Building and running + +1. Connect a USB cable between the USB port on the board and the host computer. +2. <a name="build_cmd"></a> Run the following command to build the example project and program the microcontroller flash memory: + ```bash + $ mbed compile -m <TARGET> -t <TOOLCHAIN> --flash + ``` +The binary is located at `./BUILD/<TARGET>/<TOOLCHAIN>/mbed-os-example-blinky.bin`. + +Alternatively, you can manually copy the binary to the board, which you mount on the host computer over USB. + +Depending on the target, you can build the example project with the `GCC_ARM`, `ARM` or `IAR` toolchain. After installing Arm Mbed CLI, run the command below to determine which toolchain supports your target: + +```bash +$ mbed compile -S +``` + +## Expected output +The LED on your target turns on and off every 500 milliseconds. + + +## Troubleshooting +If you have problems, you can review the [documentation](https://os.mbed.com/docs/latest/tutorials/debugging.html) for suggestions on what could be wrong and how to fix it. + +## Related Links + +* [Mbed OS Stats API](https://os.mbed.com/docs/latest/apis/mbed-statistics.html). +* [Mbed OS Configuration](https://os.mbed.com/docs/latest/reference/configuration.html). +* [Mbed OS Serial Communication](https://os.mbed.com/docs/latest/tutorials/serial-communication.html). +* [Mbed OS bare metal](https://os.mbed.com/docs/mbed-os/latest/reference/mbed-os-bare-metal.html). +* [Mbed boards](https://os.mbed.com/platforms/). + +### License and contributions + +The software is provided under Apache-2.0 license. Contributions to this project are accepted under the same license. Please see contributing.md for more info. + +This project contains code from other projects. The original license text is included in those source files. They must comply with our license guide.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/define.h Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,77 @@
+#ifndef DEFINE_H
+#define DEFINE_H
+
+struct ControllerData{
+ unsigned int ButtonState;
+ uint8_t RJoyX, RJoyY, LJoyX, LJoyY;
+};
+
+// >>> Controllerまわりで使用>>>>>>>>>>>>>>>>>>>>>
+#define CON_ADACHI (0)
+#define CON_ELECOM (1)
+#define CON_DS4 (2)
+
+#define CON_TYPE (CON_DS4)
+
+#if CON_TYPE == CON_ADACHI
+#define MASK_BUTTON_UP 0x01
+#define MASK_BUTTON_RIGHT 0x02
+#define MASK_BUTTON_DOWN 0x04
+#define MASK_BUTTON_LEFT 0x08
+#define MASK_BUTTON_R1 0x10
+#define MASK_BUTTON_R2 0x20
+#define MASK_BUTTON_L1 0x40
+#define MASK_BUTTON_L2 0x80
+
+#define BUTTON_UP 1
+#define BUTTON_RIGHT 2
+#define BUTTON_DOWN 3
+#define BUTTON_LEFT 4
+#define BUTTON_R1 5
+#define BUTTON_R2 6
+#define BUTTON_L1 7
+#define BUTTON_L2 8
+
+#elif CON_TYPE == CON_ELECOM || CON_TYPE == CON_DS4
+#define MASK_BUTTON_X 0x0001
+#define MASK_BUTTON_Y 0x0002
+#define MASK_BUTTON_A 0x0004
+#define MASK_BUTTON_B 0x0008
+
+#define MASK_BUTTON_SHIKAKU 0x0001
+#define MASK_BUTTON_SANKAKU 0x0002
+#define MASK_BUTTON_BATU 0x0004
+#define MASK_BUTTON_MARU 0x0008
+
+#define MASK_BUTTON_L1 0x0010
+#define MASK_BUTTON_R1 0x0020
+#define MASK_BUTTON_L2 0x0040
+#define MASK_BUTTON_R2 0x0080
+
+#define MASK_BUTTON_PS 0x0200 // PS4のときはPSボタン
+#define MASK_BUTTON_PAD 0x0100 // PS4のときはパッド
+#define MASK_BUTTON_JOY_L 0x0100
+#define MASK_BUTTON_JOY_R 0x0200
+#define MASK_BUTTON_BACK 0x0400
+#define MASK_BUTTON_START 0x0800
+#define MASK_BUTTON_SHARE 0x0400
+#define MASK_BUTTON_OPTION 0x0800
+
+#define MASK_BUTTON_UP 0x1000
+#define MASK_BUTTON_RIGHT 0x2000
+#define MASK_BUTTON_DOWN 0x4000
+#define MASK_BUTTON_LEFT 0x8000
+
+#define BUTTON_UP 12
+#define BUTTON_RIGHT 13
+#define BUTTON_DOWN 14
+#define BUTTON_LEFT 15
+#define BUTTON_R1 5
+#define BUTTON_R2 7
+#define BUTTON_L1 4
+#define BUTTON_L2 6
+
+#endif
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Dec 22 11:15:12 2021 +0000
@@ -0,0 +1,149 @@
+//CommunicationMonitoringクラスの動作確認用プログラム
+//宇井コンのmbed環境での動作確認をするプログラム(ControllerForMbed内で実装し,controllerクラスと区別している)
+//contoller(conrollerForMbed)クラス内のタイムアウト機能を使わないようにしている
+
+#include "mbed.h"
+#include "platform/mbed_thread.h"
+#include "Controller.h"
+#include "ControllerForMbed.h"
+#include "CommunicationMonitoring.h"
+#include "define.h"
+
+#define INT_TIME 0.001
+#define INT_TIME_MS INT_TIME*1000
+
+Serial pc(USBTX, USBRX);
+
+#if CON_TYPE == CON_DS4
+ Controller con(P7_4,P7_5, 115200); //TXpin, RXpin, baudrateを設定
+#elif CON_TYPE == CON_ADACHI
+ ControllerForMbed conmbed(P7_4,P7_5, 115200);
+#endif
+
+CommunicationMonitoring commMonitor;
+int contoller_num;
+
+DigitalOut led_user(LED_USER);
+DigitalOut led_red(LED_RED);
+DigitalOut led_green(LED_GREEN);
+DigitalOut led_blue(LED_BLUE);
+DigitalOut pin_emergency(D0); //非常停止信号
+
+Ticker interrupt;
+bool flag_10ms = false;
+bool flag_1s = false;
+
+void interrupt_func()
+{
+ static int count_10ms = 0;
+ if(count_10ms++ > (INT_TIME_MS*10 - 1))
+ {
+ flag_10ms = true;
+ count_10ms = 0;
+
+ static int count_1s = 0;
+ if(count_1s++ > (INT_TIME_MS*100 -1))
+ {
+ flag_1s = true;
+ count_1s = 0;
+ }
+ }
+}
+
+int main()
+{
+ pc.baud(115200);
+
+ /* 第一引数はタイムアウト時間[ms],第二引数はupdate関数の呼び出し周期[ms] */
+ #if CON_TYPE == CON_DS4
+ con.init(1000, INT_TIME_MS*10); //init関数を呼び出さなければタイムアウトの処理は行われない(available関数は常にtrueを返す)
+ #elif CON_TYPE == CON_ADACHI
+ conmbed.inti(1000, INT_TIME_MS*10);
+ #endif
+ contoller_num = commMonitor.init(1000, INT_TIME_MS*10);
+
+ interrupt.attach(&interrupt_func, INT_TIME);
+
+ while(1)
+ {
+ if(flag_10ms)
+ {
+ #if CON_TYPE == CON_DS4
+ //con.update(); //main関数のflag内で呼び出す.
+ commMonitor.Monitoring(con.update(), contoller_num);
+ //if(con.available())
+ if(commMonitor.getAvailable(contoller_num))
+ {
+ int buttonState = con.getButtonState();
+ uint8_t joyRx = con.readJoyRXbyte();
+ uint8_t joyRy = con.readJoyRYbyte();
+ uint8_t joyLx = con.readJoyLXbyte();
+ uint8_t joyLy = con.readJoyLYbyte();
+
+ pc.printf("%d\t", buttonState);
+ pc.printf("%d\t", joyRx);
+ pc.printf("%d\t", joyRy);
+ pc.printf("%d\t", joyLx);
+ pc.printf("%d\r\n", joyLy);
+
+ led_user.write(0);
+ pin_emergency.write(1); //非常停止を解除する
+ }
+ else
+ {
+ pc.printf("disconnected\r\n");
+ led_user.write(1);
+ pin_emergency.write(0); //非常停止を作動させる
+ }
+
+ #elif CON_TYPE == CON_ADACHI
+ //conmbed.update(); //main関数のflag内で呼び出す.
+ commMonitor.Monitoring(conmbed.update(), contoller_num);
+ //if(conmbed.available())
+ if(commMonitor.getAvailable(contoller_num))
+ {
+ int buttonState = conmbed.getButtonState();
+ uint8_t joyRx = conmbed.readJoyRXbyte();
+ uint8_t joyRy = conmbed.readJoyRYbyte();
+ uint8_t joyLx = conmbed.readJoyLXbyte();
+ uint8_t joyLy = conmbed.readJoyLYbyte();
+
+ pc.printf("%d\t", buttonState);
+ pc.printf("%d\t", joyRx);
+ pc.printf("%d\t", joyRy);
+ pc.printf("%d\t", joyLx);
+ pc.printf("%d\r\n", joyLy);
+
+ led_user.write(0);
+ pin_emergency.write(1); //非常停止を解除する
+ }
+ else
+ {
+ pc.printf("disconnected\r\n");
+ led_user.write(1);
+ pin_emergency.write(0); //非常停止を作動させる
+ }
+
+
+ #endif
+
+ flag_10ms = false;
+ }
+
+ if(flag_1s)
+ {
+ static int led_count = 0;
+
+ led_red.write(led_count & 0x01);
+ led_green.write(led_count & 0x02);
+ led_blue.write(led_count & 0x04);
+
+ led_count++;
+ if(led_count == 0x05) led_count = 0;
+
+ flag_1s = false;
+ }
+
+ thread_sleep_for(1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Wed Dec 22 11:15:12 2021 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#cf4f12a123c05fcae83fc56d76442015cb8a39e9
Binary file resources/official_armmbed_example_badge.png has changed