ゲームサンプルの敵機出現間隔についての問題

このQ&Aのポイント
  • ゲームサンプルを改造し、敵機の出現間隔を均等にする処理につまずいています。
  • 特定のソースコードが問題となっており、その原因を調査しています。
  • 特定の処理で、ランダムな数値を用いていることが関係している可能性があります。
回答を見る
  • ベストアンサー

敵機の出現間隔

あるゲームサンプルを改造しているのですが、あるところでつまずきました。均等に出現間隔のはずの距離がずれて表示されます。問題と思われるソースはこれです。 void ControlEnemy::Main(void) { if(m_timer<APPEAR_WAIT) m_timer+=SPF; if(m_timer<APPEAR_WAIT) return; m_timer=0; if(GetCount(ENEMY)<m_max_enemy) { new Enemy((float)(rand()%WND_W),ENEMY_CY,ENEMY_SPEED,ENEMY_LIFE); } } rand()%WND_Wを定数にすると均等になるのですが、rand()%WND_Wにするとなぜか均等になりません。なぜなんでしょう?

  • 79562
  • お礼率68% (164/239)

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.5

>敵機が3体しかでていないはずなのにデバックには(rand()%WND_W)でやると存在するはずのない4つ目の数字が出てきます。これは一体何なのでしょうか? あなたがそう思っていてもプログラムが、そうなっていないからです。思い込みを出来るだけ排除しましょう。 ここで疑うなら敵の発生じゃなくて消滅も含めて色々あります。 ・等間隔でちゃんと消滅していないのでは? ・発生から消滅までちゃんとトレースしましたか? ・GetCountは信用できますか? ・m_max_enemyが変化する可能性がありませんか? 関連するところは全て疑って掛かるべきでしょう。とりあえず、自分のコード、他人のコード信用するなと言っておきます。

79562
質問者

お礼

回答ありがとうございます。なんとか均等に表示できるようになりました。rand()%WND_Wがいけなかったみたいです。rand()%WND_Wが640-31か32以下の時表示されないようになってました。それによって表示が遅れてたみたいです。ありがとうございました。

その他の回答 (4)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.4

もし、このコード内いだけで問題が起きているなら if(GetCount(ENEMY)<m_max_enemy) で弾かれているとしか思えませんね。 else側を通過してないかOutputDebugString()してみては? if~elseの通過は全て疑ってトレースするほうが良いですよ。 ありえないと思うけど if(m_timer<APPEAR_WAIT) m_timer+=SPF; if(m_timer<APPEAR_WAIT) return; も疑って掛かるのがデバッグです。

79562
質問者

お礼

回答ありがとうございます。if(GetCount(ENEMY)<m_maxenemy) をOutputDebugString()したのですが均等で問題はなかったです。ただ 敵機が3体しかでていないはずなのにデバックには(rand()%WND_W)でやると存在するはずのない4つ目の数字が出てきます。これは一体何なのでしょうか? void ControlEnemy::Main(void) { static int i=0; char str[256]; wchar_t str2[256]; i++; if(m_timer<APPEAR_WAIT){ m_timer+=SPF; } if(m_timer<APPEAR_WAIT) return; m_timer=0; i++; if(GetCount(ENEMY)<m_max_enemy) { sprintf(str,"%d\n ",i); mbstowcs(str2,str,256); OutputDebugString(str2); new Enemy((float)(rand()%(WND_W)),ENEMY_CY,ENEMY_SPEED,ENEMY_LIFE); } }

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

OutputDebugString()はVS2008だとパラメータは、UNICODEの文字列しか受け付けません。TCHARや_T()ってヤツですね。 char str[100]; sprintf(str,"xxx %d",x); OutputDebugString(str); とかしませんでした? TCHAR strt[100]; sprintf(strt,_T("xxx %d"),x); OutputDebugString(strt); で表示されると思います。 違ったら補足してください。

79562
質問者

お礼

回答ありがとうございます。できました。フレームがずれていました void ControlEnemy::Main(void) { static int fream=0; fream++; if(m_timer<APPEAR_WAIT) m_timer+=SPF; if(m_timer<APPEAR_WAIT) return; m_timer=0; if(GetCount(ENEMY)<m_max_enemy) { char str[256]; wchar_t str2[256]; float f; new Enemy(f=(float)(rand()%(WND_W)),ENEMY_CY,ENEMY_SPEED,ENEMY_LIFE); sprintf(str,"%f\t%d\t%d\n ",f,ENEMY_CY,i); mbstowcs(str2,str,256); OutputDebugString(str2); fream=0; } } とやりました。なぜフレームがずれてしまったのでしょうか?

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

とりあえず、敵に番号つけて、発生と同時に敵に番号、発生フレーム数(プログラム起動からの通算フレーム数)、発生座標をOutputDebugString()でVisualStudioに表示してみてはどうでしょう。 http://msdn.microsoft.com/ja-jp/library/cc428973.aspx これでタイミングとかが分ると思いますが。

79562
質問者

お礼

回答ありがとうございます。OutputDebugStringで表示させたら???????・・・と表示されてしまいます。なぜでしょか?

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

全容が分りませんが、X座標を乱数にしているだけですか? X座標が出現間隔に関係しないなら画面全体の座標がいつも固定である場合、いつも同じY座標に出現しますから周期はAPPEAR_WAITとSPFだけで決まるはずです。 なにか問題があるとしたら、ControlEnemy::Main(void)が呼ばれる周期が乱れている可能性があります。rand()%WND_Wは関係ないでしょう。

79562
質問者

お礼

回答ありがとうございます。そうです。調べたら多分周期は乱れていないと思うのですが、何か調べる方法があれば教えていただきたいのですが。問題となっているソースを提示します。// 全てのタスクを実行 void Task::RunTask(void) { if(g_buf==NULL) return; // タスクリストが初期化されていない Task *task,*next; for(task=(Task*)m_active; m_active; task=next) { task->Main(); next=task->m_next; if(next==(Task*)m_active) break; } if(g_buf+MEM_SIZE-m_free < DFRG_SIZE) Defrag(); // デフラグ }これだけでは難しいのでしょうか?

関連するQ&A

  • この円を分割して。。

    #include <stdio.h> #include <time.h> #include <stdlib.h> #define MAX 10000 void main(void) { int i; float x1, x2, en, sum=0.0, s; srand( (unsigned)time( NULL ) ); for(i=0;i<MAX;i++) { x1=((float)rand()/(float)RAND_MAX); x2=((float)rand()/(float)RAND_MAX); if(en=(x1-0.5)*(x1-0.5)+(x2-0.5)*(x2-0.5)<=(0.5)*(0.5)) { sum++; } } s=sum/MAX; printf("円の面積:%15.6e\n",s); } 円の面積を求める方法です。がもう少し精度をあげる工夫をしようと思うのですが、円を4分割した第一象限の部分に乱数をとばしその面積を求め、4倍することで求めたいのですがどうプログラムを変えたらいいか教えてください。

  • Win32APIで作るコンボボックスの高さの調整

    作成中のアプリもだいぶ必要機能を網羅出来て来て よーし、もうちょっとだ!ってとこに来て コンボボックスのドロップダウンが「ほとんど表示されてない」事に気付きました。 なんでやのんということで調べてみると どうやらCreateWindowExとかリソースとかで指定する「高さ」が コンボボックスでCBS_DROPDOWNLISTスタイル込みの場合 ドロップダウンを表示させたときのドロップダウンリストの高さを含むように 予約領域先に作っておかなければいけない、とのこと えー、クリックすると表示になる割に 「内部的に別々で自動的に高さ計算」 とかになってるんじゃないのー? ということで またしてもMicrosoftちゃんにしてやられたって気分ですが しょうがないのでちゃっちゃとクラス化してみました。 (ていうか、なんで他のコントロールはほとんど独自クラスにしてあるのに、コンボボックスはクラス化してなかったんだろうと、小一時間(ry)) なお、現状ではMFCは使えません(w | orz) あ、たぶん TcsLiteral → const TCHAR* const szt → size_t 以外のtypedefやdefineは見れば元が何なのか分かる(か、分かんなくても問題ないはず) と思うので省略しまふ(お) ヘッダ #pragma once class myComboBox { HWND wnd; szt num; public: myComboBox( HWND hw, int x, int y, int cx ); ~myComboBox(); BOOL Enable( BOOL b ) const { return EnableWindow( wnd, b ); } Void Select( Dword i ) const { SendMessage( wnd, CB_SETCURSEL, (WPARAM)i, 0 ); } Int GetIndex() const { return (Int)SendMessage( wnd, CB_GETCURSEL, 0, 0 ); } Void Setup() const; Void AddString( TcsLiteral s ){ SendMessage( wnd, CB_ADDSTRING , 0 , (LPARAM)s ); ++num; } Void AddStrings( TcsLiteral* const s, const szt num_ ){ for ( szt i = 0; i < num_; ++i ) SendMessage( wnd, CB_ADDSTRING , 0 , (LPARAM)s[i] ); num += num_; } }; ソース #include "StdAfx.h" #include "myComboBox.h" #include "FontLibrary.h" myComboBox::myComboBox( HWND hw, int x, int y, int cx ) : num(0) { wnd = CreateWindowEx(0, _T("COMBOBOX"), null , WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST , x, y , cx, 0, hw, null, HINST::me, null); } myComboBox::~myComboBox(){ DestroyWindow( wnd ); } Void myComboBox::Setup() const { RECT rc; GetClientRect( wnd, &rc ); int cy = (int)SendMessage( wnd, CB_GETITEMHEIGHT, -1, 0 ); cy += (int)SendMessage( wnd, CB_GETITEMHEIGHT, 0, 0 ) * num; cy += GetSystemMetrics(SM_CYEDGE) * 2; cy += GetSystemMetrics(SM_CYEDGE) * 2; SetWindowPos( wnd, null, 0, 0, rc.right, cy, SWP_NOMOVE|SWP_NOZORDER ); SendMessage( wnd, CB_SETCURSEL, 0 , 0 ); SendMessage( wnd, WM_SETFONT, (WPARAM)FontLibrary::Default, True ); } 使い方の例はこんな感じです。 wnd = CreateWindowEx( ~ ・ ・ ・ combo_measden = new myComboBox( wnd, 50, 200, 60 ); TcsLiteral c[] = { _T("1"), _T("2"), _T("4"), _T("8"), _T("16"), _T("32") }; combo_measden->AddStrings( c, sizeof c / sizeof(c[0]) ); combo_measden->Setup(); 解放時 /* Windows的には「HWNDの、子ウインドウ」のみについて言えば親ウインドウのDestroyのときに同時に自動解放してくれるようですが、どっちみちcombo_measdenポインタはdeleteかけないといけないので */ delete combo_measden; DestryWindow( wnd ); で、今回何が知りたいのかというと このSetup関数の中の int cy = (int)SendMessage( wnd, CB_GETITEMHEIGHT, -1, 0 ); cy += (int)SendMessage( wnd, CB_GETITEMHEIGHT, 0, 0 ) * num; cy += GetSystemMetrics(SM_CYEDGE) * 2; cy += GetSystemMetrics(SM_CYEDGE) * 2; SetWindowPos( wnd, null, 0, 0, rc.right, cy, SWP_NOMOVE|SWP_NOZORDER ); この調整部分です。 こんでXP以降のWindowsは全部OKですかね? XPはクラシックでもXP用のVisualスタイルでもおkっぽいですが。 その他の突っ込みどころもあれば募集致します。

  • 精度を上げたいのですが…

    #include <stdio.h> #include <time.h> #include <stdlib.h> #define MAX 1000 main(void) { int i; float x1, x2, en, sum=0.0, s; srand( (unsigned)time( NULL ) ); for(i=0;i<MAX;i++) { x1=((float)rand()/(float)RAND_MAX); x2=((float)rand()/(float)RAND_MAX); if(en=(x1-0.5)*(x1-0.5)+(x2-0.5)*(x2-0.5)<=(0.5)*(0.5)) { sum++; } } s=sum/MAX; printf("円の面積:%15.6e\n",s); } この方法で円の面積を求めたんですが、もう少し精度を上げたいと思います。ただそのプログラムをどうやって書けばいいのかさえわからずとまどっています。円全体でなくその一部を考え、またその部分を簡単に面積が求められるようにわけるプログラムを組みたいのですがどのようにすればいいのか教えてください。

  • プログラミングProcessing ピンポンゲーム

    Processingでピンポンゲームを作っています。作成したプログラムは void setup(){ size(400,300); } float x=10; float y=10; float dx=1; float dy=2; int count=0; float r_w=50.0; float a_w=15.0; float a_h=15.0; boolean checkHit(float x,float y){ if(y+a_h<250)return false; if(x+a_w>=mouseX&&x<=mouseX+r_w){ return true; }else{ return false; } } void draw(){ x=x+dx;y=y+dy; if(x+a_w>=400){ dx=-1; }else if(x<0){ dx=1; } if(y+a_w>300){ x=0; y=0; dx=1; dy=2; count=0; }else if(y<0){ dy=2; } background(0,0,128); rect(x,y,a_w,a_w); rect(mouseX,250,r_w,3); text(count,10,300); if(checkHit(x,y)){ dy=-2; count=count+1; } } このプログラムだとどうしてもラケットの下にボールが潜り込んだ時に ボールが跳ね返されてしまうバグが発生してしまいます。 問題はboolean checkHitの部分にあると思うのですが、 どのように調節すればよいか分かりません。 わかる方教えてください<(__)>

  • C言語初心者です!詳しい方教えて下さい!

    以下のソースコードは野球のピッチングで投げてからキャッチャーに届くまでの軌道を出力するもので、応用すればゴルフでボールを打ってから停止するまでの同様な数値が出力される。と言われて渡されたのですが、どこを変更すればいいのかわかりません。 変更したい数値は ボールの重さ、大きさ、発射角度、初速度 と 揚力係数 です。 void force(float cl, float cy, float cd, float ut, float vt, float wt, float *fx, float *fy, float *fz) { float g=9.8, rho=1.225, S=0.0042; float q, uv; q = sqrt(ut*ut + vt*vt + wt*wt); uv = sqrt(ut*ut + vt*vt); *fx = -0.5*rho*S*q*q*(ut/q*cd+vt/uv*cy+wt/q*ut/uv*cl); *fy = -0.5*rho*S*q*q*(vt/q*cd-ut/uv*cy+wt/q*vt/uv*cl); *fz = -MASS*g-0.5*rho*S*q*q*(wt/q*cd-uv/q*cl); } void integra(float cl, float cy, float cd, float *xt, float *yt, float *zt, float *ut, float *vt, float *wt, float dt) { float u1, v1, w1, u2, v2, w2, fx, fy, fz; force(cl, cy, cd, *ut, *vt, *wt, &fx, &fy, &fz); u1 = *ut + fx*dt/MASS; v1 = *vt + fy*dt/MASS; w1 = *wt + fz*dt/MASS; force(cl, cy, cd, u1, v1, w1, &fx, &fy, &fz); u2 = 0.5*(u1 + *ut + fx*dt/MASS); v2 = 0.5*(v1 + *vt + fy*dt/MASS); w2 = 0.5*(w1 + *wt + fz*dt/MASS); *xt += 0.5*dt*(*ut + u2); *yt += 0.5*dt*(*vt + v2); *zt += 0.5*dt*(*wt + w2); *ut = u2; *vt = v2; *wt = w2; } int main() { float x[256], y[256], z[256]; int i; float dt=0.01; float dis=18.44; float cy, cl, cd=0.5; float xt, yt, zt, ut, vt, wt, us; float va, la; int white[3] = {255, 255, 255}; int red [3] = {255, 0, 0}; int green[3] = { 0, 255, 0}; int blue [3] = { 0, 0, 255}; int grey [3] = { 64, 64, 64}; int j; float ye[10], ze[10]; float yst[5] = {-0.215, 0.215, 0.215, -0.215, -0.215}; float zst[5] = {0.5, 0.5, 1.2, 1.2, 0.5}; sleep(1); for (j=0;j<10;j++) { xt = 0.0, yt=0.0, zt=1.8; printf("初速度(~150)km/h==>"); scanf ("%g", &us); if (us<=0.0) exit(0); us = us*1000.0/3600.0; printf("上下角(-5~5)(deg.)==>"); scanf ("%g", &va); va = va*PI/180.0; printf("左右角(-5~5)(deg.)==>"); scanf ("%g", &la); la = la*PI/180.0; ut = us*cos(la)*cos(va); vt = us*sin(la); wt = us*cos(la)*sin(va); printf("CL(-1~1)==>"); scanf ("%g", &cl); printf("CY(-1~1)==>"); scanf ("%g", &cy); printf("t x t z\n"); for (i=0; xt<=dis; i++) { x[i] = xt; y[i] = yt; z[i] = zt; integra(cl, cy, cd, &xt, &yt, &zt, &ut, &vt, &wt, dt); printf("%g %g %g %g\n", dt*(float)(i+1), xt, yt, zt); } ye[j] = yt, ze[j] = zt; } }

  • このプログラムを関数で小分けしたいんですが・・・

    #include <stdio.h> #include <stdlib.h> int main(void) { int n; int player; // プレイヤーの手 int enemy; // 相手の手 srand(0); // 乱数列を初期化 do { puts("じゃん けん (グー:1 チョキ:2 パー:3) "); scanf("%d", &player); //相手の手を計算 enemy = rand() % 3 + 1; // 勝ち負けを判定 if(enemy == player) { printf("あいこ~\n"); } else if(player == 1 && enemy == 2) { printf("Win!\n"); } else if(player == 2 && enemy == 3) { printf("Win!\n"); } else if(player == 3 && enemy == 1) { printf("Win!\n"); } else { printf("Lose・・・\n"); } printf("0を押したら終了。続けるなら適当な数字"); scanf("%d", &n); // n が 0 以外だったら続ける }while(n != 0); return 0; } このように、じゃんけんをするプログラムを作ったのですが メインだけでは出来たのですが、相手の手の判定や勝ち負けの判定などを 上手く関数でコンパクトにまとめたいんですが、 関数を殆ど使った事が無いので良く分かりません。 このプログラムを上手くコンパクトに関数に分けてくれませんか?

  • beginthread 引数

    #include <windows.h> #include <process.h> class CPti4Dlg::public CDialog { public: void test(void*); } void CPti4Dlg::test(void *) {    long ret;    float data[4]; ret = PtMultiInputEx(m_Id, 4, data); if(ret != 0) { ErrorHandling("PtMultiInputEx", ret); if(ret != 20102){ return; } } m_Edit_Ch0 = data[0]; m_Edit_Ch1 = data[1]; m_Edit_Ch2 = data[2]; m_Edit_Ch3 = data[3]; UpdateData(FALSE); } void CPti4Dlg::OnButtonInput() { _beginthread(&CPti4Dlg::test,0,NULL); m_Edit_Ret.SetWindowText("入力処理:正常終了"); } error C2664: '_beginthread' : 1 番目の引数を 'void (__thiscall CPti4Dlg::* )(void *)' から 'void (__cdecl *)(void *)' に変換できません。(新しい機能 ; ヘルプを参照) ------------------------------------------------------------------------------ これ問題全然ないです。 void CPti4Dlg::OnButtonInput() {    long ret;    float data[4]; ret = PtMultiInputEx(m_Id, 4, data); if(ret != 0) { ErrorHandling("PtMultiInputEx", ret); if(ret != 20102){ return; } } m_Edit_Ch0 = data[0]; m_Edit_Ch1 = data[1]; m_Edit_Ch2 = data[2]; m_Edit_Ch3 = data[3]; UpdateData(FALSE); m_Edit_Ret.SetWindowText("入力処理:正常終了"); }

  • プログラム

    #include "CScreen.h" #include <math.h> //定数定義 #define LAST_PAS_X (30) void main(void) { float sam=3.1415926f; float jim,zak=0,dom=12; int x=40,y=12,X,Y; CUROFF(); for(jim=1.0f;jim<dom;jim+=0.035f) //ループ開始 { X=(int)(x+cos(zak)*jim*2); Y=(int)(y+sin(zak)*jim); LOCATE(X,Y); COLOR(rand()%7+1); //色の処理 { printf("**"); //**入力 } WAIT(10); zak+=0.1F; while(zak>=sam*2) //*ループ { zak-=sam*2; } } //ループ終了 LOCATE(1,24); } 関数ヘッダとはなんですか。 どこに関数ヘッダを書けばいいのですか?  詳しく教えてください。

  • 代入されません(C言語)

    こんにちは。 早速質問させていただきます。 申し訳ありませんが、問題の概要など話し始めるととても時間がかかってしまう為省略させていただきます。 下記のプログラムなのですが(私はプロではないため醜いプログラムですがご了承ください)、 #include <stdio.h> int num[8][5] = {{0,0,0,0,0},{0,0,1,0,0},{0,1,0,0,0},{0,1,1,0,0}, {1,0,0,0,0},{1,0,1,0,1},{1,1,0,1,0},{1,1,1,0,0}}; int ic = 0; int i=0, j=0; int id=0;//IDナンバー int m0=0, m1=0, m2=0; //中間層 int z0=0, z1=0; int t0=0, t1=0; double s0=0,s1=0; //総和 double w00=0, w01=0, w02=0, w10=0, w11=0, w12=0;//重み double sikii0=1, sikii1=1; //しきい値(θ) θ0とθ1 int t; //正解 double hoge = 0.1; double mm0, mm1, mm2; //p2. 4)学習 で使用 //プロトタイプ宣言 void input(void); void tyukan(void); void souwa(void); //総和 void hantei(void); void seikai(void); void omomi1(void); void omomi2(void); main(){ while(ic<70){ if(id > 7){ id=0; i=0; j=0; } getchar(); printf("IC = %d ID = %d\n", ic, id); input(); tyukan(); souwa(); hantei(); seikai(); if(z0 != t0) omomi1(); else if(z1 != t1) omomi2(); i++; ic++; id++; } return 0; } void input(){ printf("入力データ M=%d A=%d B=%d\n", num[i][j], num[i][j+1], num[i][j+2]); } void tyukan(){ if(id == 0){ m0=0; m1=0; m2=0; mm0=0; mm1=0; mm2=0; s0=0; s1=0; } m0=num[i][0]+num[i][1]+num[i][2]; m1=num[i][0]+num[i][1]; m2=num[i][0]+num[i][2]; //中間層m0m1m2に代入 mm0 = (double)m0; mm1 = (double)m1; mm2 = (double)m2; printf("中間層 m0=%d m1=%d m2=%d \n", num[i][0]+num[i][1]+num[i][2], num[i][0]+num[i][1], num[i][0]+num[i][2]); } void souwa(void){ printf("総和 s0=%f s1=%f\n",(double)m0*w00 + (double)m1*w01 + (double)m1*w02, (double)m0*w10 + (double)m1*w11 + (double)m2*w12); } //*****関数判定***************************************** void hantei(void){ printf("判定は "); if(s0 >= sikii0){ printf("z0 = 1 "); z0=1; } else{ printf("z0 = 0 "); z0=0; } if(s1 >= sikii1){ printf("z1 = 1\n"); z1=1; } else{ printf("z1 = 0\n"); z0=0; printf("sikii1 %f\n",sikii1); printf("sikii0 %f\n",sikii0); } } void seikai(void){ printf("正解は "); printf("t0 = %d t1 = %d\n", num[id][3], num[id][4]); t0=num[id][3]; t1=num[id][4]; } void omomi1(void){ if(z0 == 0 && t0 == 1){ w00 = w00 + (hoge*mm0); w01 = w01 + (hoge*mm1); w02 = w02 + (hoge*mm2); sikii0 = sikii0-hoge; printf("重み変更 00 %f\n重み変更 01 %f\n重み変更 02 %f\n", w00, w01, w02); printf("閾値 %f\n", sikii0); } else if(z0 == 1 && t0 == 0){ w00 = w00 - (hoge*mm0); w01 = w01 - (hoge*mm1); w02 = w02 - (hoge*mm2); sikii0 = sikii0+hoge; printf("重み変更 00 %f\n重み変更 01 %f\n重み変更 02 %f\n", w00, w01, w02); printf("閾値 %f\n", sikii0); } } void omomi2(void){ if(z1 == 0 && t1 == 1){ w10 = w10 + (hoge*mm0); w11 = w11 + (hoge*mm1); w12 = w12 + (hoge*mm2); sikii1 = sikii1-hoge; printf("重み変更 10 %f\n重み変更 11 %f\n重み変更 12 %f\n", w10, w11, w12); printf("閾値 %f\n", sikii1); } else if(z1 == 1 && t1 == 0){ w10 = w10 - (hoge*mm0); w11 = w11 - (hoge*mm1); w12 = w12 - (hoge*mm2); sikii1 = sikii1+hoge; printf("重み変更 10 %f\n重み変更 11 %f\n重み変更 12 %f\n", w10, w11, w12); printf("閾値 %f\n", sikii1); } } 問題はこのプログラムがID7になった時に発生します。 関数hanteiの部分で s0 >= sikii0とs1 >= sikii1がそれぞれ真だったらz0(またはz1)に1を代入するように 作ったのですが、 IC=7 ID=7の部分では,s0が1.20でsikii0が0.9(s0>=sikii0)にもかかわらず z0に1が代入されません(s1とsikii1も同様)。 いろいろ考えてみましたが、原因が分かりませんでした。 どなたかよろしくお願いします。

  • ATTiny13Aが省電力化できない

    ATTiny13Aでフォトカプラを一定時間ONにする回路を作成しましたが、省電力にできません。 仕様としては10分、30分、60分をジャンパー等で選択し、ボタンを押したら一定時間の間、フォトカプラをONにします。 また、途中で再度、割り込みがあっても時間の延長はしません。 LR44電池2個で1年以上、動けばと思っています。 コードも拙い上、回路図もまともに書けない初心者ですが、よろしくお願いいたします。 #include <avr/wdt.h> #include <avr/sleep.h> //LED_PIN #define LED_PIN (5) //interrupt pin #define ACC_IN (2) //Time_select #define TIME_PIN1 (0) #define TIME_PIN2 (4) #define TIME_PIN3 (1) volatile int sleep_flg=0; volatile int counter; int count_max=15;//4second * 15 = 60 second int wait_minutes=1;//wait_time (minutes) //arduino wakeup interrupt void wakeUp() { //wdt_reset(); //sleep end sleep_flg = 0; //counter reset counter = 0; } //watch dog timer setup void wdt_set() { wdt_reset(); cli(); MCUSR = 0; WDTCR |= 0b00011000; //WDCE WDE set WDTCR = 0b01000000 | 0b100000;//WDIE set |WDIF set scale 4 seconds sei(); } //watch dog timer unset void wdt_unset() { wdt_reset(); cli(); MCUSR = 0; WDTCR |= 0b00011000; //WDCE WDE set WDTCR = 0b00000000; //status clear sei(); } //watch dog timer call ISR(WDT_vect) { //wdt_reset(); if(sleep_flg == 1) { counter++; if( counter >= (count_max * wait_minutes)) { //sleep end sleep_flg = 0; //counter reset counter = 0; } } else { } } //status reset void init_status() { counter=0; } //sleep arduino void sleep() { wdt_set(); //watch dog timer set sleep_flg=1; //enable on sleep flag set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set sleep mode attachInterrupt(0,wakeUp, RISING); //set level interrupt while(sleep_flg){ noInterrupts(); //cli(); sleep_enable(); interrupts(); //seii(); sleep_cpu(); //cpu sleep sleep_disable(); byte adcsra_old = ADCSRA; //NEW ADCSRA = 0; //NEW ADCSRA = adcsra_old; //NEW } wdt_unset(); //watch dog timer unset detachInterrupt(0); //unset level interrupt } //set up void setup() { init_status(); pinMode(LED_PIN,OUTPUT); pinMode(ACC_IN, INPUT); pinMode(TIME_PIN1, INPUT); pinMode(TIME_PIN2, INPUT); pinMode(TIME_PIN3, INPUT); } //main loop void loop() { if(!digitalRead(ACC_IN)) { sleep(); //sleep if (digitalRead(0) == HIGH) { digitalWrite(5, HIGH); //delay(1800000); // Wait for 1800 second(s) uint16_t i; for (i = 0; i < 10*60; i++) { _delay_ms(1000); } digitalWrite(5, LOW); delay(1000); // Wait for 1 second(s) } else { if (digitalRead(4) < HIGH) { digitalWrite(5, HIGH); //delay(600000); // Wait for 600 second(s) uint16_t i; for (i = 0; i < 30*60; i++) { _delay_ms(1000); } digitalWrite(5, LOW); delay(1000); // Wait for 1 second(s) } else { if (digitalRead(1) < HIGH) { digitalWrite(5, HIGH); //delay(36000000000); // Wait for 3600 second(s) uint16_t i; for (i = 0; i < 60*60; i++) { _delay_ms(1000); } digitalWrite(5, LOW); delay(1000); // Wait for 1 second(s) } else { delay(1000); // Wait for 1 second(s) } } } sleep(); //sleep } }

専門家に質問してみよう