Remote
decoder model number and carrier frequency. The carrier frequency for
an infrared (IR) decoder is the frequency used to modulate IR pulses.
The most common carrier frequency for consumer IR devices is 38 kHz,
but other frequencies are sometimes used, such as 40 kHz, 56 kHz, 36
kHz, or 39.2 kHz.
An
optical 1 results in a 0 at the output of the receiver. Another
datasheet shows more information about a similar part - Part number of
the IR receiver: GP1UW70QS,Link to the datasheet.
Receiving wavelength. What wavelength of light(nm) is the remote control decoder most sensitive to?
IR decoder board connections.
IR LED specs:
Emmsion spectrum. Datasheet can be foundhere. What is the peak emitted wavelength of this LED?
Permissible Pulse Handling Capability. First, we need to answer this following question:
Why not have the LED just on and off?(selected materials fromthis site)
1.
This lets the LED cool off. IR LEDs can take up to 1 Amp (1000
milliamps!) of current. Most LEDs only take 20mA or so. This means IR
LEDs are designed for high-power blasting BUT they can only take it for
a few microseconds. By PWM'ing it, you let the LED cool off half the
time. 2.
Another reason is that the TV will only listen to certain frequencies
of PWM. So a Sony remote at 37KHz won't be able to work with a JVC DVD
player that only wants say 50KHz. 3.
The most important reason is that by pulsing a carrier wave, you reduce
the effects of ambient lighting. The TV only looks for changes in light
levels that occur around 37–38 kHz.
From the following diagram, you can find the maximum permissible current when the duty cycle is 10% or 0.1.
Radiant intensity map. What is the Relative Radiant Intensity of light emitted by the LED when viewed 10° off center?
Which pin drives this IR LED? PL4 is associated with OC5B so it's a TIMER5's PWM module. .
Task 1 Use IR to send and receive a letter that was programmed into the code.
OC5B
is the PWM output pin that we are going to use. Putting a little jumper
on the top of JP8, the PWM pulses could be delivered to the Base of the
BJT. IR emission from the LED will be received by the decoder, a
digital signal will be available at the PL5 pin (Pin 44). However, we
don't want to use that pin as the digital input to the MCU. Place
a female-female jumper wire to connect Pin 44 and Pin 19. Pin 44 is the
digital output of the decoder, Pin 19 is the digital input of the UART
Module 1.
38
kHz pulses need a 1/38k = 26.3 or 26 us. So the PWM is 26 us. 1:1
prescaler is not the best choice but it is fine (lower duty cycle
resolution). What is
the duty value to make 10% duty cycle happen? - 10% * 26 us = 2.6 us.
N is the prescaler.
This first task doesn't use an ISR to send or receive. We use the TIMER5 module for PWM and the TIMER3 module to create a 9600 bits/s envelope for UART1 (or Serial1). Therefore,
to let Rx receives a 0, you need to turn on the PWM; to let Rx receives
a 1, you need to turn off PWM. The bit rate we are going to use is 1200
bits/s for UART1 (Serial1) in Task 1; In Task 2 and 3, we'll change it
to 2400 bits/s. When ISR is not used, you need to manually clear
the overflow flag by writing a 1 to the TOV3 bit, which is TIFR3 |= (1
<< TOV3); Since ISR is not used, you don't need to enable TIMER3's interrupt - TIMSK3 |= (1 << TOIE3);
Use the following code snippet to turn on PWM:
TCCR5A |= (1 << WGM51) | (1 << COM5B1);
TCCR5B |= (1 << WGM52) | (1 << WGM53) | (1 << CS50);
OCR5B = LED_ON;
Use the following code snippet to turn off PWM:
TCCR5A &= ~(1 << COM5B1); Interestingly, it is not OCR5B = 0 to turn it off.
You'll need to use the following block as a routine to create a time delay using TIMER3:
TCNT3 = 0x10000 - bitPeriod[baudRateSelected]; // set up the count for
a certain amount of time delay
TCCR3B |= (1 << CS30); // Prescaler 1:1 and turn on the timer
while ((TIFR3 & (1 << TOV3)) == 0); // Wait here when it is
counting
TCCR3B = 0x00; // Turn off the timer when the timer is up
TIFR3 |= (1 << TOV3); // Write a 1 to TOV3 to clear the TOV3 bit
so the timer can be re-opened in the next cycle
Use the following code snippet to go through all the bits in a byte (the letter's ASCII code). mask = 0b00000001; while (mask != 0) {
if (letter & mask) {
xxxxxxxxxxxxxxxxxxxxx; // Your code here, turn off the emitter } else {
xxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxx // Your code here, turn on the emitter }
mask <<= 1;
Case 'R' is given:
if (Serial1.available()>0) {
char received =
Serial1.read();
Serial.print("Just read in ");
Serial.print(received);
Serial.print(" from Serial1");
Serial.print(" (0x");
Serial.print(received, HEX);
Serial.println(")"); } else {
Serial.println("Nothing received from Serial1"); } break;
You'll need to design your Case 'S' to send the Start bit, the data byte, and the Stop bit through the emitter.
Task 1 grading rubric: (Your
code should be built using the examples provided in this tutorial and
must not rely on entirely new programming methods found through AI) 1. #define and variable declaration (10 points) 2.
The void setup() function (10 points). Serial1 baud rate 1200 bits/s. Place TIFR3 |= (1 <<
TOV3); in your setup function if the first letter received is incorrect. 3. Case 'S'. (30 points)
Task 1's demo video:
Task 2 Repeat Task 1 Using the TIMER3 ISR to Send
When it enters ISR, the TOV3 bit is cleared automatically so TIFR3 |= (1 << TOV3); is not needed.
ISR needs to be enabled in the setup() function: TIMSK3 |= (1 << TOIE3);
In
Case 'S', set a flag to be true so the next time it enters the ISR, it
doesn't stay at the TX_IDLE state but the TX_DATA_BITS state.
At the end of the ISR, TIMER3's TCNT3 register needs to be re-configured.
Task 2 grading rubric: (Your
code should be built using the examples provided in this tutorial and
must not rely on entirely new programming methods found through AI.) 1. #define and variable declaration (10 points) 2.
The void setup() function (10 points). Serial1 baud rate 2400 bits/s. 3. Case 'S'. (30 points). Add delay(10) to your 'S' or 'R' cases if data instability is observed. 4. The ISR. (50 points) Task 2's demo video is not provided since it does the same job.
Task 3 Use IR to transmit a string
In
order to have better control of Serial 1, we need to bypass the
embedded function Serial1.begin(). This function sets up the baud rate,
enable receive and trasmitt interrupts, and defines the data length.
Now, we need to configure these operations using Arduino's control
registers.
The
UBRRn register sets up the baud rate. The user must follow the
following equation to assign the baud values to the 12-bit UBRRnH/L
registers
There
are two bytes (16 bits) allocated for the UBRR registers but only the
lower 4 bits of UBRRHn and the entire byte of UBRRLn are used.
Therefore, you need the following two lines to assign your baud values
to these registers: UBRR1H = BAUD_VALUE >> 8; UBRR1L = BAUD_VALUE;
RXCIEn
The UART1 initialization for this example is as follows:
UBRR1H = BAUD_VALUE >> 8; UBRR1L = BAUD_VALUE; // Enable receiver, transmitter, and RX Complete interrupt UCSR1B = (1 << RXEN1) | (1 << RXCIE1); // Set frame format: 8 data bits, no parity, 1 stop bit UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
We use 2400 bits/s as the baud rate, what is BAUD_VALUE?