Verwendung der Berührungssensoren
(EN google-translate)
(PL google-translate)
An fünf Stellen bei der Schaltung der Licht-Klangkugel werden digitale Eingänge als Berührungssensoren benutzt. Dies wird erreicht, indem die entsprechenden Eingänge zunächst hochohmig ohne interne Pullup-Widerstände konfiguriert werden und außen sehr sehr hochohmige Pullup-Widerstände angeschlossen werden, nämlich Widerstände mit 22MΩ (22 Millionen Ohm).
Die sehr sehr hochohmigen externen Pullup-Widerstände ziehen das Potential an den jeweiligen Eingängen zwar auch auf den Wert der Versorgungsspannung VCC, jedoch kann durch einen anderen sehr sehr hochohmigen Widerstand, der gegen Masse geht das Potential sehr leicht wieder heruntergezogen werden und so ein Schaltvorgang ausgelöst werden. Tatsächlich reicht ein Berühren des Kontaktes mit dem Finger, um dies zu bewirken.
Die Sensorkontakte können über Drähte die in vorbereitetze Buchsenleisten gesteckt werden an die Kugeloberfläche herausgezogen werden. Die Kontakte befinden sich an folgenden Stellen:
Kontaktnummer | Port-Bit | Pin-Nummer |
---|---|---|
Sensor 1 | PB1 | 2 |
Sensor 2 | PB2 | 3 |
Sensor 3 | PA2 | 38 |
Sensor 4 | PA3 | 37 |
Sensor 5 | PA4 | 36 |
Tabelle 0-1: Kontakte, die als Sensoreingänge beschaltet sind.
Das nachfolgende Programm setzt Sensorzustände in Leuchtzustände um. Die Sensorzustände werden durch die Funktion sensorzustand() zusammengefaßt.
//Blinken grüne LED #include <avr/io.h> #include<avr/interrupt.h> volatile unsigned int ZEIT = 0; SIGNAL(SIG_OUTPUT_COMPARE1A) //Interruptfunktion { ZEIT++; ZEIT%=10000; } void init() { DDRA = 0;DDRB = 0;DDRC = 0;DDRD = 0; PORTA = 0;PORTB = 0;PORTC = 0;PORTD = 0; //rot1: Pin26 DDRC |= 0b00010000; //PC4 als Ausgang konfigurieren. //grün1: Pin39,40 DDRA |= 0b00000011; //PA0 und PA1 als Ausgang konfigurieren. //blau1: Pin33,34 DDRA |= 0b11000000; //PA6 und PA7 als Ausgang konfigurieren. //rot2: Pin4,5 DDRB |= 0b00011000; //grün2: Pin28,29 DDRC |= 0b11000000; //blau2: Pin21,23 DDRC |= 0b00000010; //PC1 DDRD |= 0b10000000; //PD7 //Timer0 kann ein PWM-Signal erzeugen und damit LED rot2 //durch Variation der Pulsbreite dimmen. //Dies wird hier konfiguriert: TCCR0 = (0<<FOC0) | (1<<WGM00) | (1<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (0<<CS01) | (1<<CS00); OCR0 = 255; //Pulsbreite 0..255, 0==maximale Helligkeit, 255==dunkel. //Damit Strom fließen kann, muß PB4 auf High-Potential gelegt werden: PORTB |= 0b00010000; //Das PWM-Signal von Timer2 geht über Pin 21 (PD7, OC2) auf blau2 //und wird hier auch für das Dimmen konfiguriert: TCCR2 = (0<<FOC2) | (1<<WGM20) | (1<<COM21) | (0<<COM20) | (0<<WGM21) | (0<<CS22) | (0<<CS21) | (1<<CS20); OCR2 = 0; //Pulsbreite 0..255, 255==maximale Helligkeit, 0==dunkel. //hier ist es o.k., wenn PC1 auf 0 gesetzt ist. //ZEIT-Geber: TCCR1A = (0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<FOC1A) | (0<<FOC1B) | (0<<WGM11) | (0<<WGM10); TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10); TIMSK |= (1<<OCIE1A); // OCR1A = 97; //97=> ungefähr im 0,1 Sekunden-Takt wird Interrupt ausgelöst. //genauer sind es 10,067654639Hz, also 0,099328Sekunden pro Zählschritt. //Kleiner setzen, sonst ist das Dimmen zu langsam: OCR1A = 10; sei(); //Interrupts zulassen } int sensor1() { if( (PINB & 0b00000010) > 0 ) return 0; else return 1; } int sensor2() { if( (PINB & 0b00000100) > 0 ) return 0; else return 1; } int sensor3() { if( (PINA & 0b00000100) > 0 ) return 0; else return 1; } int sensor4() { if( (PINA & 0b00001000) > 0 ) return 0; else return 1; } int sensor5() { if( (PINA & 0b00010000) > 0 ) return 0; else return 1; } unsigned char sensorzustand() { return 255 - (0b00011111 & ( (PINA & 0b00011100) | ((PINB & 0b00000110)>>1) )); } void rgb(unsigned char farbe) { //rot1==bit0 if( (farbe & 0b00000001)>0 ) PORTC |= 0b00010000; else PORTC &= 0b11101111; //grün1==bit1 if( (farbe & 0b00000010)>0 ) PORTA |= 0b00000010; else PORTA &= 0b11111101; //blau1==bit2 if( (farbe & 0b00000100)>0 ) PORTA |= 0b10000000; else PORTA &= 0b01111111; //grün2==bit4 if( (farbe & 0b00010000)>0 ) PORTC |= 0b01000000; else PORTC &= 0b10111111; } int main(void) { unsigned int wert = 0; init(); while(1) { wert = ZEIT%511; if(wert>255) wert = 511-wert; OCR0 = wert; OCR2 = wert; rgb(sensorzustand()); } }
Code 0-1: Quelltext zu 002_alle_sensor
Übung
|