ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Javaの課題丸投げコミュの失礼します。次のプログラムを改良して頂きたいのですが・・・

  • mixiチェック
  • このエントリーをはてなブックマークに追加
これらのプログラムはjpegカメラを起動させ、撮った写真データを無線(ZigBee)でパソコンに送信する、というものです。


○MainFrame.java
import java.awt.*;
import javax.swing.* ;
import java.io.*;
import gnu.io.*;

public class MainFrame extends JFrame{
public static void main(String[] args) {
JFrame frame = new MainFrame();
Canvas canvas = new Canvas();
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
catch(Exception e){ }
Thread t = new Thread(canvas);
t.start();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(canvas);
frame.setSize(400, 400);
frame.setVisible(true);
}
}



○Canvas.java
import java.awt.*;
import javax.swing.* ;
import java.io.*;
import gnu.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

class Canvas extends JPanel implements Runnable{
public sport com=null;
public String com_number = "COM6"; //私のPCではCOM6
public int baut_rate = 115200; //ZigBee使用のため
//public InetAddress target_ip=null;
public Image img=null;
public int image_count=0, jpeg_size=0;
public byte[] jpeg_data =new byte[0xFFFF]; //画像データ用配列Max64kbyte
private volatile Thread th=null;
private int status=-1;
private int i=0, j=0, k=0, loop=0, data_size=0, get_size_flag=0;
private String str=null;
private byte[] data =new byte[1024]; //受信データ用配列
// public File f = new File("C:\\Documents and Settings\\i06326\\C328\\image.jpg");
public BufferedImage bimg = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);

// Commands of C328-7640 Camera
byte[] sync ={ -86,13, 0, 0, 0, 0 };//0xAA,0x0D, 00,00,00,00
byte[] ack ={ -86,14,13, 0, 0, 0 };//0xAA,0x0E,0x0D,00,00,00
byte[] initial ={ -86, 1, 0, 7, 7, 5 };//0xAA,0x01,JPEG, size
byte[] package_size={ -86, 6, 8, 0, 2, 0 };//0xAA,0x06,512byte
byte[] get_picture ={ -86, 4, 5, 0, 0, 0 };//0xAA,0x04,Get Preview Picture
byte[] ack_with_id ={ -86,14, 0, 0, 0, 0 };//0xAA,0x0E,Package ID
byte[] ack_last_id ={ -86,14, 0, 0, -16, -16 };//0xAA,0x0E,Package LastID
byte[] reset ={ -86, 8, 0, 0, 0, 0 };//0xAA,0x08,Reset whole system
byte[] Power_Off ={ -86, 9, 0, 0, 0, 0 };//0xAA,0x09,

Canvas(){ setBackground(new Color(255,255,255)); }
public void run(){
while(true){
if( status==-1 ){
img=null;
try{
if(com == null){
com = new sport(com_number,baut_rate);
if(com.comID != null) status=0;
}
}
catch(Exception e){ }
repaint();//paintメソッド呼出し
try{
if( status==0 ){
// com.bsend(reset);//Send reset
// Thread.sleep(1000);
i=0; data=com.receives(com.length());//buffer clear
while( i<60 ){//sending sync 60 count
com.bsend(sync); Thread.sleep(20);//sending sync & wait
if( com.length()==12 ){//12byte受信を確認
com.bsend(ack);//sending sync
status=1; i=60;//C328応答に対する処理
}
++i;
}
}
}
catch(Exception e){}
repaint();//paintメソッド呼出し
try{
if( status==1 ){
i=0; data=com.receives(com.length());//buffer clear
com.bsend(initial);
while( i<2000 ){
Thread.sleep(2);
if( com.length()>=6 ){
status=2; i=2000;//inital OK
}
++i;
}
}
}
catch(Exception e){}
repaint();//paintメソッド呼出し
try{
if( status==2 ){
i=0; data=com.receives(com.length());//buffer clear
com.bsend(package_size);
while( i<2000 ){
Thread.sleep(2);
if( com.length()>=6 ){
status=3; i=2000;//inital OK
Thread.sleep(2000);
//wait for 1-2seconds befor capturing the first picture
}
++i;
}
}
}
catch(Exception e){}
}// if( status==-1 )のカッコを閉じる
try{
if( status==3 ){
i=0; data=com.receives(com.length());//buffer clear
com.bsend(get_picture);//Send get_picture
while( i<2000 ){
Thread.sleep(2);
if( com.length()>=12 ){
status=4; i=2000;//get picture OK
}
++i;
}
}
}
catch(Exception e){}

try{
loop=0; j=0;
while( status==4 ){
data=com.receives(com.length());//buffer clear
get_size_flag=0; i=0; ack_with_id[4]=(byte)loop;
com.bsend(ack_with_id);// send ack with ID
while( i<5000 ){
Thread.sleep(2);
if( get_size_flag==0 && com.length()>=4 ){
data=com.receives(4);
data_size=((data[3]<<8) & 0xFF00)+(data[2] & 0xFF)+2;//+VerifyCode 2byte
if( data_size > 508 || 2 > data_size ) break;//data_sizeが正常範囲外
get_size_flag=1;//データサイズが正常取得出来た時に1となる
}
if( get_size_flag==1 ){
if(com.length()>=data_size){
data=com.receives(data_size);
for(k=0; k<(data_size-2); ++k){//末尾のVerifyCode 2byteを除外
jpeg_data[j]=data[k]; ++j;//JPEG用配列に代入
}
i=9999;//data_size分の受信があれば正常処理として出る
if( data_size<508 ){//data_size==0が正常処理としてあり得る
status=5; com.bsend(ack_last_id);
}
}
}
++i;
}
if( i<9999 ) break; //所定の量のデータが来なかった
if( loop>100 ) break;//1枚の画像は最大でも70Data Package程度なので100は異常
if( j>0xFFFF ) break;//画像は最大でも40kbye程度なので64kbyteは異常
++loop; data=com.receives(com.length());//buffer clear
}//本ループは正常終了ならばstatus=5、異常ならばstatus=4のままで出る。
}
catch(Exception e){}
if( status==5 ){
img = getToolkit().createImage( jpeg_data ); ++image_count;
jpeg_size=j; status=3; repaint();//paintメソッド呼出し
}else{//異常発生時の処理
try{
com.bsend(Power_Off); Thread.sleep(50);
if(com != null) com.disconnect();
com = null;
Thread.sleep(8000); //再接続前にwaitを入れる
}
catch(Exception e){}
status=-1; repaint();//paintメソッド呼出し
}
}//while( th==thisThread)のループを閉じる
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if( status==-1 ){
if(str == null){str = "sport関数がおかしい?";}
g.drawString(str,10,30);
g.drawString("Portが既に使用されている可能性があります。",10,50);
}
if( status==0 ){
g.drawString("TCP接続完了、次にカメラとの通信を試みています",10,30);
}
if( status==1 || status==2 )
g.drawString("カメラと通信中",160,110);
if( image_count>0 && status>=3 ){
g.drawImage(img ,0, 20, this );//JPEG画面を描画
save(img);
if( (image_count % 10)!=0 ){
str=" カメラ "+image_count+" 枚目 "+jpeg_size/1000 +" kbyte";
}
g.drawString(str,10,10);
}
}
void save(Image image){
Graphics gr = bimg.getGraphics();
gr.drawImage(image, 0, 0, null);
gr.dispose();
try{
ImageIO.write(bimg, "jpeg", new File("C:\\Documents and Settings\\i07325\\image.jpg"));
}catch(Exception e){
System.out.println("ファイル書き込みエラー");
}
}
}



○sport.java
//シリアルポート関連
import java.applet.Applet;
import java.*;
import java.lang.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.io.*;
import gnu.io.*;

public class sport{
public SerialPort port = null;
protected CommPortIdentifier comID = null;
public DataInputStream dis = null;
protected DataOutputStream dos = null;
protected String message = "(´・ω・`)";

public sport(String ComName,int BaudRate){
try{
comID = CommPortIdentifier.getPortIdentifier(ComName);
message = "COMPORT OK!";
System.out.println(ComName+" BaudRate="+BaudRate);
}
catch (Exception e) {
message = "Error opening socket";
System.out.println("Error opening socket");
return;
}
//もしポートが既に開いていないなら、ポートを開いて各種設定を行います。
if(comID.isCurrentlyOwned()==false){
try
{
//シリアルポートのインスタンスを生成
port = (SerialPort)comID.open("serial_camera",2000);
//ボーレート、データビット数、ストップビット数、パリティを設定
port.setSerialPortParams(BaudRate,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
//フロー制御はしない
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
}
catch(Exception e){ message="うまく開けませんでした。";}
}
else{ message="すでに開いています。"; }

try{ // Create an input stream
dis = new DataInputStream( new BufferedInputStream(port.getInputStream()));
}
catch (Exception ex) { message="Error creating input stream"; }

try{ // Create an output stream
dos = new DataOutputStream( new BufferedOutputStream(port.getOutputStream()));
}
catch (Exception ex) { message="Error creating output stream"; }
}

public synchronized void disconnect(){
if (port != null){
try{ port.close(); }
catch (Exception e){ }
}
}


public synchronized void bsend(byte[] temp){
try{
for(int i=0;i<temp.length;i++){
System.out.print(temp[i]);
}
System.out.println("");
dos.write(temp, 0, temp.length);
dos.flush();
}
catch(Exception ex) {
message = "Error sending data : " + ex.toString();
}
}

public synchronized byte[] receives(int length){
byte[] retval = new byte[length];
try{
dis.read(retval);
}
catch (IOException e){ }
return(retval);
}

public synchronized int length(){
int len = 0;
try{
len = dis.available();
}
catch (IOException e){ }
return len;
}
}



このプログラムにタイマー機能を付けて、リセットができるようにしたいのです。例えば、撮影ができないようなことになった場合、自分の手で電源を切る(リセットする)のではなく、プログラム自体でリセットをかけ、無理矢理撮影ができるようにしたいのです。

10分おきにリセットをかけ、それから撮影を開始する。というものが望ましいです。

よろしくお願い致します。

コメント(3)

問題の切り分けができてないね。まずカメラとZigbeeの説明くらいしたら?
ここの部分はJavaとは関係ないわけだしさ。まぁZigbeeだからふつうにシリアル通信だろうけど
リセットをかけるメソッド(コマンド)は実装してるの?
シリアル通信での特定のカメラのリセットコマンドなんて知らないよ。
ソース長いからあんまし詳しくは見てないです。
10分おきの起動自体は精度を求めないんだったら単純に
◎メインのカメラの接続確認のあたり
if(!isConnected)restart();

*適当にメソッド追加?*
restart(){
 while(true){
  min=10;//休止時間設定
  Thread.sleep(min*60*1000);
  if(camera.reset)break;//カメラのリセット(カメラ制御がcameraオブジェクトだとして)
 }
}

とかでもすればいいのでは?
あ、ごめんなさい。接続が切れたらじゃなく撮影できなかったらだねw
接続切れたらリセット信号も出せないじゃんww
まぁ見るフラグの違いか。
それにソース見たらもともと撮影できなかった時の処理書いてるっぽいね。

try{
 com.bsend(Power_Off); Thread.sleep(50);
 if(com != null) com.disconnect();
 com = null;
 Thread.sleep(8000); //再接続前にwaitを入れる
}
のところで異常発生時の処理してるんじゃないの?
そこをうえみたいに10分おきで繰り返すように変えたらどうでしょうか
お早い返事ありがとうございます。

失礼致しました。
確かにいくつか不足しておりました。


このプログラムはカメラの撮影した映像を監視することを目的として作成しました。データ処理端末がカメラの制御コマンドを無線で送信し、カメラの起動、撮影等を制御します。
データ処理端末はカメラが取得した映像を無線受信し、JPEG画像に復元、表示します。

ZigBeeに関しましてはお察しの通りシリアル通信です。
通信速度は20kbps〜250kbps。使用周波数帯は2.4GHz帯です。
私が今使用している物では通信距離が約1Kmとなっています。

チュン様@オルコッ党様の方法でまずはやってみようと思います。
また何かありましたら戻ってくるかもしれません。
その時もよろしくお願い致します。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Javaの課題丸投げ 更新情報

Javaの課題丸投げのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング