使用光电门和红板来计算摆的周期

时间:2019-05-19 21:14:51

标签: c++

我对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

2 个答案:

答案 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;