对于基于 Arduino Sketch 的测光表,'loop'之外的功能不会触发/触发
For an Arduino Sketch based light meter, functions outside of 'loop' are not being set off/firing
我对Arduino很陌生。我对Java和ActionScript3有更多的经验。我正在用Arduino Uno和TAOS TSL235R光频转换器建造一个测光表。
我只能用不同的传感器找到一个图图里亚尔,所以我正在努力转换我需要的东西,让它全部工作(也就是一些复制和粘贴,可耻的是,但我是新手)。
有三个部分:这是Arduino和Taos TSL230R光传感器系列的第一个教程:入门。
摄影转换:Arduino和TSL230R:摄影转换。
起初,我可以返回TSL235R传感器创建的频率值,但一旦我尝试添加用于摄影转换的代码,我只返回了零,主循环之外的任何功能似乎都没有启动,因为我的Serial.Println()
没有返回任何东西。
比起我的数学是否完美,我更关心的是激发函数在ActionScript和Java中,有函数的事件侦听器等等,我是否需要声明函数以使其在C/C++中激发?
基本上,我如何确保我的所有函数都使用C编程语言?
我的Arduino素描:
// 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");
}
要读的代码太多了,我应该从哪里开始。
在您的loop()
中,您正在分配frequency
,但正在打印freq
// get our current frequency reading
frequency = get_tsl_freq();
-- snip --
Serial.println(freq);
在get_tsl_freq()
中,您正在创建一个隐藏全局freq
的本地unsigned int freq
,并将其用于计算和返回值,这可能也是您感到困惑的原因。在这段代码中,我看不出frequency
和freq
是全局变量的原因。函数还包含不可访问的代码,控件将在返回时离开函数,返回后的语句将永远不会执行。
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++,但由于Arduino软件会进行一些篡改,以及在函数声明之前不允许使用什么,你可以逃脱惩罚。
关于你在计算中使用的常数
float w_m2 = (uw_cm2 / (float) 1000000) * (float) 100;
可以写成
float w_m2 = (uw_cm2 / 1000000.0f) * 100.0f;
甚至像这样,因为CCD_ 10是一个浮动
float w_m2 = (uw_cm2 / 1000000) * 100;
您似乎也采取了这两种方法来等待,您有计算代码,并且只有在自上次运行以来超过1000毫秒时才运行,但在同一代码中也有delay(1000)
,这可能根本无法按预期工作。
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法删除指针,已触发断点
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 当再次触发信号时,从Qt插槽执行的功能被第二次调用时会发生什么?
- Winapi -Tounicode功能会触发访问
- 通过模板构造函数(std ::功能和迷你案例)将构造函数触发
- 如何传递用于SQLite中触发功能的变量
- 如何设置通知功能,以便在创建QWidget派生对象时触发
- QMainWindow菜单栏:OpenGL触发的功能导致GL上下文问题
- 为什么我的连接没有触发信号功能
- 对于基于 Arduino Sketch 的测光表,'loop'之外的功能不会触发/触发