Помогите в совместимости библиотек irremote и tlc5940

Jacks_d
Offline
Зарегистрирован: 31.12.2011

Суть в чем при инициализации обоих библиотек ардуина ни на что не реагирует, проблема в использовании одного второго таймера, это и подтвердило гугление и аналогичные проблемы с использованием tone.

Использовал два вида библиотек для пульта: IRremote и судя по всему ее развитее ArduinoIRremotemaster ничего не поменялось

Вот ссылка на tlc5940 https://code.google.com/p/tlc5940arduino/

http://forum.arduino.cc/index.php?PHPSESSID=iq8derdpru672cnc065sici4m7&topic=61412.0 по этой ссылке было обсуждение этой проблемы но я так и не понял что точно нужно менять и будит ли это работать на 328/168 камне

вот мой код который

#include <IRremote.h>
#include "Tlc5940.h"
int l[16];
int v[16];
byte inserial[37];
boolean inserialAP = 0;
int delayled = 3;
long time;
int t = 0;
long DU;
int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()  
{
Serial.begin(57600);
irrecv.enableIRIn();
Tlc.init();
}
void dump(decode_results *results) {
  int count = results->rawlen;}
void loop() 
{
 if(irrecv.decode(&results)) 
   {
    if(results.vue != 4294967295)
      {DU=results.vue;Serial.print(DU, HEX);}
    if(results.vue == 4294967295)
      {Serial.print(DU, HEX);}
    dump(&results);
    irrecv.resume(); // Receive the next vue
  }
  
 if(Serial.available() > 37) // если с СОМ пришло больше + символов стираем буфер
   {while(Serial.available()) Serial.read(); }
 if(Serial.available() == 37)// если буфер СОМ = 37 то пишем в массив
   {for(int i=0; i < 37; i++) 
       {inserial[i] = Serial.read() - 48;} 
    while(Serial.available()) Serial.read();
    time=millis();
    }

if(inserial[0]==1 && inserial[1]==1 && inserial[2]==1 && inserial[3]==1)
  {for(int b=0; b < 16; b++) 
      {v[b] = map(( inserial[((b*2)+4)] * 10 + inserial[((b*2)+5)]), 0, 63, 0, 4095);
       }
       
   }    
if(inserial[36]==1)
  {for(byte i=0; i<16; i++)
      {if(v[i]>l[i]){l[i]++; Tlc.set(i, l[i]);}
       if(v[i]<l[i]){l[i]--; Tlc.set(i, l[i]);}
       }
   }
Tlc.update(); 
delayMicroseconds(500);       
   

if(v[0]==l[0]&&v[1]==l[1]&&v[2]==l[2]&&v[3]==l[3]&&v[4]==l[4]&&v[5]==l[5]&&v[6]==l[6]&&v[7]==l[7]&&
   v[8]==l[8]&&v[9]==l[9]&&v[10]==l[10]&&v[11]==l[11]&&v[12]==l[12]&&v[13]==l[13]&&v[14]==l[14]&&
   v[15]==l[15]&&inserial[36]==1)
  {inserial[36]=0;
   for(byte c=0; c<16; c++)
      {Serial.print(l[c]/64);if(c==15){inserial[0]=0;inserial[1]=0;inserial[2]=0;inserial[3]=0;
       Serial.println();Serial.print("TimeSet ");Serial.println(millis()-time);}
       }
   }
} 

В общем помогите одну из них перевести на другой таймер т.к. в програмировании только на уровне Ардуино(

maksim
Offline
Зарегистрирован: 12.02.2012
Jacks_d
Offline
Зарегистрирован: 31.12.2011

Хм... TLC заработала, спасибо за подсказку видно плохо искал. А вот с ИК приемником судя по всему никак на одной нане т.к. посмотрел библиотеку tlc5940 она использует 9ый пин с первым таймером, и вот что увидел:

 tlc5940.h:

#ifdef TLC_ATMEGA_8_H

/** Enables the Timer1 Overflow interrupt, which will fire after an XLAT
    pulse */
#define set_XLAT_interrupt()    TIFR |= _BV(TOV1); TIMSK = _BV(TOIE1)
/** Disables any Timer1 interrupts */
#define clear_XLAT_interrupt()  TIMSK = 0

#else

/** Enables the Timer1 Overflow interrupt, which will fire after an XLAT
    pulse */
#define set_XLAT_interrupt()    TIFR1 |= _BV(TOV1); TIMSK1 = _BV(TOIE1)
/** Disables any Timer1 interrupts */
#define clear_XLAT_interrupt()  TIMSK1 = 0

#endif

/** Enables the output of XLAT pulses */
#define enable_XLAT_pulses()    TCCR1A = _BV(COM1A1) | _BV(COM1B1)
/** Disables the output of XLAT pulses */
#define disable_XLAT_pulses()   TCCR1A = _BV(COM1B1)

extern volatile uint8_t tlc_needXLAT;
extern volatile void (*tlc_onUpdateFinished)(void);
extern uint8_t tlc_GSData[NUM_TLCS * 24];

 tlc5940.cpp

/* Timer Setup */

    /* Timer 1 - BLANK / XLAT */
    TCCR1A = _BV(COM1B1);  // non inverting, output on OC1B, BLANK
    TCCR1B = _BV(WGM13);   // Phase/freq correct PWM, ICR1 top
    OCR1A = 1;             // duty factor on OC1A, XLAT is inside BLANK
    OCR1B = 2;             // duty factor on BLANK (larger than OCR1A (XLAT))
    ICR1 = TLC_PWM_PERIOD; // see tlc_config.h

ATmega_8.h

/** OC1A (Arduino digital pin 9) -> XLAT (TLC pin 24) */
#define XLAT_PIN     PB1
#define XLAT_PORT    PORTB
#define XLAT_DDR     DDRB

Я конечно уже смирился с тем что прийдется использовать еще адин МК для TLC и есть плюс что можно использовать на том что с ИК приемником функцию Tone для будильника, но может есть вариант что-то переделать?

 

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Возникла подобная проблема, как я понимаю химичить таймеры ниачом, никак тут от этой проблемы не уйти. Решено методом Serial over IR (Tx через 2И-НЕ с генератором в светодиод, скорость не более 2400): http://forum.arduino.cc/index.php?topic=10555.0

Вместо стандартной логики 2И-НЕ и генерации несущей с таймера, можно использовать вход Reset у 555. Номиналы 555 - зарядный резистор (от плюса к 7 выводу) - 1k, разрядный (от 7 к 2, 6) - 10k, конденсатор 1800 пФ керамика. Как раз примерно 38 кГц генерит, плюс модулировать от ардуины удобно. Правда внешний таймер дополнительно кушает 20 мА, мож для кого-то сие важно.

Связь только half-duplex, или как-то придумывайте защиту от отражений ИК-сигнала.