質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • Arduino

    660questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

  • Processing

    317questions

    Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Arduino タッチされたとき1回だけ処理をさせるには

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,024

sasaquita

score 12

Processingでスイッチ化

いつもお世話になっております。
現在、ProcessingとArduinoを連携させてリズムゲームを作成しております。
手袋に導電糸をつけて、手のひらが合わさると、信号がProcessingに流れるようになっています。
※Arduinoでプルアップ式で、通電したら信号がPrcessingに行くようにしています。

画面のイメージとしては、下記のようなものになっております。
黒枠にボールが落ちてきた際に、タイミングよくスイッチを押すと点数が+1つき、失敗すると-1になる仕組みを作っております。

イメージ説明

しかし、手の平を合わせている間ずっと+1の処理がされてしまいます。
これを手の平をあわせてタップしたときだけ、1回だけ処理をするようにしたいです。
どうすればいいのでしょうか。

int num =3;
int count;
Ball[] ball = new Ball[num];

import processing.serial.*;
import cc.arduino.*;
import org.firmata.*;

final int sP = 5;
final int lp = 13;

final int sec = 10;
boolean waithing = true;

boolean b;

Arduino arduino;

void setup() {
  //ball = new Ball(width/2,100,30,1);
  count = 0;
  smooth();
  b = false;
  size(400, 400);
  arduino = new Arduino(this, "/dev/tty.usbmodem1411", 57600);
  arduino.pinMode(lp, Arduino.OUTPUT);
  arduino.pinMode(sP, Arduino.INPUT);
  background(255);
  frameRate(60);

  for (int i =0; i < ball.length; i++) {
    ball[i] =  new Ball(width/2, -i*50 - random(60, 100), 30, 2);
  }
}

void draw() {
  background(255);
  turnOn();
  fill(0);
  text("counter : " + count, 30, 30);
  fill(0, 0, 0, .5);
  rect(0, height-100, width, 50);

  for (int i = 0; i < ball.length; i++) {
    ball[i].move();
    ball[i].display();
    fill(0);
    text("this is " + i, ball[i].x+30, ball[i].y);
  }
}

class Ball {
  float x, y;
  float diameter;
  float speed;
  int direction =1;

  Ball(float xpos, float ypos, float dia, float spd) {
    x = xpos;
    y = ypos;
    diameter = dia;
    speed = spd;
  }
  void move() {
    y += (speed * direction);
    //if(y > (height - diameter/2) ||y < diameter/2){
    //  direction *= -1;
    //}
    if (y > height+diameter) {
      y = 0;
    }
  }

  void display() {
    ellipse(x, y, diameter, diameter);
  }
  void textSample(String txt) {
    textAlign(CENTER);
    fill(0);
    textSize(16);
    text("txt", x, y);
  }
  boolean finished() {
    if (y > height + diameter) {
      return true ;
    } else {
      return false;
    }
  }
}

void turnOn() {
  int val;
  val = arduino.digitalRead(sP);
  if (val == 0) {
    if ((ball[0].y > height-100) && (ball[0].y < height-50)) {
      count++; 
      fill(255, 0, 0);
      rect(0, height-100, width, 50);
    } else {
      count--; 
      fill(0, 0, 255);
      rect(0, height-100, width, 50);
    }
  }
}

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • MasahikoHirata

    2017/03/02 18:57

    ソースは恐らくprocessing側だと思われますが、arduino側も掲示して頂ければ。

    キャンセル

  • sasaquita

    2017/03/02 19:05

    arduino側はfirmateのstandardFirmateの例を書き込んでおります。

    キャンセル

回答 1

0

こんにちは。

①タップ検出時(val==0)の一回だけ「count++」を処理。
②2回目以降「count++」を実行されないようにすれば良いという理解で良いでしょうか?
→ 「count--」側も同じように繰り返し実行されてしまいますね。

それであれば、「前回のval値」を消されないよう保存しておいて、前回と同じ(val==0)なら「count処理」しないという風に考えてみましょう。
コードは以下のようになるでしょうか?
コメントがないので間違っていたらごめんなさい。
※:コードを他人に見てもらう時は特にコメントを入れた方が見えもらえる率が上がりますよ。
※:ビルドしていないのでエラー出るかもしれません。ご注意ください。

void turnOn() {
 // prev_valは、この関数から抜けても消えずに継続して使用するためstatic領域宣言
 // prev_valは、またval判定の初回時に無効になるのを防ぐため0以外に初期設定しておく
  satic int prev_val = 1; 
  int val; 

  val = arduino.digitalRead(sP);

  // val=0かつ前回値と違う時だけ処理する(つまりval=0でpre_val=1の時)
  if ((val == 0) && (prev_val != 0)) {
    if ((ball[0].y > height-100) && (ball[0].y < height-50)) {
        count++; 
        fill(255, 0, 0);
        rect(0, height-100, width, 50);
      }
    } else {
      count--; 
      fill(0, 0, 255);
      rect(0, height-100, width, 50);
    }
  }

  // 抜ける前に前回値を保存
  prev_val = val;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/03 02:32

    > ①タップ検出時(val==0)の一回だけ「count++」を処理。
    > ②2回目以降「count++」を実行されないようにすれば良いという理解で良いでしょうか?
    > → 「count--」側も同じように繰り返し実行されてしまいますね。
    こちらの理解であっております。

    夜遅くにありがとうございます。
    今、Arduinoの環境がなく試せないですが、明日、試してみます。

    コメント今後つけるようにします。
    今まで、そんなにコードを人を魅せる機会がなかったので、気づきませんでした。
    そういった作法まで教えていただきすごく助かります。
    ありがとうございます!

    キャンセル

  • 2017/03/03 22:08

    雰囲気あっているようで良かったです(笑)
    ArduinoIDEを使用せずに直接コードを書いてしまったので、「検証/マイコンボードへの書き込み」を押した時のビルド処理でエラー出るかもしれません。
    今読み直して見たらコメントも分かりにくい文章ですみません。
    わからないことがあったらまた聞いてください。結果報告でも結構です。

    キャンセル

同じタグがついた質問を見る

  • Arduino

    660questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

  • Processing

    317questions

    Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。