2016-06-07 2 views
0

Для проекта, содержащего контроллер светодиодной полосы, я хочу заменить ИК-пульт на Arduino nano. Теперь после ряда исследований (http://blog.allgaiershops.com/2012/05/10/reversing-an-rgb-led-remote/) и измерений я обнаружил, что контроллер светодиодной полосы использует протокол NEC.Программирование временного времени Arduino для вывода сигнала 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); 
} 

Для этого в этом коде я использовал библиотеку времени, разработанную Габриэлем Стейплсом.

[обновить] После того, как вы указали советы @Gmodjackass, следующий код получил сигнал NEC на выходе штыря 2. Примечание: код можно оптимизировать, добавив поддержку для прямого манипулирования портами.

#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

Некоторые из ваших расхождений синхронизации может быть вызван очень медленной природой digitalWrite Arduino, в возможно посмотреть в использовании direct port manipulation. Также подумайте об использовании этого delay function, так как это может вызвать некоторые из ваших проблем с синхронизацией.

(отредактированы орфографические ошибки)

+0

спасибо за советы :), я буду проверять его и обновить код, если результат работает. – Fernand

+0

@Jonathan Leffler Редактировать – Fernand