温度センサー LM35DZ
温度センサー LM35DZ を使用したときのデータです。まだ、校正途中です。
2021.6.23 今振り返りますが、LM35DZ温度センサーの出力をマイコンのアナログ端子(A0)へ直接接続していました。
この事は、インピーダンスの関係では問題が何かしらあると考えます。
A0端子の入力インピーダンスとLM35DZの出力インピーダンスの関係です。
この問題があり不安定な受信(受信記録)データとなったと考えます。
回路を追加する実験をします。
後日の報告となります。
温度センサー LM35DZ
温度センサー LM35DZ を使用したときのデータです。まだ、校正途中です。
2021.6.23 今振り返りますが、LM35DZ温度センサーの出力をマイコンのアナログ端子(A0)へ直接接続していました。
この事は、インピーダンスの関係では問題が何かしらあると考えます。
A0端子の入力インピーダンスとLM35DZの出力インピーダンスの関係です。
この問題があり不安定な受信(受信記録)データとなったと考えます。
回路を追加する実験をします。
後日の報告となります。
:START
@echo off
echo Hello Tom 10min. interval logger. eternally
cd C:\Users\ __\Documents\MyRuby
ruby RS232C_280.rb
timeout 600 /NOBREAK > NUL
REM 600-->10min
GOTO START
------------------------------------------------------
10分間隔の起動です。10分インターバルです。
プログラムを起動してからそのプログラムが終了する時間をT1とします。
インターバル時間をT2とします。すると、周期をTとするとT=T1+T2 となります。
ここで、T1=600(SEC),T2=(1SEC)
と仮定すると、1日(24時間)では24X6=144回実行します。T2の1(SEC)が144秒遅れで現れます。144/60=2.4分
これが、インターバル時間による問題と言えば問題です。
これが嫌なら、
高度に時刻に厳密に実行させたいなら、割り込み処理を行わせます。
途中
Ruby(ルビー)をはじめました
//+++++++ 各文の分かりやすい注釈文(コメント)が欲しいです +++++++
// +++++ コンパイルができたので、とにかく何とかなりそうな予感がします +++
// +++ minGW でコンパイルができました。ワーニングは出ました。ですが、+++
//++++ コンパイルエラーではなかったです +++++++++++++
//Good.
//東京工業大学ロッボト技術研究会さんありがとうございました。私、何とか自力でCompileできました。
//■C:\MinGW\RS232C> mingw32-g++ RS232C~1.CPP 私の現在のマシンはデヴァイスマネージャーでCOM1・COM6を表示していたのでCOM1を記述しました。
//私のマシンのCOM6は現在DataLoggerBで稼働使用中です。
// Compileエラー無し。ワーニングはあり。
/* RS232Cプログラムを書く方法ですが、
・C#やVBで.NETFrameworkを利用する
・C++でWin32APIを利用する
の二つの方法があるようですが、私がCしか触れたことがないのでWin32APIをつかって作ります。
またWindowsアプリケーションはよくわからないのでコンソールアプリケーションを想定しています。
全体の流れは
1.ファイルとしてCOMポートを開く
2.送信バッファの設定
3.送受信バッファの初期化
4.COMポート構成情報の初期化
5.タイムアウトの設定
でRS232C通信が使えるようになります。
今回の通信の仕様は
RTS,CTSフロー制御なし
9600bps
データサイズ8bit
パリティビットなし
ストップビット1bit
main()関数内での受信処理
です。
まずはいくつかのヘッダファイルを読み込んでおきましょう。*/
#include <string>//良く知らん
#include <stdio.h>//printfなどの標準入出力関数を使うためのヘッダファイル
#include <windows.h>//Wi32APIを使うためのヘッダファイル
#include <tchar.h>//_T()使うのに要る
int main(void){
//1.COMポートを開く
// HANDLE hComPort;//COMポートのハンドルいろいろ使うのでグローバル変数にしておくとよい
// hComPort = CreateFile( //ファイルとしてポートを開く
// _T("COM4"),// ポート名を指すバッファへのポインタ:COM4を開く(デバイスマネージャでどのポートが使えるか確認)
// GENERIC_READ | GENERIC_WRITE, // アクセスモード:読み書き両方する
// 0, //ポートの共有方法を指定:オブジェクトは共有しない
// NULL, //セキュリティ属性:ハンドルを子プロセスへ継承しない
// OPEN_EXISTING, //ポートを開き方を指定:既存のポートを開く
// 0, //ポートの属性を指定:同期 非同期にしたいときはFILE_FLAG_OVERLAPPED
// NULL // テンプレートファイルへのハンドル:NULLって書け
// );
HANDLE hComPort;
hComPort = CreateFile(
_T("COM1"), //@@@@@@@@@@@@@@@@@@@@@@@@@ ここ
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hComPort == INVALID_HANDLE_VALUE){//ポートの取得に失敗
printf("指定COMポートが開けません.\n\r");
CloseHandle(hComPort);//ポートを閉じる
return 0;
}
else{
printf("COMポートは正常に開けました.\n\r");
}
/*ポートをファイルとみなしCreateFile()関数を用いて開きます。失敗するとINVALID_HANDLE_VALUEを返します。
ポートの属性は非同期(FILE_FLAG_OVERLAPPED)にした方がいいらしいですが上手くいかなかったので同期通信にしてあります。
2.送受信バッファの設定 */
int check;//エラーチェック用の変数
check = SetupComm(
hComPort,//COMポートのハンドラ
1024,//受信バッファサイズ:1024byte
1024//送信バッファ:1024byte
);
if (check == FALSE){
printf("送受信バッファの設定ができません.\r\n");
CloseHandle(hComPort);
return 0;
}
else{
printf("送受信バッファの設定が完了しました.\r\n");
}
/*SetupComm()関数を用いて送受信バッファの設定をします。
3.送受信バッファの初期化 */
check = PurgeComm(
hComPort,//COMポートのハンドラ
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR//出入力バッファをすべてクリア
);
if (check == FALSE){
printf("送受信バッファの初期化ができません.\r\n");
CloseHandle(hComPort);
return 0;
}
else{
printf("送受信バッファの初期化が完了しました.\r\n");
}
/* PurgeComm()関数を用いて出入力すべてのバッファをクリアします。
4.COMポート構成情報の初期化 */
DCB dcb;//構成情報を記録する構造体の生成
GetCommState(hComPort, &dcb);//現在の設定値を読み込み
dcb.DCBlength = sizeof(DCB);//DCBのサイズ
dcb.BaudRate = 9600;//ボーレート:9600bps
dcb.ByteSize = 8;//データサイズ:8bit
dcb.fBinary = TRUE;//バイナリモード:通常TRUE
dcb.fParity = NOPARITY;//パリティビット:パリティビットなし
dcb.StopBits = ONESTOPBIT;//ストップビット:1bit
dcb.fOutxCtsFlow = FALSE;//CTSフロー制御:フロー制御なし
dcb.fOutxDsrFlow = FALSE;//DSRハードウェアフロー制御:使用しない
dcb.fDtrControl = DTR_CONTROL_DISABLE;//DTR有効/無効:DTR無効
dcb.fRtsControl = RTS_CONTROL_DISABLE;//RTSフロー制御:RTS制御なし
dcb.fOutX = FALSE;//送信時XON/XOFF制御の有無:なし
dcb.fInX = FALSE;//受信時XON/XOFF制御の有無:なし
dcb.fTXContinueOnXoff = TRUE;// 受信バッファー満杯&XOFF受信後の継続送信可否:送信可
dcb.XonLim = 512;//XONが送られるまでに格納できる最小バイト数:512
dcb.XoffLim = 512;//XOFFが送られるまでに格納できる最小バイト数:512
dcb.XonChar = 0x11;//送信時XON文字 ( 送信可:ビジィ解除 ) の指定:XON文字として11H ( デバイス制御1:DC1 )
dcb.XoffChar = 0x13;//XOFF文字(送信不可:ビジー通告)の指定:XOFF文字として13H ( デバイス制御3:DC3 )
dcb.fNull = TRUE;// NULLバイトの破棄:破棄する
dcb.fAbortOnError = TRUE;//エラー時の読み書き操作終了:終了する
dcb.fErrorChar = FALSE;// パリティエラー発生時のキャラクタ(ErrorChar)置換:なし
dcb.ErrorChar = 0x00;// パリティエラー発生時の置換キャラクタ
dcb.EofChar = 0x03;// データ終了通知キャラクタ:一般に0x03(ETX)がよく使われます。
dcb.EvtChar = 0x02;// イベント通知キャラクタ:一般に0x02(STX)がよく使われます
check = SetCommState(hComPort, &dcb); //設定値の書き込み
if (check == FALSE){//エラーチェック
printf("COMポート構成情報の変更に失敗しました.\r\n");
CloseHandle(hComPort);
return 0;
}
else{
printf("COMポート構成情報を変更しました.\r\n");
}
/* DCB構造体で構成情報を設定します。今回すべての変数について書き込んでいますが、GetCommState()関数で基本情報を読み込んでいるため変更する部分だけ書き換えればいいです。
ボーレートやデータサイズ、パリティビット、ストップビットなどはマイコン側とあわせてください。
書き換えた後にSetCommState()関数で再設定を行います。*/
//5.タイムアウト時間の設定
COMMTIMEOUTS TimeOut; // COMMTIMEOUTS構造体の変数を宣言
GetCommTimeouts(hComPort, &TimeOut); // タイムアウトの設定状態を取得
TimeOut.ReadTotalTimeoutMultiplier = 0;//読込の1文字あたりの時間:タイムアウトなし
TimeOut.ReadTotalTimeoutConstant = 1000;//読込エラー検出用のタイムアウト時間
//(受信トータルタイムアウト) = ReadTotalTimeoutMultiplier × (受信予定バイト数) + ReadTotalTimeoutConstant
TimeOut.WriteTotalTimeoutMultiplier = 0;//書き込み1文字あたりの待ち時間:タイムアウトなし
TimeOut.WriteTotalTimeoutConstant = 1000;//書き込みエラー検出用のタイムアウト時間
//(送信トータルタイムアウト) = WriteTotalTimeoutMultiplier ×(送信予定バイト数) + WriteTotalTimeoutConstant
check = SetCommTimeouts(hComPort, &TimeOut);//タイムアウト設定の書き換え
if (check == FALSE){//エラーチェック
printf("タイムアウトの設定に失敗しました.\r\n");
CloseHandle(hComPort);
return 0;
}
else{
printf("タイムアウトの設定に成功しました.\r\n");
}
/*構成情報の設定と似た手順です。COMMTIMEOUTS構造体を使い、GetCommTimeouts()関数で基本情報を取得し、変更したのちSetCommTimeouts()関数で書き換えています。各値はよく知りませんがこんな感じが多いです。
ここまででCOMポートの初期設定ができました次に送信してみましょう。
6.送信 */
char SendData[] = "17";//送信データの用意
int SendSize = strlen(SendData)+1;//送信データサイズを取得
DWORD writeSize;//実際に送信したデータサイズ
WriteFile(hComPort,SendData,SendSize,&writeSize,NULL);
/* WriteFile()関数を用いて送信。送信するデータサイズはNULL文字の分+1するのを忘れないように。
7.受信 */
int i = 0;
char RecieveChar[1];//1文字受信のための変数
char RecieveData[100];//受信文字列
unsigned long nn;
while (1) {
ReadFile(hComPort, RecieveChar, 1, &nn, 0); // シリアルポートに対する読み込み
if (nn == 1) {
if (RecieveChar[0] == 10 || RecieveChar[0] == 13) { // '\r'や'\n'を受信すると文字列を閉じる
if (i != 0) {
RecieveData[i] = '\0';//最後にNULL文字を付加して
i = 0;//文字列を先頭に戻す
printf("%s\n", RecieveData);//受信した文字列を表示
}
}
else {
RecieveData[i] = RecieveChar[0];//受信した文字を文字列にする
i++;
}
}
}
}
/*ReadFil()関数で1文字ずつ受信して'\r'や'\n'で文字列の切り分けを行っています。
受信のタイミングは分からないのでスレッド受信にすべきなのですが、スレッドに関して未だ理化していないことが多いので今回はwhileで回し続けています。
VisualStudio2013で作り、PIC32MX440FとRS23C通信を行いました。
数字を文字データとして送信しPICが素数かどうか判定して素数だと「~ is a prime! 」と返すプログラムを書いて実行したところ。*/
//--------------------------------------------------------------
//COM1を指定して、Compileし、実行しました
//Compilerは ■C:\MinGW\RS232C> mingw32-g++ RS232C~1.CPP
//C:\MinGW\RS232C>a.exe
//---------------------------------------------------------------
//COMポートは正常に開けました.
//送受信バッファの設定が完了しました.
//送受信バッファの初期化が完了しました.
//COMポート告ャ|情報を変更しました.
//タイムアウトの設定に成功しました.
//------------------------------------------------------------------------------------------------------------------------------
//なるメッセージを表示しました
//c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot open output file a.exe: Permission denied
//はa.exegaがすでに実行中においてCompile実行をしたからです。
//--------------------------------------------------------------------------------------------------------------------------------