現在opencvで画像処理をしながら、別スレッドでmbedから送られてくる文字を表示するプログラムを作っています。
しかし、一度目は正しく動作するのですがプログラムを終了して2度目を開始するとシリアルポートを開くところで停止してしまいます。mbedを取り外すと正しくエラーが表示されており、もう一度mbedを接続しプログラムを実行すると正常に接続がされますが、2度目を開始すると、やはりシリアルポートを開くところで停止してしまいます。
環境はlinuxでc++です。プログラムは以下のようにしています。
#include <opencv2/objdetect/objdetect.hpp>
//////省略/////
using namespace cv;
using namespace std;
/////////camera設定//////////
#define CAM_W 320
#define CAM_H 240
#define WINNAME "camera"
#define pixel_8UC1(img,x,y) *((img)->data + ((img)->cols * (y) + (x)))
#define pixel_8UC3(img,x,y,c) *((img)->data + ((img)->cols * 3 * (y) + 3 * (x) + (c)))
#define RGB_DIFF 50
#define BUFFSIZE 256
/////////camera設定//////////
#define BAUDRATE B9600
#define MODEMDEVICE "/dev/tty.usbmodem1422"
#define BUFFSIZE 256
#define COULDNOTFORK -1
#define FALSE 0
#define TRUE 1
volatile int STOP = FALSE;
static int fd = -1;
void serial_init(int fd) {
struct termios tio;
memset(&tio, 0, sizeof(tio));
tio.c_cflag = CS8 |CLOCAL| CREAD;
tio.c_iflag = 0;
tio.c_oflag = 0;
tio.c_lflag = 0;
tio.c_cc[VMIN]= 1;
tio.c_cc[VTIME] = 0;
tio.c_lflag = ICANON;
tio.c_iflag = IGNPAR | ICRNL;
// ボーレートの設定
cfsetispeed(&tio, BAUDRATE);
cfsetospeed(&tio, BAUDRATE);
// デバイスに設定を行う
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &tio);
}
void *thred_func(void* std){
struct termios oldtio, newtio;
char buf[BUFFSIZE];
int count;
int check;
fd = open(MODEMDEVICE,O_RDWR|O_NOCTTY);//2度目以降ここで止まってしまいます
printf("serial OK \n");
if (fd < 0) {
perror(MODEMDEVICE);
return NULL;
}
tcgetattr(fd,&oldtio); /* 現在のシリアルポートの設定を待避させる*/
bzero(&newtio, sizeof(newtio));
serial_init(fd);
printf("recive\n");
while (FALSE == STOP) {
memset(&buf, 0, sizeof(buf));
count = read(fd, &buf, BUFFSIZE);
if (count < 0) {
fprintf(stdout, "CHILD:Could not read from serial port\n");
STOP = TRUE;
} else {
fprintf(stdout, "CHILD:RCVD CHAR %s %d \n", buf, count);
}
}
tcsetattr(fd,TCSANOW,&oldtio);
check = close(fd);
if (check != 0) {
printf("error\n");
}
fprintf(stdout, "CHILD:BYE!\n");
return NULL;
}
void construct_2(Mat src,Mat back_img,Mat *dst,Mat *mask){
............
}
int main(){
Mat frame,disp_img;
Mat background_img,mask,sub_img;
VideoCapture cap;
int key,state;
int flag = 0;
pthread_t th;
int stat;
char buf[BUFFSIZE];
stat = pthread_create(&th, NULL, thred_func, (void*)(buf));
cap.open(0);
if (!cap.isOpened())
return (1);
cap.set(CV_CAP_PROP_FRAME_WIDTH, CAM_W);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, CAM_H);
disp_img.create(Size(CAM_W, CAM_H),CV_8UC3);
background_img.create(Size(CAM_W, CAM_H),CV_8UC3);
mask.create(Size(CAM_W, CAM_H),CV_8UC1);
cap.read(frame);
background_img = frame.clone();
printf("start");
while (1) {
if (cap.grab() == false) {
printf("grab error\n");
continue;
}
if (cap.retrieve(frame,0) == 0) {
printf("retrieve error\n");
continue;
}
construct_2(frame, background_img, &disp_img, &mask);
imshow(WINNAME, disp_img);//結果の表示
blur(mask, mask, Size(5,5));
imshow("mask", mask);
////////何かキーが押されたら画像処理終了/////////
key = waitKey(1);
if(key >= 0){
switch (key) {
case 0x73:
background_img = frame.clone();
break;
default:
fprintf(stderr,"\nkey input %x\n",key);
flag = 1;
break;
}
}
if (flag != 0) {
break;
}
}
STOP = TRUE;
cap.release();
disp_img.release();
destroyWindow(WINNAME);
return(0);
}
No.1ベストアンサー
- 回答日時:
> プログラムを終了して2度目を開始するとシリアルポートを開くところで停止してしまいます。
このプログラムを終了ってメインスレッドを終了するのですよね。このときシリアル通信しているスレッドの方は正しく終了処理していないですよね。
シリアル通信が正しくクローズされていないので再オープンの際に待ちに入ってしまっているのではないかと思います。mbedを外すとシリアル回線がリセットされて次のオープンでは上手くいくのでしょう。
プログラム終了時に通信スレッドを止めてシリアル回線をクローズする必要があるでしょう。
回答ありがとうございます。マルチスレッドを使わずにシリアルポートをオープンするだけのプログラムでも同じ問題があったのですが、シリアルポートを”dev/tty.usbmodem1422”から”dev/cu.usbmodem1422”へ変更することで解決しました。
No.2
- 回答日時:
> プログラムを終了して2度目を開始するとシリアルポートを開くところで停止してしまいます。
このプログラムを終了ってメインスレッドを終了するのですよね。このときシリアル通信しているスレッドの方は正しく終了処理していないですよね。
シリアル通信が正しくクローズされていないので再オープンの際に待ちに入ってしまっているのではないかと思います。mbedを外すとシリアル回線がリセットされて次のオープンでは上手くいくのでしょう。
プログラム終了時に通信スレッドを停止してシリアル回線をクローズする処理を入れる必要があると思います。
回答ありがとうございます。シリアルポートを”dev/tty.usbmodem1422”から”dev/cu.usbmodem1422”へ変更することで解決しました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
2の補数を計算するプログラム
-
3のつく数と3の倍数を表示 C言語
-
ヌメロンのプログラム
-
C言語で%を使わない余りの出し方
-
whileとifを使い偶数を出すには
-
乱数で交互に偶数、奇数が、、、。
-
C++で表を作成したいのです ...
-
C++ bmp 透過処理
-
カードシャッフルのブログラム...
-
C言語 サイコロ 2つの値を返せない
-
C言語 格子点が多角形の中にあ...
-
複数の共有メモリの作成
-
opencvとmbedのシリアル通信で...
-
条件が多い場合
-
intとlongは同じ?
-
プログラムの考え方。
-
unsigned int に0xffffffを代入...
-
漸化式:nCrの計算(C言語)
-
コマンドプロンプトを使用して...
-
C言語で簡単なパックマンゲーム...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
再起呼び出しの回数をカウント...
-
C言語で%を使わない余りの出し方
-
画像の拡大・縮小
-
迷路を脱出する経路探索プログ...
-
分数の足し算をさせるプログラ...
-
C言語で簡単なパックマンゲーム...
-
C++で表を作成したいのです ...
-
条件が多い場合
-
複数の共有メモリの作成
-
ヒストグラム均等化処理プログラム
-
3のつく数と3の倍数を表示 C言語
-
argvのNULLチェック
-
乱数で交互に偶数、奇数が、、、。
-
プログラミングに関して
-
OpenCVによる4値化について
-
whileとifを使い偶数を出すには
-
16bitで乱数を生成する方法
-
再帰処理をループ処理に変換
おすすめ情報