August 23, 2010
by bullfrog_69r
|
I am currently working on a project to recieve and eventually transmit the signal from my tv remote control. So far I have managed to recieve the signal and acertain the rough time between pulses (using a while loop and a simple counter) but i need to be more accurate to re-transmit the signal. At the moment i cant seem to get thhe timer working to get this time.
Also i was after some help with setting up the PWM in order to use it to send the base 38kHz signal used by the remote.
Any help would be appreciated!
//PIN configuration
//PC0 (PCINT8) - Buffered Infra Red Receiver (Vout)
//PC3 - test LED
//PC4 - test LED
//PC5 - IR LED
uint8_t dataSize = 36;
volatile uint16_t data[36];
uint8_t started;
uint8_t count;
uint8_t sampled = 0;
uint8_t done = 0;
ISR(PCINT1_vect){
PORTC |= (1<<PC3);
//if we have not started, check for start bit on DATA line
if(!started){
if (PC0 == 0 ){
started = 1;
int i;
//clear data
for(i = 0; i< dataSize;i++){
data[i] = 0;
}
return;
}
}
else if(count < 36) {
//if pin is low is start of pulse, record last timed time
if(PC0 == 0){
data[count] = TCNT1;
}
//else the pin is high and restart timer
else if(PC2 == 1){
TCNT1 = 0x0000;
}
count++;
return;
}
else if(count == 36){ //pairty bit
//not implemented
count++;
PORTC &= ~(1<<PC3);
done = 1;
return;
}
else{ //stop bit
//should check to make sure DATA line is high, what to do if not?
started = 0;
PORTC &= ~(1<<PC3);
done = 1;
}
}
void realtimeclock_setup(){
// setup Timer1:
TCCR1A |= (1<<WGM11);
// clocked from CLK/1024
// which is 14745600/1024, or 14400 increments per second
TCCR1B |= (1<<CS10);
}
int main(){
//initialise everything
realtimeclock_setup();
PCICR |= (1<<PCIE1);
PCMSK1 |= (1<<PCINT8);
sei();
lcd_init();
// LED as output
DDRC |= (1<<PC5);
// LED as output
DDRC |= (1<<PC4);
// LED as output
DDRC |= (1<<PC3);
// set PC0 as input
DDRC &= ~(1<<PC0);
// turn on internal pull up resistor for PA0
PORTC |= (1<<PC0);
// start up the serial port
uart_init();
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
stdin = stdout = &uart_stream;
//Print searching to LCD
while(done == 0){
lcd_clear_and_home();
lcd_write_string(PSTR("Searching***"));
lcd_line_two();
delay_ms(3000);
}
//print data to serial port
int j;
for(j = 0; j<36; j++){
printf_P(PSTR("%d,"), data[j]);
}
printf_P(PSTR("\r\n\n"));
PORTC &= ~(1<<PC3);
PORTC |= (1<<PC4);
return 0;
}
|
August 26, 2010
by bretm
|
In a number of places you have code like
if(PC0 == 0){
and it seems like you're trying to read pin states that way. The values PC0, PC2, etc., are constants. PC0 will always equal 0 and PC2 will always equal 2, at least on the Nerdkits chip. What you need to do to read the state of PC2, for example to tell if it's low, is
if ((PINC & (1<<PC2)) == 0) {
You should declare the "done" variable as volatile since it's modified by the interrupt routine. Otherwise the compiler could optimize your "while(done==0)" loop into a "while(1)" loop and then omit the rest of your main routine since it's no longer reachable. |