2012-03-12 5 views
-1

私はArduinoにとって非常に新しいです。私はJavaとActionScript 3でもっと多くの経験を持っています。私はArduino UnoTAOS TSL235Rの光 - 周波数変換器の中から光度計を構築しています。Arduino Sketchベースの光度計の場合、「ループ」外の機能はオフ/発射されていません

私は別のセンサーを使用しているtuturialしか見つけることができないので、私はそれをすべて動作させるために必要なものを変換する方法を取り入れています(コピー&ペースト、恥ずかしながら、これは初めてです)。

3つの部分があります。これは、シリーズArduino and the Taos TSL230R Light Sensor: Getting Startedの最初のチュートリアルです。

写真変換:Arduino and the TSL230R: Photographic Conversions

最初に、私はTSL235Rセンサーで作成された周波数の値を返すことができましたが、写真変換のコードを追加しようとすると、返されるのはゼロになり、メインループ以外の機能は起動しません私のSerial.Println()は何も返されません。

私の数学が完璧である場合よりも、機能を発火させることにもっと関心があります。 ActionScriptとJavaには関数などのイベントリスナーがありますが、C/C++で起動する関数を宣言する必要はありますか?

基本的に、私のすべての機能がC言語で動作するようにするにはどうすればよいですか?

私のArduinoのSketch

// TSL230R Pin Definitions 
#define TSL_FREQ_PIN 2 

// Our pulse counter for our interrupt 
unsigned long pulse_cnt = 0; 

// How often to calculate frequency 
// 1000 ms = 1 second 
#define READ_TM 1000 

// Two variables used to track time 
unsigned long cur_tm = millis(); 
unsigned long pre_tm = cur_tm; 

// We'll need to access the amount of time passed 
unsigned int tm_diff = 0; 

unsigned long frequency; 
unsigned long freq; 
float lux; 
float Bv; 
float Sv; 
// Set our frequency multiplier to a default of 1 
// which maps to output frequency scaling of 100x. 
int freq_mult = 100; 

// We need to measure what to divide the frequency by: 
// 1x sensitivity = 10, 
// 10x sensitivity = 100, 
// 100x sensitivity = 1000 
int calc_sensitivity = 10; 


void setup() { 
    attachInterrupt(0, add_pulse, RISING); // Attach interrupt to pin2. 
    pinMode(TSL_FREQ_PIN, INPUT); //Send output pin to Arduino 
    Serial.begin(9600); //Start the serial connection with the copmuter. 
}//setup 


void loop(){ 
    // Check the value of the light sensor every READ_TM ms and 
    // calculate how much time has passed. 
    pre_tm = cur_tm; 
    cur_tm = millis(); 

    if(cur_tm > pre_tm) { 
     tm_diff += cur_tm - pre_tm; 
    } 
    else 
     if(cur_tm < pre_tm) { 
      // Handle overflow and rollover (Arduino 011) 
      tm_diff += (cur_tm + (34359737 - pre_tm)); 
     } 

    // If enough time has passed to do a new reading... 
    if (tm_diff >= READ_TM) { 
     // Reset the ms counter 
     tm_diff = 0; 

     // Get our current frequency reading 
     frequency = get_tsl_freq(); 

     // Calculate radiant energy 
     float uw_cm2 = calc_uwatt_cm2(frequency); 

     // Calculate illuminance 
     float lux = calc_lux_single(uw_cm2, 0.175); 
    } 
    Serial.println(freq); 
    delay(1000); 
} //Loop 


unsigned long get_tsl_freq() { 
    // We have to scale out the frequency -- 
    // Scaling on the TSL230R requires us to multiply by a factor 
    // to get actual frequency. 
    unsigned long freq = pulse_cnt * 100; 
    // Reset pulse counter 
    pulse_cnt = 0; 
    return(freq); 
    Serial.println("freq"); 
} //get_tsl_freq 


void add_pulse() { 
    // Increase pulse count 
    pulse_cnt++; 
    return; 
    Serial.println("Pulse"); 
}//pulse 


float calc_lux_single(float uw_cm2, float efficiency) { 
    // Calculate lux (lm/m^2), using standard formula 
    //  Xv = Xl * V(l) * Km 

    // where Xl is W/m^2 (calculate actual received uW/cm^2, extrapolate from sensor size 
    // to whole cm size, then convert uW to W), 
    // V(l) = efficiency function (provided via argument) and 
    // Km = constant, lm/W @ 555 nm = 683 (555 nm has efficiency function of nearly 1.0). 
    // 
    // Only a single wavelength is calculated - you'd better make sure that your 
    // source is of a single wavelength... Otherwise, you should be using 
    // calc_lux_gauss() for multiple wavelengths. 

    // Convert to w_m2 
    float w_m2 = (uw_cm2/(float) 1000000) * (float) 100; 
    // Calculate lux 
    float lux = w_m2 * efficiency * (float) 683; 
    return(lux); 
    Serial.println("Get lux"); 
} //lux_single 


float calc_uwatt_cm2(unsigned long freq) { 
    // Get uW observed - assume 640 nm wavelength. 
    // Note the divide-by factor of ten - 
    // maps to a sensitivity of 1x. 
    float uw_cm2 = (float) freq/(float) 10; 
    // Extrapolate into the entire cm2 area 
    uw_cm2 *= ((float) 1/(float) 0.0136); 
    return(uw_cm2); 
    Serial.println("Get uw_cm2"); 
} //calc_uwatt 


float calc_ev(float lux, int iso) { 
    // Calculate EV using the APEX method: 
    // 
    // Ev = Av + Tv = Bv + Sv 
    // 
    // We'll use the right-hand side for this operation: 
    // 
    // Bv = log2(B/NK) 
    // Sv = log2(NSx) 

    float Sv = log((float) 0.3 * (float) iso)/log(2); 

    float Bv = log(lux/((float) 0.3 * (float) 14))/log(2); 

    return(Bv + Sv); 
    Serial.println("get Bv+Sv"); 
} 


float calc_exp_tm (float ev, float aperture ) { 
    // Ev = Av + Tv = Bv + Sv 
    // need to determine Tv value, so Ev - Av = Tv 
    // Av = log2(Aperture^2) 
    // Tv = log2(1/T) = log2(T) = 2^(Ev - Av) 

    float exp_tm = ev - (log(pow(aperture, 2))/log(2)); 

    float exp_log = pow(2, exp_tm); 

    return(exp_log ); 
    Serial.println("get exp_log"); 
} 


unsigned int calc_exp_ms(float exp_tm) { 
    unsigned int cur_exp_tm = 0; 

    // Calculate mS of exposure, given a divisor exposure time. 

    if (exp_tm >= 2) { 
     // Deal with times less than or equal to half a second 

     if (exp_tm >= (float) int(exp_tm) + (float) 0.5) { 
      // Round up 
      exp_tm = int(exp_tm) + 1; 
     } 
     else { 
      // Round down 
      exp_tm = int(exp_tm); 
     } 
     cur_exp_tm = 1000/exp_tm; 
    } 
    else if(exp_tm >= 1) { 
     // Deal with times larger than 1/2 second 

     float disp_v = 1/exp_tm; 
     // Get first significant digit 
     disp_v  = int(disp_v * 10); 
     cur_exp_tm = (1000 * disp_v)/10; 
    } 
    else { 
     // Times larger than 1 second 
     int disp_v = int((float) 1/exp_tm); 
     cur_exp_tm = 1000 * disp_v; 
    } 
    return(cur_exp_tm); 
    Serial.println("get cur_exp_tm"); 
} 


float calc_exp_aperture(float ev, float exp_tm) { 
    float exp_apt = ev - (log((float) 1/exp_tm)/log(2)); 
    float apt_log = pow(2, exp_apt); 

    return(apt_log); 
    Serial.println("get apt_log"); 
} 

答えて

2

私が開始する必要が読むために多くのコードです。あなたのloop()あなたはグローバルfreqを隠しているローカルunsigned int freqを作成し、計算のために、値を返す、多分それは、ソースであることを利用しているfrequencyを割り当てるが、get_tsl_freq()freq

// get our current frequency reading 
    frequency = get_tsl_freq(); 
-- snip -- 
Serial.println(freq); 

を印刷するには

あなたのための混乱の。このコードではfrequencyfreqがグローバルになる理由はありません。この関数には到達不能なコードも含まれており、コントロールは関数をリターンのままにします。リターン後のステートメントは決して実行されません。

unsigned long get_tsl_freq() { 
    unsigned long freq = pulse_cnt * 100; <-- hides global variable freq 
    // re-set pulse counter 
    pulse_cnt = 0; 
    return(freq);   <-- () not needed 
    Serial.println("freq"); <-- Unreachable 
} 

もう少し読むと、C++の本を拾い読みして少しお読みください。あなたのコードは、それが技術的に有効なC + +ではないコンパイルしている間、あなたはいくつかのmanglingを行うArduinoソフトウェアと、宣言される前に関数を使用することを許可しないので、あなたの計算に使用する定数に

uw_cm2フロート

float w_m2 = (uw_cm2/1000000) * 100; 

あるので

float w_m2 = (uw_cm2/(float) 1000000) * (float) 100; 

float w_m2 = (uw_cm2/1000000.0f) * 100.0f; 

かさえ、このようなように書くことができます。また、取るように見えますどちらの方法も待っていると、計算するコードがあり、実行している場合にのみ実行されます最後に実行されてから1000ミリ秒以上経過していますが、同じコード内にdelay(1000)もありますが、これはまったく動作しない可能性があります。

+0

おかしくありません。これにより、はるかに明確になります。また、いくつかの理由でdidntの場合、スケッチは "このスコープで定義されていない"エラーをスローするので、私はいくつかの変数をグローバルにしました。私が読んでいたチュートリアルでローカルを維持していましたが、 –

+0

私はC++ 。私はC++の本を手に入れようとしていますが、私はこの小さな実験に取り組み、いくつか作ったときに進捗報告を投稿します。あなたの時間r_ahlskogに感謝します。他のアドバイスはいつでも歓迎します –

+0

@JosephAaronCampbellあなたはC++のバックグラウンドがあまりないので、言語の簡単な終わりではありません。私の答えで触れていないことがあります。あなたがStackoverflowを見れば、無料の読書リソースもあると思います。おそらくあなたが持っていた問題は、内側の範囲で変数を宣言して、その範囲外で使用しようとしました。私はいつも何らかの努力をした人々を助けるように努めます。 –

関連する問題