2007.8.23

  • 評価実験~
完成し、評価実験に入ったけど、LED赤が反応しなくなりました。
はやく原因を究明して実験続けないとWISSがやばい。

今まで困ってたこと関連の記述を見つけたので、書いておく。
最近知識が増えてきて、やっと「こういうことか!」と気がついた。

ArduinoのベースになってるWiringは、processingの様に手軽に
電子工作を「スケッチ」できる、難しいC言語とかを書かなくても
簡単に赤外線やサーボの制御ができたりするツール。ただし、16bit
タイマ2つと8bitタイマ1つがWiringに占有されているので、タイ
マ処理(スレッドの様なもの)が使えない。また、外部入力やUSART
受信など全ての割り込みが使えないので、1つのloop()メソッドの
中で全てを処理しなければならなくなる。例えば、delay()で停止
中にセンサからの入力があっても受け取ることができないのが弱点。
ただ、そういう時はCPUを増やす(Wiring/Arudinoを2つ使う)と
いう技でどうにかなる。
s.h.log - Arduino - UART、LED、AD変換を試した より
いつもお世話になっているページです。

なるほど、pwm制御に苦労する訳だ・・・。processingに対応してるだけあって、やはりprocessingに値を渡してディスプレイを制御するほうが断然簡単!!
今は色々と試行錯誤の結果、黄色LEDで呼吸(吸う、吐く)を表現する部分はanalogWrite()、赤⇔青もグラデーション?はdigitalWrite()を使用している。どちらかに統一すると、電圧とか実行時間が不安定になるので、これが一番最良である。もうひとつ、digitalWrite()とdelayMicroseconds()を吸うmaxのときに赤外線LEDで1を28個分送信するのに使用している。しかしこれ以上analogWrite()やdigitalWrite()を使うとどうしても動作が不安定になるので、同期したことを知らせるLED制御がどうしても不安定になってしまっている。少なくともdigitalWrite()は無理そうだ。


  • ダミー呼吸
ダミーの呼吸を使う実験用に、ダミー呼吸データを記録してプログラムに書いたらプログラム容量オーバーになったので、呼吸データをまず0と1(上昇と下降:吐息と吸息)にした。それでもまだ容量が大きかったので、1が出現するときのtの値と1の続いた数にデータ圧縮した。

  • データ例
1    96
210  116
433  166
705  139
922  27
1018 77
1182 85
1359 71
1521 165
1779 124
2002 74
2201 145
2427 47

まあでもこのデータはこのように解凍して使うことになった。
/***
  呼吸-LED1
  pwmを用いない → 赤/青LEDだけ用いる
  平均値の出し方を随時に変えてみたバージョン
  LEDは2色だけ
  b_led_re_re4_noheikin_redをpwm用いないように書き換えた 
  b_led_re_re4_noheikin_red1を参考にした(←LED1個verの)。
  b_led_re_re4_noheikin_red2の、pwmを[赤/青LED用いる]に変更
  b_led_re_re4_noheikin_red3に、how_to_38kHzの赤外線LEDを追加
  ***/
 
 
//sekibun
  int i = 0;
  int h[70] = { 0 };
  long sum = 0;
  int heikin1, heikin2;
  int now;
 
//maxx
  int maxx;
  int widthh[4] = { 8, 8, 8, 8 };
  char line1, line2;
  long t = 0;
  long time1, time2;
  int widadd = 8;
 
//Yellow_LED
  int ledPin3 = 11;   // LED connected to digital pin 11
//  int YPW1 = 1;
  int YPW2 = 4;
  int k1 = 0;
 
//Red_LED
  int ledPin2 = 12;   // LED connected to digital pin 12
  int RPW1 = 0;
  int RPW2 = 1;
//  int k2 = 0;
  int k3 = 0;
 
//Blue_LED
  int ledPin1 = 10;   // LED connected to digital pin 10
  int BPW1 = 0;
  int BPW2 = 1;
 
//赤外線LED
  int IRPin = 2;
  int pulsos[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
           1,1,1,1,1,1,1,1,1,1,1,1,1};
  int cont = 0;
  int cont2 = 0;
 
//赤外線受信モジュール
  int sekimoju;
 
//同期LED
  int ledPin4 = 9;
  int douki = 0;
 
 
//LEDその他
  int sokudo = 0;
/*  k1, k2, k3 について
 *  ** k1 **
 *    k1 = 0  // 上向きのベクトルのとき(温度上昇時)
 *    k1 = 1  // 下向きのベクトルのとき(温度下降時)
 *  ** k2 **
 *    k2 = 0  // 振幅が350(基準値)より小のとき
 *    k2 = 1  // 振幅が350(基準値)より大のとき
 *  ** k3 **
 *    k3 = 0  // 連続で出るYPW2=150の、150が最初に出たとき
 *    k3 = 1  // 2個目以降の150のとき
 */
 
void setup()
{
  Serial.begin(9600);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT); 
  pinMode(ledPin4, OUTPUT);
  pinMode(IRPin, OUTPUT);
}
 
void loop()
{
  sum = 0;
  heikin1 = heikin2;
  // ここで70幅分の平均値をずらしながら計算 // この辺省略
  for(i=69 ; i>=1 ; i--){
    h[i] = h[i-1];
    sum += h[i];
  }
  //h[0] = analogRead(0);
  sum += h[0];
  heikin2 = sum/70;
 
  t++;
  if(t >= 2470){
    t = 0;
  }
 
  if( t>=1    && t<=1+96    || t>=210  && t<=210+116  ||
      t>=433  && t<=433+166 || t>=705  && t<=705+139  ||
      t>=922  && t<=922+27  || t>=1018 && t<=1018+77  ||
      t>=1182 && t<=1182+85 || t>=1359 && t<=1359+71  ||
      t>=1521 && t<=1521+165|| t>=1779 && t<=1779+124 ||
      t>=2002 && t<=2002+74 || t>=2201 && t<=2201+145 ||
      t>=2427 && t<=2427+47 ){
    k1 = 1;
  }else{
    k1 = 0;
  }
  Serial.println(widthh[0]);
 
  //LED_Yellow and Red  
      if(k1 == 1){ // 下向きのベクトルのとき(温度下降時)
        if(YPW2 > 1){
            YPW2 = YPW2 - 2 ; // LEDだんだん暗く
        }
        if(YPW2 <= 1){
          YPW2 = 1;
        }
      }
      if(k1 == 0){ // 上向きのベクトルのとき(温度上昇時)
         if(YPW2 < 150){
           k3 = 0;
           YPW2 = YPW2 + 2; // LEDだんだん明るく
         }
         if(YPW2 >= 150){
           YPW2 = 150;
           if(k3 == 0){  //要はLEDがmaxのとき
               time1 = time2;
             time2 = t;
             widthh[0] = time2 - time1;      // 振幅
 
             if(widthh[0] >= 400){
                 // 振幅が増加するとき だんだん青に
               if(sokudo >= -4) sokudo++;
             }
             else if(widthh[0] <= 200){
                 // 振幅が減少するとき だんだん赤に
               if(sokudo <= 4)  sokudo--;
             }
             else if(widthh[0] > 200 && widthh[0] < 400){
                 // 振幅基準値
 
               if(sokudo >= 1)  sokudo--;
               if(sokudo <= -1) sokudo++;
             }
             k3 = 1;
           }
           //赤外線LED
           for(cont=0;cont<28;cont++){
            if(pulsos[cont]==1){
	      for(cont2=0;cont2<38;cont2++){ 
	        digitalWrite(IRPin,HIGH);
	        delayMicroseconds(13);
	        digitalWrite(IRPin, LOW);
	        delayMicroseconds(13);
	      } 
            }else{
	      digitalWrite(IRPin, LOW);
	      delay(1);
            }
          }
         }
      }
      analogWrite(ledPin3, YPW2);   // sets the LED on
 
//LED_Red and Blue
  if(sokudo <= 1 && sokudo >= -1){ // 振幅基準値 (LED黄色)
  // LED明るさ0に
    RPW1 = BPW1 = 0;
    RPW2 = BPW2 = 1;
  }
  if(sokudo == 2){ // 振幅が増加するとき だんだん青に
    RPW1 = 0;    RPW2 = 1;
    BPW1 = 1;    BPW2 = 10;
  }
  if(sokudo == 3){ // 振幅が増加するとき だんだん青に
    RPW1 = 0;    RPW2 = 1;
    BPW1 = 1;    BPW2 = 5;
  }
  if(sokudo == 4){ // 振幅が増加するとき だんだん青に
    RPW1 = 0;    RPW2 = 1;
    BPW1 = 2;    BPW2 = 4;
  }
  if(sokudo == 5){ // 振幅が増加するとき だんだん青に
    RPW1 = 0;    RPW2 = 1;
    BPW1 = 2;    BPW2 = 1;
  }
  //
  if(sokudo == -2){ // 振幅が増加するとき だんだん赤に
    RPW1 = 1;    RPW2 = 10;
    BPW1 = 0;    BPW2 = 1;
  }
  if(sokudo == -3){ // 振幅が増加するとき だんだん赤に
    RPW1 = 1;    RPW2 = 5;
    BPW1 = 0;    BPW2 = 1;
  }
  if(sokudo == -4){ // 振幅が増加するとき だんだん赤に
    RPW1 = 2;    RPW2 = 4;
    BPW1 = 0;    BPW2 = 1;
  }
  if(sokudo == -5){ // 振幅が増加するとき だんだん赤に
    RPW1 = 2;    RPW2 = 1;
    BPW1 = 0;    BPW2 = 1;
  }
  // Red LED
  digitalWrite(ledPin2, HIGH);   // sets the LED on Red
  delay(RPW1);
  digitalWrite(ledPin2, LOW);    // sets the LED off Red
  delay(RPW2);
  // Blue LED
  digitalWrite(ledPin1, HIGH);   // sets the LED on Blue
  delay(BPW1); 
  digitalWrite(ledPin1, LOW);    // sets the LED off Blue
  delay(BPW2);
 
  //* Down *//
  if(heikin1 > heikin2){
    if((line1 == 'U' && line2 == 'F') || 
       (line1 == 'F' && line2 == 'U') ||
       (line1 == 'U' && line2 == 'U')){
    line1 = line2;
    line2 = 'D';
 
    k1 = 1;
    }
 
    else if(line1 == 'F' && line2 == 'F'){
      line1 = line2;
      line2 = 'D';
 
      k1 = 1;
    }
    else{
      line1 = line2;
      line2 = 'F';
    }
  }
 
  //* Up *//
  else if(heikin1 < heikin2){
    if((line1 == 'D' && line2 == 'F') || 
       (line1 == 'F' && line2 == 'D') ||
       (line1 == 'D' && line2 == 'D') ||
       (line1 == 'F' && line2 == 'F')){
      line1 = line2;
      line2 = 'U';
 
      k1 = 0;
    }
    else{
      line1 = line2;
      line2 = 'F';
    }
  }
 
  //* Flat *//
  else {
    line1 = line2;
    line2 = 'F';
  }
 
  //* 赤外線受信モジュール *//
  sekimoju = analogRead(1);
 
  if(sekimoju <= 1 && k3 == 0){
    for(i=0 ; i<=10 || douki>=250 ; i++){
      douki = douki + 4;
      analogWrite(ledPin4, douki);
    }
  }else{
    douki = 0;
    analogWrite(ledPin4, douki);
  }
}
 




コメント
名前:
コメント:




today: -
yesterday: -
最終更新:2007年08月23日 23:24