ATtiny402 Infrarot-Transceiver
Das bereits vorgestellte Infrarot-Morsegerät
mit kapazitivem Berührungsssensor wurde noch einmal verbessert und zu
einem kompletten Infrarot-Transceiver erweitert. Das Ziel waren kleine
Morsegeräte für Übungen im Amateurfunk-Club. Teilnehmer von Morsekursen
können sich gegenseitig anfunken und den normalen Funkverkehr üben.
Neben der IR-Sendediode ist auch der IR-Empfänger mit auf der Platine.
Zusätzlich muss nur noch ein Piezo-Lautsprecher angeschlossen werden.
Ein entscheidender Punkt ist der geringe Stromverbrauch und eine
automatische Abschaltung nach einer gewissen Zeit ohne Sendeaktion. Der
Mikrocontroller ATtin202/402 schaltet dann das Empfänger-IC und eine
Bereitschafts-LED ab und geht in den Power-Down-Modus. Gemessen wurde
ein Reststrom von nur noch 3 µA, was unterhalb der Selbstentladung
üblicher Batterien liegt. Eine kleiner Li-Akku findet Platz auf der
Platine.
Zum erneuten Einschalten wird ein Tastschalter verwendet, der einen
Interrupt auslöst und den Controller aus dem Sleep-Modus aufweckt. Als
zweite Nutzung kann dieser Taster auch alternativ zum Berührungssensor
als Morsetaste verwendet werden. PA6 verwendet einen internen Pullup
und ist mit dem Taster verbunden. An PA7 liegt eine rote LED zur
Anzeige der Bereitschaft. Gleichzeit wird über PA3 der Empfänger
eingeschaltet. Beide Ausgänge hätte man auch zusammenfasen können.
Allerdings ist so die Möglichkeit offen geblieben, den Empfänger
während der aktiven Aussendung stumm zu schalten. Das aktuelle Programm
lässt den Empfänger mitlaufen, sodass man über die optische Kopplung
einen Mithörton bekommt. PA3 steuert wieder die IR-Sende-LED, wobei
diesmal ein Treibertransistor für eine höhere Sendeleistung eingesetzt
wird. Die Reichweite konnte damit bis auf 10 m vergrößert werden.
//IRCWTRX202, Touch PA1, IR-LED PA3, LED PA7, S1 PA6, RX PA2
#include <avr/io.h>
#define F_CPU 3333333
#define __DELAY_BACKWARD_COMPATIBLE__
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/atomic.h>
volatile uint8_t pa6Ioc;
uint8_t t=0;
uint16_t timeout = 0;
ISR(PORTA_PORT_vect){
if(PORTA.INTFLAGS & PIN6_bm){
pa6Ioc = 1;
PORTA.INTFLAGS &= PIN6_bm;
}
}
int main(void){
PORTA.DIRSET = PIN3_bm; //Ausgang PA3
PORTA.DIRSET = PIN1_bm; //Ausgang PA1
PORTA.PIN1CTRL = PORT_PULLUPEN_bm;; //Pullup PA1
PORTA.DIR |= PIN7_bm; //LED
PORTA.OUT |= PIN7_bm;
PORTA.DIR |= PIN2_bm; //IR-RX
PORTA.OUT |= PIN2_bm;
PORTA.DIR &= ~ PIN6_bm; //S1
PORTA.PIN6CTRL |= PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
while(1) {
t=0;
PORTA.DIRCLR = PIN1_bm;
while((!(VPORTA.IN & PIN1_bm))&&(t<3)){
t++;
}
PORTA.DIRSET = PIN1_bm;
if (t>1 ||!(VPORTA.IN & PIN6_bm) ){
for(char n=0; n<10; n++){
PORTA.OUTSET = PIN3_bm;
_delay_us(3);
PORTA.OUTCLR = PIN3_bm;
_delay_us(21);
}
timeout = 0;
}
_delay_ms(1);
timeout++;
if(timeout>65000){
PORTA.OUT &= !PIN7_bm;
PORTA.OUT &= !PIN2_bm;
sleep_mode();
ATOMIC_BLOCK(ATOMIC_FORCEON){
_delay_ms(10);
}
timeout=0;
PORTA.OUT |= PIN7_bm;
PORTA.OUT |= PIN2_bm;
}
}
}