2016-06-07 10 views
0

NEC信号输出对于包含导致条带控制器我想和一个Arduino纳米更换IR遥控一个项目的Arduino定时编程。现在做一些研究(http://blog.allgaiershops.com/2012/05/10/reversing-an-rgb-led-remote/)和测量后,我发现,导致带钢控制器采用NEC协议。对电线

现在我试图创建一个程序上的IR_receiver测量,将模拟按钮按下的事件之一。但是,当测量数字引脚2(支持PWM)的输出时,时序不会接近所需的时间。

然而,如果我使用for循环写在主循环功能(高/低输出),可以建立一个高输出500US。

我在想,如果你能给我一些支持,以获取代码运行,或者你可以给我一些建议,如何以有效的方式处理在Arduino的时机。

/* 
Timer2_Counter_display_time_elapsed.ino 
Timer2 Counter Basic Example - Demonstrates use of my Timer2_Counter, which is a timer function with 0.5us precision, 
rather than 4us precision like the built-in Arduino micros() function has. 
By Gabriel Staples 
Visit my blog at http://electricrcaircraftguy.blogspot.com/ 
-My contact info is available by clicking the "Contact Me" tab at the top of my blog. 
-Please support my work & contributions by buying something here: https://sites.google.com/site/ercaguystore1/ 
My original post containing this code can be found here: http://electricrcaircraftguy.blogspot.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html 
Written: 17 May 2014 
Updated: 30 May 2014 
*/ 

//CODE DESCRIPTION: 
//This code demonstrates the use of my Timer2, which provides a more precise timer than micros(). 
//micros() has a precision of only 4us. However, Timer2 keeps track of time to a precision of 0.5us. 
//This is especially important in my code which reads an RC receiver PWM signal, which varies from 900~2100us. 
//Though this code demonstrates the use of the Timer_2 functions I have written, it does not adequately demonstrate the 
//real utility of the code, so I will state the following: 
//By using my Timer2 timer to measure the PWM high time interval on an RC receiver, in place of using micros(), I can get repeatable 
//pulse width reads with a fluctuation of ~1us, rather than having a read-in range fluctuating by as much as +/- 4~8 us when I use micros(). 
//This is an increase in precision of ~8x. 

//include the library 
#include <eRCaGuy_Timer2_Counter.h> 
#define pin_output 2 
#include <time.h> 

//Note: an object of this class was already pre-instantiated in the .cpp file of this library, so you can simply access its methods (functions) 
//  directly now through the object name "timer2" 
//eRCaGuy_Timer2_Counter timer2; //this is what the pre-instantiation line from the .cpp file looks like 

boolean on=false; 
int values[24][32]={0}; 
int one_output =1680; 
int zero_output= 560; 

void low_output(int); 
void high_output(int); 
void start_protocol(int); 
void end_protocol(int); 


void setup() { 
    //configure Timer2 
    timer2.setup(); //this MUST be done before the other Timer2_Counter functions work; Note: since this messes up PWM outputs on pins 3 & 11, as well as 
    //interferes with the tone() library (http://arduino.cc/en/reference/tone), you can always revert Timer2 back to normal by calling 
    //timer2.unsetup() 
    //values[0]={8,4,1,5,8,6}; 
    //prepare serial 
    Serial.begin(115200); 
    pinMode(pin_output, OUTPUT); 
    digitalWrite(pin_output, HIGH); 
    //Output a header of info: 
    /*Serial.println(F("Notes:")); 
    Serial.println(F("micros() has a precision of 4us")); 
    Serial.println(F("get_count() with unsigned long final data type has a final precision of 1us, and is fast")); 
    Serial.println(F("get_count() with float final data type has a final precision of 0.5us, and is not quite as fast")); 
    Serial.println(F("get_micros() has a precision of 0.5us, and is slower than the above 2 methods, so one of the above 2 methods is preferred")); 
    Serial.println(F("=============================================="));*/ 
} 


void loop() { 
    //declare local variables 
    delay(2000); 
    start_protocol(); 
    low_output(8); 
    high_output(4); 
    low_output(1); 
    high_output(5); 
    low_output(8); 
    high_output(6); 
    end_protocol(); 
    static unsigned long t_start = timer2.get_count(); 
    // unsigned long t_micros = micros(); 
    unsigned long t_T2_count = timer2.get_count(); 
    //float t_T2_micros = timer2.get_micros(); 
    if ((t_T2_count - t_start)/2 >= 2000003) 
    { 
     digitalWrite(pin_output, HIGH); 
    } 
} //end of loop() 


void low_output(int xtimes) 
{ 
    for (int i =0 ; i<xtimes ; i++){ 
     static unsigned long t_start = timer2.get_count(); //units of 0.5us; the count accumulated by Timer2_Counter 

     //acquire time stamps 

     unsigned long t_T2_count = timer2.get_count(); //units of 0.5us; the count accumulated by Timer2_Counter 

     //See if 1.000003 seconds has elapsed. If so, print out the time stamps. Note: I am using this elapsed time because I want it to NOT be divisible by 4, so that 
     //you can hopefully see the extra precision provided by the Timer2_Counter library, which the default Arduino micros() function does not have 
     if ((t_T2_count - t_start)/2 >= zero_output)//1000003) //if 1.000003 seconds has elapsed 
     { 
      t_start = t_T2_count; //update start time 
      if(on==false) { 
       digitalWrite(pin_output, LOW); 
       on=true; 
      }else { 
       digitalWrite(pin_output, HIGH); 
       on=false; 
      } 

     } 
    } 
    return; 
} 


void high_output(int xtimes) 
{ 
    for (int i =0 ; i<xtimes ; i++){ 
     static unsigned long t_start = timer2.get_count(); 

     //acquire time stamps 

     unsigned long t_T2_count = timer2.get_count(); 


     if ((t_T2_count - t_start)/2 >= one_output) 
     { 
      t_start = t_T2_count; //update start time 
      if(on==false) { 
       digitalWrite(pin_output, LOW); 
       on=true; 
      }else { 
       digitalWrite(pin_output, HIGH); 
       on=false; 
      } 

     } 
    } 
    return; 
} 


void start_protocol(){ 

    static unsigned long t_start = timer2.get_count(); 
    unsigned long t_T2_count = timer2.get_count(); 
    digitalWrite(pin_output, LOW);  


    t_start = timer2.get_count(); 
    t_T2_count = timer2.get_count(); 
    if ((t_T2_count - t_start)/2 >= 9000) 
    { 
     digitalWrite(pin_output, HIGH); 
    } 

} 


void end_protocol(){ 

    static unsigned long t_start = timer2.get_count(); 
    unsigned long t_T2_count = timer2.get_count(); 
    if ((t_T2_count - t_start)/2 >= zero_output) 
    { 
     digitalWrite(pin_output, LOW); 
    } 

    t_start = timer2.get_count(); 
    t_T2_count = timer2.get_count(); 
    if ((t_T2_count - t_start)/2 >= 40000) 
     digitalWrite(pin_output, HIGH); 

    t_start = timer2.get_count(); 
    t_T2_count = timer2.get_count(); 
    if ((t_T2_count - t_start)/2 >= 9000) 
    { 
     digitalWrite(pin_output, LOW); 
    } 
    t_start = timer2.get_count(); 
    t_T2_count = timer2.get_count(); 
    if ((t_T2_count - t_start)/2 >= 2100) 
    { 
     digitalWrite(pin_output, HIGH); 
    } 
    t_start = timer2.get_count(); 
    t_T2_count = timer2.get_count(); 
    if ((t_T2_count - t_start)/2 >= zero_output) 
    { 
     digitalWrite(pin_output, LOW); 
    } 
    digitalWrite(pin_output, HIGH); 
} 

为此,我使用了Gabriel Staples制作的时间库。

[更新] 按照@Gmodjackass的提示,以下代码在引脚2的输出上得到了NEC信号。注意:可以通过添加对直接引脚端口操作的支持来优化代码。

#define pin_output 2 
#include <time.h> 

boolean on=false; 
int values[24][32]={0}; 
int one_output =1680; 
int zero_output= 560; 
int sb=-1; 
void low_output(int); 
void high_output(int); 
void start_protocol(); 
void end_protocol(); 
void selection_protocol(String); 
void setup() { 

    Serial.begin(115200); 
    pinMode(pin_output, OUTPUT); 
    digitalWrite(pin_output, HIGH); 
    Serial.print("user_inpu: on(1)/off(0)"); 
    delayMicroseconds(400); 
} 

void loop() { 
    //declare local variables 
    if (Serial.available()) 
    { 

     char sb = Serial.read(); 
     Serial.print(sb); 
     switch (sb){ 
     case '0': 
      selection_protocol("off"); 
      break; 
     case '1': 
      selection_protocol("on"); 
      break; 

     } 
     sb=-1; 
    } 
} //end of loop() 

void low_output(int xtimes) 
{ 
    for (int i =0 ; i<xtimes*2 ; i++){   
     if(on==false) { 
      digitalWrite(pin_output, LOW); 
      on=true; 
     }else { 
      digitalWrite(pin_output, HIGH); 
      on=false; 
     } 
     delayMicroseconds(zero_output); 
     //} 
    } 
    return; 
} 
void high_output(int xtimes) 
{ 
    for (int i =0 ; i<xtimes*2 ; i++){  
     if(on==false) { 
      digitalWrite(pin_output, LOW); 
      on=true; 
      delayMicroseconds(zero_output); 
     }else { 
      digitalWrite(pin_output, HIGH); 
      on=false; 
      delayMicroseconds(one_output); 
     } 
     //} 
    } 
    return; 
} 
void start_protocol(){ 
    digitalWrite(pin_output, LOW);  
    delayMicroseconds(9000); 
    digitalWrite(pin_output, HIGH); 
    delayMicroseconds(4400); 


    return; 
} 
void end_protocol(){ 

    digitalWrite(pin_output, LOW); 
    delayMicroseconds(zero_output);   
    digitalWrite(pin_output, HIGH); 
    delay(40);   
    digitalWrite(pin_output, LOW); 
    delayMicroseconds(9000);  
    digitalWrite(pin_output, HIGH); 
    delayMicroseconds(2100);  
    digitalWrite(pin_output, LOW); 
    delayMicroseconds(zero_output); 
    digitalWrite(pin_output, HIGH); 
    return; 
} 
void selection_protocol(String user_input){ 

    if(user_input == "on"){ 
     Serial.print("on selected"); 
     start_protocol(); 
     low_output(8); 
     high_output(4); 
     low_output(1); 
     high_output(5); 
     low_output(8); 
     high_output(6); 
     end_protocol(); 
    } 
    if(user_input == "off"){ 
     Serial.print("off selected"); 
     start_protocol(); 
     low_output(8); 
     high_output(4); 
     low_output(1); 
     high_output(3); 
     low_output(1); 
     high_output(1); 
     low_output(6); 
     high_output(1); 
     low_output(1); 
     high_output(6); 
     end_protocol(); 

    } 
    return; 
} 

回答

0

一些你的时间不符,可以通过Arduino的的digitalWrite的很慢的性质造成的,也许考虑使用direct port manipulation。也可以考虑使用此delay function替代,因为它可能会导致更多的你的时间的问题。

(编辑拼写错误)

+0

感谢您的提示:),我会检查它,如果结果是工作更新代码。 – Fernand

+0

@Jonathan Leffler感谢您的编辑 – Fernand