none
Visualstudio + Accelerometer RRS feed

  • 質問

  • 私は大学院生で、surfaceを用いて、visualstudioで、空のプロジェクトを作成し、開発を進めています。

    研究の方針で、使っているsurface内の加速度センサを用いることになり、今使っているプロジェクトから加速度センサーを呼びたいです。複数のサイトをみて、プロパティをいじったりしたのですが、うまくいきません。

    どうすればいいでしょうか。

    2016年8月2日 1:13

回答

  • 空のプロジェクトから作成しているアプリケーションはコンソールだとかATLやMFCのデスクトップアプリケーションといった形式がありますが、どの形式で進めているのでしょうか。

    たとえばコンソールアプリと以下のようにSensor APIで加速度センサの値を取得できました
    #コードレシピの「[C++] Native Code (VC++) で Windows 7 Sensor API を使う」を加速度センサに書き換え

    #include "stdafx.h"
    //#include "targetver.h"
    //#include <stdio.h>
    //#include <tchar.h>
    
    //#include <atlbase.h> // ATLを参照
    //#include <atlstr.h>
    
    //#include <INITGUID.H>
    //#include <SensorsApi.h>
    //#include <sensors.h>
    //#include <iostream>
    
    class CSensorEventSink : public ISensorEvents
    {
    public:
    	// ISensorEvents で定義されているイベント 
    	STDMETHOD(OnStateChanged)(ISensor* pSensor, SensorState state);
    	STDMETHOD(OnLeave)(REFSENSOR_ID sensorID);
    	STDMETHOD(OnDataUpdated)(ISensor* pSensor, ISensorDataReport* pNewData);
    	STDMETHOD(OnEvent)(ISensor* pSensor, REFGUID eventId, IPortableDeviceValues* pEventData);
    
    	// 以下は、COMのおまじない 
    	CSensorEventSink() : m_lRefCount(0) {}
    	STDMETHODIMP QueryInterface(REFIID riid, void **ppObject)
    	{
    		*ppObject = 0;
    		if (riid == __uuidof(ISensorEvents))    {
    			*ppObject = reinterpret_cast<ISensorEvents*>(this);
    		}
    		else if (riid == IID_IUnknown) {
    			*ppObject = reinterpret_cast<IUnknown*>(this);
    		}
    		else {
    			return E_NOINTERFACE;
    		}
    		(reinterpret_cast<IUnknown*>(*ppObject))->AddRef();
    		return S_OK;
    	}
    	ULONG _stdcall AddRef() {
    		m_lRefCount++;
    		return m_lRefCount;
    	}
    	ULONG _stdcall Release() {
    		ULONG lRet = --m_lRefCount;
    		if (m_lRefCount == 0) delete this;
    		return lRet;
    	}
    
    private:
    	long m_lRefCount;
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	//DebugBreak();
    	MessageBox(0, _T("WAIT"), NULL, 0);
    	CoInitializeEx(NULL, COINIT_MULTITHREADED);
    
    	// センサーマネージャを取り出す為の変数 
    	CComPtr<ISensorManager> pSensorManager = NULL;
    	// 取得したセンサーを格納する為の変数 
    	CComPtr<ISensor> pAccelerometerSensor = NULL;
    
    	// センサーがサポートするプロパティのキーを格納するコレクション 
    	IPortableDeviceKeyCollection* pKeys;
    	// センサーがサポートするプロパティ値を格納するコレクション。キーと値のペアを格納 
    	IPortableDeviceValues* pValues;
    
    	// センサーマネージャの取得 
    	HRESULT hr = CoCreateInstance(
    		__uuidof(SensorManager), NULL, CLSCTX_INPROC_SERVER,
    		__uuidof(ISensorManager),
    		(LPVOID*)&pSensorManager);
    
    	// センサーコレクション変数 
    	CComPtr<ISensorCollection> pAccelerometerSensors;
    
    	// 加速度センサーを取り出す 
    	hr = pSensorManager->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D, &pAccelerometerSensors);
    
    	if (!SUCCEEDED(hr))
    	{
    		return 1;
    	}
    
    	PROPERTYKEY pKey;
    	PROPVARIANT pValue;
    
    	while (true)
    	{
    		// 取得に成功したので、複数の候補から所望のセンサーを取り出す 
    		DWORD count = 0;
    		hr = pAccelerometerSensors->GetCount(&count);
    		for (DWORD i = 0; i < count; i++) {
    			CComPtr<ISensor> pCandidate;
    			hr = pAccelerometerSensors->GetAt(i, &pCandidate);
    			if (SUCCEEDED(hr))
    			{
    				pAccelerometerSensor = pCandidate;
    
    				// 例えばフレンドリーネームを条件にする場合 
    				BSTR friendlyName;
    				hr = pCandidate->GetFriendlyName(&friendlyName);
    				// 取得したフレンドリーネームを基に比較等を行い、確定 
    				std::wcout << friendlyName << "\t";
    				SysFreeString(friendlyName);
    
    				// センサーの説明を取得
    				hr = pAccelerometerSensor->GetProperty(SENSOR_PROPERTY_DESCRIPTION, &pValue);
    				std::wcout << pValue.pwszVal << std::endl;
    				PropVariantClear(&pValue);
    
    				// サポートするプロパティキーを取得する 
    				HRESULT hr = pAccelerometerSensor->GetSupportedDataFields(&pKeys);
    				if (SUCCEEDED(hr))
    				{
    					// 取得したキーに対応する変数群を取り出す 
    					ISensorDataReport* pNewData;
    					hr = pAccelerometerSensor->GetData(&pNewData);
    
    					if (SUCCEEDED(hr))
    					{
    						hr = pNewData->GetSensorValues(pKeys, &pValues);
    						if (SUCCEEDED(hr)){
    							DWORD count = 0;
    							hr = pKeys->GetCount(&count);
    							for (DWORD i = 0; i < count; i++){
    								hr = pKeys->GetAt(i, &pKey);
    								if (!SUCCEEDED(hr))
    								{
    									continue;
    								}
    								// プロパティ値を取り出す。 
    								hr = pValues->GetValue(pKey, &pValue);
    								if (!SUCCEEDED(hr))
    								{
    									continue;
    								}
    								switch (pValue.vt)
    								{
    								case VT_I8:
    									std::cout << pValue.intVal << "\t";
    									break;
    								case VT_R4:
    									std::cout << pValue.fltVal << "\t";
    									break;
    								case VT_R8:
    									std::cout << pValue.dblVal << "\t";
    									break;
    								case VT_FILETIME:
    									FILETIME ft = pValue.filetime;
    									FILETIME ftLocal;
    									SYSTEMTIME st;
    
    									FileTimeToLocalFileTime(&ft, &ftLocal);
    									FileTimeToSystemTime(&ftLocal, &st);
    									std::wcout << st.wYear << L"/" << st.wMonth << L"/" << st.wDay << L" " 
    										       << st.wHour << L":" << st.wMinute << L":" << st.wSecond << L"\t";
    
    									break;
    								}
    								PropVariantClear(&pValue);
    							}
    							std::cout << std::endl;
    						}
    					}
    				}
    
    				break;
    			}
    		}
    
    		Sleep(100);
    	}
    
    	CoUninitialize();
    	return 0;
    }
    #イベントでなくループで取出してます


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 星 睦美 2016年8月3日 2:29
    • 回答としてマーク ken120 2016年8月3日 3:39
    2016年8月2日 18:06
  • Visual C++ の 「空のプロジェクト」 から新規作成してみました。(Surfaceで動作確認済)

    1. Visual C++ の 「空のプロジェクト」 を作成
    2. プロジェクトに「Source.cpp」を追加して、下記をコピペ
    #include <iostream>
    
    using namespace Platform;
    using namespace Windows::Devices::Sensors;
    
    [MTAThread]
    int main(void)
    {
    	Accelerometer^ accelerometer = Accelerometer::GetDefault();
    	if (accelerometer)
    	{
    		accelerometer->ReadingChanged += ref new Windows::Foundation::TypedEventHandler<Accelerometer^, AccelerometerReadingChangedEventArgs^>(
    			[](Accelerometer^ sender, AccelerometerReadingChangedEventArgs^ args) {
    			std::cout << "X:" << args->Reading->AccelerationX;
    			std::cout << "Y:" << args->Reading->AccelerationY;
    			std::cout << "Z:" << args->Reading->AccelerationZ << std::endl;
    		});
    	}
    	std::cin.get();
    	return 0;
    }

    1. プロジェクトのプロパティで「構成のプロパティ」→「C/C++」→「全般」→「追加の #using ディレクトリ」に下記の2つのパスを追加。


    C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages\

    C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\

    1. 同じ画面で「Windows ランタイム拡張機能の使用」を「はい (/ZW)」に設定
    2. 「構成のプロパティ」→「C/C++」→「コード生成」の「最小リビルドを有効にする」を「いいえ (/Gm-)」に設定
    3. プロジェクトをビルド&実行

    ※3のパスは環境によって異なるかもしれません。(Platform.winmdとWindows.winmdが存在するフォルダをそれぞれ追加しました)

    作成したプロジェクトは、http://work.vc/Project1.zip に置いています。


    • 編集済み kenjinoteMVP 2016年8月3日 1:26
    • 回答の候補に設定 星 睦美 2016年8月3日 2:29
    • 回答としてマーク ken120 2016年8月3日 3:39
    2016年8月3日 1:13

すべての返信

  • こんにちは、

    以下のサイトから加速度センサーを使うためのサンプルがダウンロードできます。

    https://code.msdn.microsoft.com/windowsapps/Accelerometer-Sensor-Sample-22982671

    参考になりますでしょうか?

    > 複数のサイトをみて、プロパティをいじったりしたのですが、うまくいきません。
    どの部分がどううまくいかなかったのか、具体的に質問されたほうが回答が得やすいかと思います。
    Visual Studioのバージョンや言語の詳細も教えてください。
    2016年8月2日 1:31
  • 返信ありがとうございます。

    こちらは以前試そうとしたのですが、このサンプルはwindows8用でして、申し上げてなかったのですが、自分はwindows10で開発しています。そのため、このサンプルは起動できません。

    詳細としまして、windows10のvisualstudio2015で、言語はC++です。

    私が行ったのは、空のプロジェクトを立ち上げ、プロパティからwindowsランタイムの拡張をして、加速度センサーのクラスである、Accelerometerを使用するための、Windows::Devices::sensorsの名前空間の使用を可能にし、Accelerometer::GetDefault()を使用しました。コンパイルは通ったのですが、実行時に、中断されてしまい、その原因がわかりません。

    2016年8月2日 1:42
  • 私の環境 (Surface, Windows 10, Visual Studio 2015) では上記サンプルは、Visual Studio 2015 でビルドでき、動きました。加速度もリアルタイムで取得できていました。

    サンプルではターゲットが Windows 8.1 でしたので、「空白のアプリ(ユニバーサル Windows)」のプロジェクトを新規に作成し、必要なコードをサンプルからコピー&ペーストして動作させてみましたが、やはり動きました。

    MainPage.xaml.cpp

    //
    // MainPage.xaml.cpp
    // MainPage クラスの実装。
    //
    
    #include "pch.h"
    #include "MainPage.xaml.h"
    
    using namespace App1;
    
    using namespace Platform;
    using namespace Windows::Foundation;
    using namespace Windows::Foundation::Collections;
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Xaml::Controls::Primitives;
    using namespace Windows::UI::Xaml::Data;
    using namespace Windows::UI::Xaml::Input;
    using namespace Windows::UI::Xaml::Media;
    using namespace Windows::UI::Xaml::Navigation;
    using namespace Windows::Devices::Sensors;
    using namespace Windows::UI::Core;
    
    MainPage::MainPage()
    {
    	InitializeComponent();
    	accelerometer = Accelerometer::GetDefault();
    
    	if (accelerometer)
    	{
    		uint32 minReportInterval = accelerometer->MinimumReportInterval;
    		accelerometer->ReportInterval = minReportInterval > 16 ? minReportInterval : 16;
    		readingToken = accelerometer->ReadingChanged::add(ref new TypedEventHandler<Accelerometer^, AccelerometerReadingChangedEventArgs^>(this, &MainPage::ReadingChanged));
    	}
    }
    
    void MainPage::ReadingChanged(Accelerometer^ sender, AccelerometerReadingChangedEventArgs^ e)
    {
    	Dispatcher->RunAsync(
    		CoreDispatcherPriority::Normal,
    		ref new DispatchedHandler(
    			[this, e]()
    	{
    		AccelerometerReading^ reading = e->Reading;
    
    		ScenarioOutput_X->Text = reading->AccelerationX.ToString();
    		ScenarioOutput_Y->Text = reading->AccelerationY.ToString();
    		ScenarioOutput_Z->Text = reading->AccelerationZ.ToString();
    	},
    			CallbackContext::Any
    		)
    	);
    }

    MainPage.xaml.h

    //
    // MainPage.xaml.h
    // MainPage クラスの宣言。
    //
    
    #pragma once
    
    #include "MainPage.g.h"
    
    namespace App1
    {
    	/// <summary>
    	/// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    	/// </summary>
    	public ref class MainPage sealed
    	{
    	public:
    		MainPage();
    
    	private:
    		Windows::Foundation::EventRegistrationToken readingToken;
    		Windows::Devices::Sensors::Accelerometer^ accelerometer;
    		void ReadingChanged(Windows::Devices::Sensors::Accelerometer^ sender, Windows::Devices::Sensors::AccelerometerReadingChangedEventArgs^ e);
    	};
    }


    作成したプロジェクトは下記からダウンロードできます。
    http://work.vc/AccelerometerCPP.zip

    参考になりますでしょうか?

    2016年8月2日 8:51
  • 返信ありがとうございます。

    空白のアプリで作成したみたところ、動作の確認できました。

    しかし、私が今開発を進めているのは、空のプロジェクトのほうです。これだと加速度が動作しません。

    アプリのほうでないといけないのでしょうか。

    (今開発を進めているプロジェクトをアプリのほうに移行するのは環境設定等のため、かなりの手間です)

    2016年8月2日 12:56
  • 空のプロジェクトから作成しているアプリケーションはコンソールだとかATLやMFCのデスクトップアプリケーションといった形式がありますが、どの形式で進めているのでしょうか。

    たとえばコンソールアプリと以下のようにSensor APIで加速度センサの値を取得できました
    #コードレシピの「[C++] Native Code (VC++) で Windows 7 Sensor API を使う」を加速度センサに書き換え

    #include "stdafx.h"
    //#include "targetver.h"
    //#include <stdio.h>
    //#include <tchar.h>
    
    //#include <atlbase.h> // ATLを参照
    //#include <atlstr.h>
    
    //#include <INITGUID.H>
    //#include <SensorsApi.h>
    //#include <sensors.h>
    //#include <iostream>
    
    class CSensorEventSink : public ISensorEvents
    {
    public:
    	// ISensorEvents で定義されているイベント 
    	STDMETHOD(OnStateChanged)(ISensor* pSensor, SensorState state);
    	STDMETHOD(OnLeave)(REFSENSOR_ID sensorID);
    	STDMETHOD(OnDataUpdated)(ISensor* pSensor, ISensorDataReport* pNewData);
    	STDMETHOD(OnEvent)(ISensor* pSensor, REFGUID eventId, IPortableDeviceValues* pEventData);
    
    	// 以下は、COMのおまじない 
    	CSensorEventSink() : m_lRefCount(0) {}
    	STDMETHODIMP QueryInterface(REFIID riid, void **ppObject)
    	{
    		*ppObject = 0;
    		if (riid == __uuidof(ISensorEvents))    {
    			*ppObject = reinterpret_cast<ISensorEvents*>(this);
    		}
    		else if (riid == IID_IUnknown) {
    			*ppObject = reinterpret_cast<IUnknown*>(this);
    		}
    		else {
    			return E_NOINTERFACE;
    		}
    		(reinterpret_cast<IUnknown*>(*ppObject))->AddRef();
    		return S_OK;
    	}
    	ULONG _stdcall AddRef() {
    		m_lRefCount++;
    		return m_lRefCount;
    	}
    	ULONG _stdcall Release() {
    		ULONG lRet = --m_lRefCount;
    		if (m_lRefCount == 0) delete this;
    		return lRet;
    	}
    
    private:
    	long m_lRefCount;
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	//DebugBreak();
    	MessageBox(0, _T("WAIT"), NULL, 0);
    	CoInitializeEx(NULL, COINIT_MULTITHREADED);
    
    	// センサーマネージャを取り出す為の変数 
    	CComPtr<ISensorManager> pSensorManager = NULL;
    	// 取得したセンサーを格納する為の変数 
    	CComPtr<ISensor> pAccelerometerSensor = NULL;
    
    	// センサーがサポートするプロパティのキーを格納するコレクション 
    	IPortableDeviceKeyCollection* pKeys;
    	// センサーがサポートするプロパティ値を格納するコレクション。キーと値のペアを格納 
    	IPortableDeviceValues* pValues;
    
    	// センサーマネージャの取得 
    	HRESULT hr = CoCreateInstance(
    		__uuidof(SensorManager), NULL, CLSCTX_INPROC_SERVER,
    		__uuidof(ISensorManager),
    		(LPVOID*)&pSensorManager);
    
    	// センサーコレクション変数 
    	CComPtr<ISensorCollection> pAccelerometerSensors;
    
    	// 加速度センサーを取り出す 
    	hr = pSensorManager->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D, &pAccelerometerSensors);
    
    	if (!SUCCEEDED(hr))
    	{
    		return 1;
    	}
    
    	PROPERTYKEY pKey;
    	PROPVARIANT pValue;
    
    	while (true)
    	{
    		// 取得に成功したので、複数の候補から所望のセンサーを取り出す 
    		DWORD count = 0;
    		hr = pAccelerometerSensors->GetCount(&count);
    		for (DWORD i = 0; i < count; i++) {
    			CComPtr<ISensor> pCandidate;
    			hr = pAccelerometerSensors->GetAt(i, &pCandidate);
    			if (SUCCEEDED(hr))
    			{
    				pAccelerometerSensor = pCandidate;
    
    				// 例えばフレンドリーネームを条件にする場合 
    				BSTR friendlyName;
    				hr = pCandidate->GetFriendlyName(&friendlyName);
    				// 取得したフレンドリーネームを基に比較等を行い、確定 
    				std::wcout << friendlyName << "\t";
    				SysFreeString(friendlyName);
    
    				// センサーの説明を取得
    				hr = pAccelerometerSensor->GetProperty(SENSOR_PROPERTY_DESCRIPTION, &pValue);
    				std::wcout << pValue.pwszVal << std::endl;
    				PropVariantClear(&pValue);
    
    				// サポートするプロパティキーを取得する 
    				HRESULT hr = pAccelerometerSensor->GetSupportedDataFields(&pKeys);
    				if (SUCCEEDED(hr))
    				{
    					// 取得したキーに対応する変数群を取り出す 
    					ISensorDataReport* pNewData;
    					hr = pAccelerometerSensor->GetData(&pNewData);
    
    					if (SUCCEEDED(hr))
    					{
    						hr = pNewData->GetSensorValues(pKeys, &pValues);
    						if (SUCCEEDED(hr)){
    							DWORD count = 0;
    							hr = pKeys->GetCount(&count);
    							for (DWORD i = 0; i < count; i++){
    								hr = pKeys->GetAt(i, &pKey);
    								if (!SUCCEEDED(hr))
    								{
    									continue;
    								}
    								// プロパティ値を取り出す。 
    								hr = pValues->GetValue(pKey, &pValue);
    								if (!SUCCEEDED(hr))
    								{
    									continue;
    								}
    								switch (pValue.vt)
    								{
    								case VT_I8:
    									std::cout << pValue.intVal << "\t";
    									break;
    								case VT_R4:
    									std::cout << pValue.fltVal << "\t";
    									break;
    								case VT_R8:
    									std::cout << pValue.dblVal << "\t";
    									break;
    								case VT_FILETIME:
    									FILETIME ft = pValue.filetime;
    									FILETIME ftLocal;
    									SYSTEMTIME st;
    
    									FileTimeToLocalFileTime(&ft, &ftLocal);
    									FileTimeToSystemTime(&ftLocal, &st);
    									std::wcout << st.wYear << L"/" << st.wMonth << L"/" << st.wDay << L" " 
    										       << st.wHour << L":" << st.wMinute << L":" << st.wSecond << L"\t";
    
    									break;
    								}
    								PropVariantClear(&pValue);
    							}
    							std::cout << std::endl;
    						}
    					}
    				}
    
    				break;
    			}
    		}
    
    		Sleep(100);
    	}
    
    	CoUninitialize();
    	return 0;
    }
    #イベントでなくループで取出してます


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 星 睦美 2016年8月3日 2:29
    • 回答としてマーク ken120 2016年8月3日 3:39
    2016年8月2日 18:06
  • 自分はコンソールで進めているのですが、掲載していただいたのを実行した結果、取得できました。

    使用させていただきます。

    本当にありがとうございました。

    2016年8月3日 1:09
  • Visual C++ の 「空のプロジェクト」 から新規作成してみました。(Surfaceで動作確認済)

    1. Visual C++ の 「空のプロジェクト」 を作成
    2. プロジェクトに「Source.cpp」を追加して、下記をコピペ
    #include <iostream>
    
    using namespace Platform;
    using namespace Windows::Devices::Sensors;
    
    [MTAThread]
    int main(void)
    {
    	Accelerometer^ accelerometer = Accelerometer::GetDefault();
    	if (accelerometer)
    	{
    		accelerometer->ReadingChanged += ref new Windows::Foundation::TypedEventHandler<Accelerometer^, AccelerometerReadingChangedEventArgs^>(
    			[](Accelerometer^ sender, AccelerometerReadingChangedEventArgs^ args) {
    			std::cout << "X:" << args->Reading->AccelerationX;
    			std::cout << "Y:" << args->Reading->AccelerationY;
    			std::cout << "Z:" << args->Reading->AccelerationZ << std::endl;
    		});
    	}
    	std::cin.get();
    	return 0;
    }

    1. プロジェクトのプロパティで「構成のプロパティ」→「C/C++」→「全般」→「追加の #using ディレクトリ」に下記の2つのパスを追加。


    C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages\

    C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\

    1. 同じ画面で「Windows ランタイム拡張機能の使用」を「はい (/ZW)」に設定
    2. 「構成のプロパティ」→「C/C++」→「コード生成」の「最小リビルドを有効にする」を「いいえ (/Gm-)」に設定
    3. プロジェクトをビルド&実行

    ※3のパスは環境によって異なるかもしれません。(Platform.winmdとWindows.winmdが存在するフォルダをそれぞれ追加しました)

    作成したプロジェクトは、http://work.vc/Project1.zip に置いています。


    • 編集済み kenjinoteMVP 2016年8月3日 1:26
    • 回答の候補に設定 星 睦美 2016年8月3日 2:29
    • 回答としてマーク ken120 2016年8月3日 3:39
    2016年8月3日 1:13
  • 返信ありがとうございます!!

    この方法でも動作確認できました。

    ずっと悩んでいたので、解決できてとてもうれしいです。

    ありがとうございました!!

    2016年8月3日 1:45
  • フォーラム オペレーターの星 睦美です。ken120 さん、こんにちは。
    今回はMSDN フォーラムでのken120 さんの質問へフォーラム ユーザーからの回答があり、解決できたようですね。

    回答者への良いフィードバックになりますので、参考になった回答には投稿者から[回答としてマーク] をお願いしています。

    では、これからもMSDN フォーラムをお役立てください。


    フォーラム オペレーター 星 睦美 - MSDN Community Support



    • 編集済み 星 睦美 2016年8月3日 2:30 編集
    2016年8月3日 2:28