我对C ++还是很陌生,但认为使用我学校随身携带的SparkFun套件和Photogate会很酷。我最终尝试计算使用光电门创建的摆的周期。 我将数字原型板连接到Redboard,然后连接到Photogate。我在Vernier Photogate教程页面中找到的以下代码用于Arduino IDE。尽管此代码有效,但它仅输出光闸被阻止的时间。
因此,从本质上讲,我需要跟踪钟摆首先阻塞光闸,然后再次向左移动的时间,最后只是最后一次闸门回到中心时所花费的时间。 因此,我相信我需要一段代码捕获第一个时间戳,一段代码等待直到发生第二个阻塞事件,然后捕获第二个时间戳并最终收集差异?我似乎无法解决这个问题,甚至无法开始理解如何编写代码。我希望这个论坛可以对该项目提供一些见识。
/* VernierTutorialPhotogate (v2018)
* This sketch will send a status message to the Serial
* Monitor on whether the Photogate is blocked or unblocked.
* It lists the time that the photogate is blocked in microseconds since the program started running or
* since the last time the counter overflowed.
* It will also turn on the LED (pin D13) when the
* photogate is blocked.
*
* Plug the Photogate into the Digital 1 port on the
* Vernier Arduino Interface Shield or into a Digital Protoboard
* Adapter wired to Arduino pins 2, 3, 4, and 5.
*/
int photogatePin = 2; //create global variable for pin assignment to sensor
int LEDpin = 13; //create global variable for pin assignment to LED
int photogateStatus; //create global variable for photogate status: LOW=blocked, HIGH=unblocked
int oldStatus = HIGH;
unsigned long timeus = 0; //Time in us
void setup()
{
Serial.begin(9600); // set up Serial library at 9600 bps
pinMode(LEDpin, OUTPUT);
Serial.println("Vernier Format 2");
Serial.println("Photogate blocked times taken using Ardunio");
Serial.print("Time");
Serial.print("us");
};// end of setup
void loop ()
{
photogateStatus = digitalRead(photogatePin);//low when blocked
if (photogateStatus == LOW)
{
digitalWrite(LEDpin, HIGH);// turn on LED
if (oldStatus == HIGH)
{
timeus = micros();
Serial.println(timeus);
}
}
else digitalWrite(LEDpin, LOW);// turn off LED
oldStatus = photogateStatus;
} ;// end of loop
答案 0 :(得分:0)
假设您应该使用micros()的减法来计算周期,因为micros()包含从程序运行开始的时间 注意将光电门放置在哪里,如果放置在垂直中间线,则只要钟摆开始运行,只需从第一块到第二块的时间加倍即可
答案 1 :(得分:0)
总有一天,我将不得不拿一块Arduino板来看看它是如何工作的。我主要使用纯C / C ++的MSP430。我不会像这样长时间地把处理器束缚起来,我想对于Arduino也可以说同样的话。
我会有一个主循环来处理事件的发生,例如中断。
是的,您只是想尝试一个简单的示例,因此您的方法很好。真是令人深思。
for(;;)
{
if(state & STATE_TRIGGER)
; //do something
//or
switch( state & STATE_MASK)
{
case STATE_EVENT_A:
//do something
break;
}
}
这里,我假设从某个主循环调用了“ loop()”。
void loop ()
{
int cnt - 0;
int timer;
for( ; !digitalRead(photogatePin); )//wait for the next low
;
for( ; digitalRead(photogatePin); )//then wait for the next high
;
timer = micros();//here I assume this is a system free running timer.
//will look for two events as the sensor may not be symmetrically positioned.
for( ; !digitalRead(photogatePin); )//wait for the next low
;
for( ; digitalRead(photogatePin); )//then wait for the next high
;
for( ; !digitalRead(photogatePin); )//wait for the next low
;
for( ; digitalRead(photogatePin); )//then wait for the next high
;
int accual = micros() - timer; //another assumption as the 'micro()' could have rolled over.
Serial.println(accual);
}
更新
您最终可能如何编程此程序.....
我要做的就是设置一个计时器以启动拍照事件。并确保它比钟摆摆动的时间更长。这将作为外围设备设置而不是主循环的一部分发生。关闭触发器,并为下一个照片事件设置中断。
在该中断中,为主循环设置一个状态标志,例如:
state |= STATE_FIRST_HALF;
在该主循环中
case STATE_FIRST_HALF:
state &= ~STATE_FIRST_HALF;
//and set the timer to stop on the next event.
//set event to cause an interrupt.
break;
在第二个中断处理程序中,您将:
state |= STATE_DONE;
global_time = timer.get_count()
//or however you get the timer data to global_time
然后:
case STATE_DONE:
state &= ~STATE_DONE
//output global_time to uart
break;