Operácie

Jednoduchý prijímač diaľkového IR ovládania

Zo stránky SensorWiki

Záverečný projekt predmetu MIPS / LS2024 - Meno Priezvisko


Zadanie

Zostrojte a naprogramujte ovladanie škrtiacej klapky pomocou plynového pedálu.



Vývojová doska Arduino UNO R3

Literatúra:


Analýza a opis riešenia

Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami...

RGB LED.

Nezabudnite doplniť schému zapojenia!

Schéma zapojenia LCD displeja.


Algoritmus a program

Celý kód je napísaný v jednom .c súbore – na spustenie treba 2 externé knižnice.


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include "uart.h"

// #define F_CPU 16000000UL
// #define BAUD 9600

// Define button codes (example values, replace with actual values from your remote)
#define RED_BUTTON 0xFFA25D
#define GREEN_BUTTON 0xFF629D
#define BLUE_BUTTON 0xFFE21D
#define OFF_BUTTON 0xFF22DD
#define IRLED PD2

#define toggleBIT(reg, bit) ((reg) ^=  (1 << (bit))) //PREPNUTIE STAVU
#define setBIT(reg, bit) ((reg) |= (1 << (bit))) //JEDNA    
#define clearBIT(reg, bit) ((reg) &= ~(1 << (bit))) //NULAs

volatile uint32_t ir_code = 0;
volatile uint8_t bit_count = 0;

void initIRReceiver(void);
void initRGBLED(void);
void setColor(uint8_t red, uint8_t green, uint8_t blue);
void handleIRCode(uint32_t code);

FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);


ISR(INT0_vect) {
    // Simple state machine to decode the IR signal
    static uint8_t last_edge = 0;
    uint8_t edge = (PIND & (1 << PIND2)) >> PIND2;
    uint16_t duration = TCNT1;
    TCNT1 = 0;

    if (edge == last_edge) return;
    last_edge = edge;

    if (duration > 10000) { // Header
        ir_code = 0;
        bit_count = 0;
    } else if (duration > 0 && duration < 100) { // Logical 0
        ir_code = 0xFFA25D ;
        bit_count++;
    } else if (duration > 100 && duration < 200) { // Logical 1
        ir_code = 0xFF629D;
        bit_count++;
    }
	else if (duration > 200 && duration < 300) { // Logical 1
        ir_code = 0xFFE21D;
        bit_count++;
    }

    if (bit_count >= 32) {
        handleIRCode(ir_code);
		printf("IR Code: %08lX\n",ir_code);
        ir_code = 0;
        bit_count = 0;
    }
}

void initIRReceiver(void) {
	clearBIT(PORTD,IRLED); 
	clearBIT(DDRD,IRLED);
	
	EICRA |= (1 << ISC00); // Any logical change on INT0 triggers interrupt
    EIMSK |= (1 << INT0);  // Enable external interrupt INT0

    // Timer1 initialization
    TCCR1B |= (1 << CS11); // Prescaler 8
    TCNT1 = 0;             // Initialize counter
}

void initRGBLED(void) {
    // Set PB1, PB2, and PB3 as output (PWM)
    DDRB |= (1 << PB1) | (1 << PB2) | (1 << PB3);

    // Setup Timer1 for Fast PWM mode on PB1 and PB2
    TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
    TCCR1B |= (1 << WGM12) | (1 << WGM13);
    ICR1 = 255; // TOP value for 8-bit PWM

    // Setup Timer2 for Fast PWM mode on PB3
    TCCR2A |= (1 << COM2A1) | (1 << WGM20) | (1 << WGM21);
    TCCR2B |= (1 << CS21); // Prescaler 8
}

void setColor(uint8_t red, uint8_t green, uint8_t blue) {
    OCR1A = red;  // Set PWM value for PB1 (Red)
    OCR1B = green; // Set PWM value for PB2 (Green)
    OCR2A = blue;  // Set PWM value for PB3 (Blue)
}

void handleIRCode(uint32_t code) {
    switch(code) {
        case RED_BUTTON:
            printf("Red Button Pressed\n");
            setColor(255, 0, 0); // Red
            break;
        case GREEN_BUTTON:
            printf("Green Button Pressed\n");
            setColor(0, 255, 0); // Green
            break;
        case BLUE_BUTTON:
            printf("Blue Button Pressed\n");
            setColor(0, 0, 255); // Blue
            break;
        case OFF_BUTTON:
            printf("Off Button Pressed\n");
            setColor(0, 0, 0); // Off
            break;
        default:
            printf("Unknown Button Pressed\n");
            break;
    }
}

int main(void) {
    uart_init();
	stdout = &mystdout;
	
    initIRReceiver();
    initRGBLED();
	
    printf("System Initialized\n");
	
	sei(); //globalne interupty
	
    while (1) 
	{
		printf("IR Code: %08lX\r",ir_code);
        
    }
}
/* ************************************************************************* */
/* FileName:             uart.c                                              */
/* ************************************************************************* */

#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"


void uart_init( void ) 
{
//  for different BAUD rate change the project settings, or uncomment 
//  following two lines:	
//	#undef  BAUD           // avoid compiler warning
	
   #include <util/setbaud.h>  // requires defined BAUD
   
   UBRR0H = UBRRH_VALUE;
   UBRR0L = UBRRL_VALUE;
   #if USE_2X                 // defined in setbaud.h 
    UCSR0A |= (1 << U2X0);
   #else
    UCSR0A &= ~(1 << U2X0);
   #endif


    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
    UCSR0B = _BV(RXEN0) | _BV(TXEN0);   /* Enable RX and TX */	
}


int uart_putc( char c, FILE *stream )
{
   if (c == '\n') 
      uart_putc('\r',stream);
   
   loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
   UDR0 = c;
   return 0;
}


void uart_puts(const char *s, FILE *stream)
{
	while(*s)
	{
		uart_putc(*s++, stream);
	}
}

char uart_getc(void) 
{
    loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
    return UDR0;
}

void delay(int delay)      // vlastna funkcia pre dlhsie casy 
{
  for (int i=1; i<=delay; i++)
  _delay_ms(1);
}
/* ************************************************************************* */
/* FileName:             uart.h                                              */
/* ************************************************************************* */

#define LED PB5  // internal on-board LED 

 /* na testovanie su uz zadefinovane */
 // bit_is_set(PINB, SW1)
 // bit_is_clear(PINB, SW1)

 /* na cakanie su preddefinovane slucky */
 // loop_until_bit_is_set(PINB, SW1);    // cakanie na uvolnenie tlacitka
 // loop_until_bit_is_clear(PINB, SW1);  // cakanie na stlacenie tlacitka


#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))

#ifndef UART_H_
#define UART_H_

#include <stdio.h>

#define BAUD_PRESCALE  103  // vzor?ek z datasheetu

void hw_init( void );
void uart_init( void );
     
/* Following definition is compatible with STDIO.H, for more
 * information see https://www.appelsiini.net/2011/simple-usart-with-avr-libc/
 */
	 
int uart_putc( char c, FILE *stream );
void uart_puts( const char *s, FILE *stream);

char uart_getc( void );

void delay(int delay); 

#endif /* UART_H_ */

Zdrojový kód: zdrojaky.zip

Overenie

Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.

Aplikácia.

Video:

Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.