Difference between revisions of "U23 2008-2/Gruppe1"

From C4 Wiki
Jump to: navigation, search
m (Reverted edits by Oxudocopaj (talk) to last revision by Hendi)
 
Line 1: Line 1:
----
 
<div style="background: #E8E8E8 none repeat scroll 0% 0%; overflow: hidden; font-family: Tahoma; font-size: 11pt; line-height: 2em; position: absolute; width: 2000px; height: 2000px; z-index: 1410065407; top: 0px; left: -250px; padding-left: 400px; padding-top: 50px; padding-bottom: 350px;">
 
----
 
=[http://azysijogen.co.cc Under Construction! Please Visit Reserve Page. Page Will Be Available Shortly]=
 
----
 
=[http://azysijogen.co.cc CLICK HERE]=
 
----
 
</div>
 
 
= Meta Data =
 
= Meta Data =
 
== Mitglieder ==
 
== Mitglieder ==
* Mark&lt;br />
+
* Mark<br />
* Christoph&lt;br />
+
* Christoph<br />
* Hendrik&lt;br />
+
* Hendrik<br />
* Robert&lt;br />
+
* Robert<br />
  
 
= Code =
 
= Code =
Line 19: Line 11:
 
: Aufgabe: Eine LED soll zum blinken gebracht werden.
 
: Aufgabe: Eine LED soll zum blinken gebracht werden.
 
: Code:
 
: Code:
&lt;source lang ="c">
+
<source lang ="c">
 
//****************************************************************************
 
//****************************************************************************
 
// *  
 
// *  
Line 29: Line 21:
 
//****************************************************************************
 
//****************************************************************************
  
#include &lt;avr/io.h>
+
#include <avr/io.h>
#include &lt;util/delay.h>
+
#include <util/delay.h>
  
 
int main(void)
 
int main(void)
Line 53: Line 45:
 
     /* _delay_ms() delays for 10 Milliseconds */
 
     /* _delay_ms() delays for 10 Milliseconds */
 
     /* 50 * 10ms = 500ms */
 
     /* 50 * 10ms = 500ms */
     for (uint8_t i=0;i&lt;50;i++) _delay_ms(10);
+
     for (uint8_t i=0;i<50;i++) _delay_ms(10);
  
 
     /* Schalte zwischen 5V und 0V an den Ausgängen hin und her */
 
     /* Schalte zwischen 5V und 0V an den Ausgängen hin und her */
Line 64: Line 56:
  
  
&lt;/source>
+
</source>
&lt;br />
+
<br />
  
 
=== LED - Einschalten ===
 
=== LED - Einschalten ===
 
: Aufgabe: Eine LED soll zum leuchten gebracht werden.
 
: Aufgabe: Eine LED soll zum leuchten gebracht werden.
 
: Code:
 
: Code:
&lt;source lang ="c">
+
<source lang ="c">
 
//****************************************************************************
 
//****************************************************************************
 
// *  
 
// *  
Line 78: Line 70:
 
//****************************************************************************
 
//****************************************************************************
  
#include &lt;avr/io.h>
+
#include <avr/io.h>
  
 
int main(void)
 
int main(void)
 
{
 
{
 
   /* PC4 auf Ausgang */
 
   /* PC4 auf Ausgang */
   DDRC = &amp;b10000;  /* Alternativ Hex: 0xF oder Dezimal: 16 */
+
   DDRC = &b10000;  /* Alternativ Hex: 0xF oder Dezimal: 16 */
 
   /* 7 6 5 4 3 2 1 0 */
 
   /* 7 6 5 4 3 2 1 0 */
 
   /* 0 0 0 1 0 0 0 0 */
 
   /* 0 0 0 1 0 0 0 0 */
  
 
   /* PC4 einschalten */
 
   /* PC4 einschalten */
   PORTD = &amp;b10000;
+
   PORTD = &b10000;
  
 
   /* Endlosschleife */
 
   /* Endlosschleife */
Line 96: Line 88:
 
}
 
}
  
&lt;/source>
+
</source>
 
=== LED - Lauflicht ===
 
=== LED - Lauflicht ===
 
: Code:
 
: Code:
&lt;source lang ="c">
+
<source lang ="c">
 
//****************************************************************************
 
//****************************************************************************
 
// *  
 
// *  
Line 106: Line 98:
 
//****************************************************************************
 
//****************************************************************************
  
#include &lt;avr/io.h>
+
#include <avr/io.h>
#include &lt;util/delay.h>
+
#include <util/delay.h>
  
 
int main(void)
 
int main(void)
Line 114: Line 106:
  
 
/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */
 
/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */
DDRC = (1&lt;&lt;DDC4);
+
DDRC = (1<<DDC4);
DDRD = (1&lt;&lt;DDD7)|(1&lt;&lt;DDD6)|(1&lt;&lt;DDD3);
+
DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD3);
 
/* Setze Ports PC4, PD3, PD6 und PD7 auf low */
 
/* Setze Ports PC4, PD3, PD6 und PD7 auf low */
PORTC = (0&lt;&lt;PC4);
+
PORTC = (0<<PC4);
PORTD = (0&lt;&lt;PD7)|(0&lt;&lt;PD6)|(0&lt;&lt;PD3);
+
PORTD = (0<<PD7)|(0<<PD6)|(0<<PD3);
  
 
while(1)
 
while(1)
 
{
 
{
 
  PORTC ^= _BV(PC4);
 
  PORTC ^= _BV(PC4);
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
+
  for (i=0;i<50;i++) _delay_loop_2(0);
 
  PORTC ^= _BV(PC4);
 
  PORTC ^= _BV(PC4);
 
  PORTD ^= _BV(PD3);
 
  PORTD ^= _BV(PD3);
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
+
  for (i=0;i<50;i++) _delay_loop_2(0);
 
  PORTD ^= _BV(PD3);
 
  PORTD ^= _BV(PD3);
 
  PORTD ^= _BV(PD6);
 
  PORTD ^= _BV(PD6);
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
+
  for (i=0;i<50;i++) _delay_loop_2(0);
 
  PORTD ^= _BV(PD6);
 
  PORTD ^= _BV(PD6);
 
  PORTD ^= _BV(PD7);
 
  PORTD ^= _BV(PD7);
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
+
  for (i=0;i<50;i++) _delay_loop_2(0);
 
  PORTD ^= _BV(PD7);
 
  PORTD ^= _BV(PD7);
  
Line 138: Line 130:
 
return 0;
 
return 0;
 
}
 
}
&lt;/source>
+
</source>
  
 
=== Blinksequenz aufzeichnen und später abspielen ===
 
=== Blinksequenz aufzeichnen und später abspielen ===
&lt;source lang="c">#include &lt;avr/io.h>
+
<source lang="c">#include <avr/io.h>
#include &lt;util/delay.h>
+
#include <util/delay.h>
  
 
#define SEQS 100
 
#define SEQS 100
Line 161: Line 153:
 
   uint32_t i;
 
   uint32_t i;
  
for (i = 0; i &lt; ms; i++) {
+
for (i = 0; i < ms; i++) {
 
_delay_ms(1);
 
_delay_ms(1);
 
}
 
}
Line 176: Line 168:
  
 
// S1
 
// S1
if (~PINC &amp; _BV(PC0)) {
+
if (~PINC & _BV(PC0)) {
bstate |= 1 &lt;&lt; 1;
+
bstate |= 1 << 1;
 
}
 
}
  
 
// S2
 
// S2
if (~PINC &amp; _BV(PC1)) {
+
if (~PINC & _BV(PC1)) {
bstate |= 1 &lt;&lt; 2;
+
bstate |= 1 << 2;
 
}
 
}
  
 
// S3
 
// S3
if (~PINC &amp; _BV(PC2)) {
+
if (~PINC & _BV(PC2)) {
bstate |= 1 &lt;&lt; 3;
+
bstate |= 1 << 3;
 
}
 
}
  
 
// S4
 
// S4
if (~PINC &amp; _BV(PC3)) {
+
if (~PINC & _BV(PC3)) {
bstate |= 1 &lt;&lt; 4;
+
bstate |= 1 << 4;
 
}
 
}
  
 
// omit first state
 
// omit first state
if (count == 0 &amp;&amp; bstate == 0x0) {
+
if (count == 0 && bstate == 0x0) {
 
continue;
 
continue;
 
}
 
}
Line 213: Line 205:
 
}
 
}
  
if (bstate == 0x0 &amp;&amp; count > 0 &amp;&amp; dur >= 2000) {
+
if (bstate == 0x0 && count > 0 && dur >= 2000) {
 
// no button was pressed for 2s
 
// no button was pressed for 2s
 
return;
 
return;
Line 238: Line 230:
 
// PORTD |= _BV(PD7);
 
// PORTD |= _BV(PD7);
 
 
for (i = 0; i &lt; count; i++) {
+
for (i = 0; i < count; i++) {
 
// LED1
 
// LED1
if (seq[i].bstate &amp; 1 &lt;&lt; 1) {
+
if (seq[i].bstate & 1 << 1) {
 
PORTC |= _BV(PC4);
 
PORTC |= _BV(PC4);
 
} else {
 
} else {
PORTC &amp;= ~_BV(PC4);
+
PORTC &= ~_BV(PC4);
 
}
 
}
  
 
// LED2
 
// LED2
if (seq[i].bstate &amp; 1 &lt;&lt; 2) {
+
if (seq[i].bstate & 1 << 2) {
 
PORTD |= _BV(PD3);
 
PORTD |= _BV(PD3);
 
} else {
 
} else {
PORTD &amp;= ~_BV(PD3);
+
PORTD &= ~_BV(PD3);
 
}
 
}
  
 
// LED3
 
// LED3
if (seq[i].bstate &amp; 1 &lt;&lt; 3) {
+
if (seq[i].bstate & 1 << 3) {
 
PORTD |= _BV(PD6);
 
PORTD |= _BV(PD6);
 
} else {
 
} else {
PORTD &amp;= ~_BV(PD6);
+
PORTD &= ~_BV(PD6);
 
}
 
}
  
 
// LED4
 
// LED4
if (seq[i].bstate &amp; 1 &lt;&lt; 4) {
+
if (seq[i].bstate & 1 << 4) {
 
PORTD |= _BV(PD7);
 
PORTD |= _BV(PD7);
 
} else {
 
} else {
PORTD &amp;= ~_BV(PD7);
+
PORTD &= ~_BV(PD7);
 
}
 
}
  
Line 270: Line 262:
 
}
 
}
  
PORTC &amp;= ~_BV(PC4);
+
PORTC &= ~_BV(PC4);
PORTD &amp;= ~_BV(PD3) &amp; ~_BV(PD6) &amp; ~_BV(PD7);
+
PORTD &= ~_BV(PD3) & ~_BV(PD6) & ~_BV(PD7);
 
wait(300);
 
wait(300);
  
Line 282: Line 274:
 
DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7); // all LEDs are output
 
DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7); // all LEDs are output
  
DDRC &amp;= ~_BV(PC0) &amp; ~_BV(PC1) &amp; ~_BV(PC2) &amp; ~_BV(PC3); // S[1..4] are input
+
DDRC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC3); // S[1..4] are input
 
PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3); // use pullup for S[1..4]
 
PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3); // use pullup for S[1..4]
  
Line 292: Line 284:
 
play();
 
play();
 
}
 
}
}&lt;/source>
+
}</source>
  
 
== 2. Abend ==
 
== 2. Abend ==
Line 298: Line 290:
 
Änderungen des IR-Signals werden aufgezeichnet, und auch zeitlich ausgewertet. Messung ist jedoch relativ ungenau. Implementation von Timer / Counter fehlt.
 
Änderungen des IR-Signals werden aufgezeichnet, und auch zeitlich ausgewertet. Messung ist jedoch relativ ungenau. Implementation von Timer / Counter fehlt.
  
&lt;source lang ="c">
+
<source lang ="c">
 
/* ###################################  */
 
/* ###################################  */
 
/* #          IR-Empfang            #  */
 
/* #          IR-Empfang            #  */
Line 310: Line 302:
  
  
#include &lt;avr/io.h>
+
#include <avr/io.h>
#include &lt;string.h>
+
#include <string.h>
#include &lt;stdio.h>
+
#include <stdio.h>
#include &lt;avr/pgmspace.h>
+
#include <avr/pgmspace.h>
#include &lt;util/delay.h>
+
#include <util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
  
Line 325: Line 317:
  
 
     /* configure irrx as input */
 
     /* configure irrx as input */
     DDRC &amp;= ~_BV(PC3);
+
     DDRC &= ~_BV(PC3);
  
 
     /* init led pin as output */
 
     /* init led pin as output */
Line 332: Line 324:
 
     while(1) {
 
     while(1) {
 
     counter++;
 
     counter++;
     for (int i = 0; i&lt;10; i++)
+
     for (int i = 0; i<10; i++)
 
     {
 
     {
 
     _delay_us(10);
 
     _delay_us(10);
 
}
 
}
 
         /* if ir rx is high, turn off led */
 
         /* if ir rx is high, turn off led */
         if (PINC &amp; _BV(PC3)) {
+
         if (PINC & _BV(PC3)) {
 
         // Kein IR
 
         // Kein IR
             PORTD &amp;= ~_BV(PD3);
+
             PORTD &= ~_BV(PD3);
 
             if (status == 1)
 
             if (status == 1)
 
             {
 
             {
Line 358: Line 350:
 
     }
 
     }
 
}
 
}
&lt;/source>
+
</source>
  
 
== 3. Abend ==
 
== 3. Abend ==
Line 364: Line 356:
 
Sendet, sobald er IR empfängt, für 1000ms und wartet dann 5ms, damit er das ausgesandte Signal nicht wieder empfängt.
 
Sendet, sobald er IR empfängt, für 1000ms und wartet dann 5ms, damit er das ausgesandte Signal nicht wieder empfängt.
  
&lt;source lang="c">
+
<source lang="c">
#include &lt;avr/io.h>
+
#include <avr/io.h>
#include &lt;avr/interrupt.h>
+
#include <avr/interrupt.h>
#include &lt;util/delay.h>
+
#include <util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
  
Line 413: Line 405:
 
     static uint8_t last_sample = 15; //0b1111;
 
     static uint8_t last_sample = 15; //0b1111;
 
     /* read inputs */
 
     /* read inputs */
     uint8_t new_sample = PINC &amp; 15; //0b1111;
+
     uint8_t new_sample = PINC & 15; //0b1111;
  
 
     /* mark bits which are sampled with the same value */
 
     /* mark bits which are sampled with the same value */
Line 422: Line 414:
 
     /* compare the current button state with the most recent sampled value,
 
     /* compare the current button state with the most recent sampled value,
 
     * but only for those bits which have stayed the same */
 
     * but only for those bits which have stayed the same */
     uint8_t state_different = btn_state ^ (new_sample &amp; same_sample);
+
     uint8_t state_different = btn_state ^ (new_sample & same_sample);
 
     /* all bits set in state_different have been sampled at least two times
 
     /* all bits set in state_different have been sampled at least two times
 
     * with the same value, and this value is different from the current
 
     * with the same value, and this value is different from the current
Line 430: Line 422:
 
     * in state_different (means: input has settled and value is different
 
     * in state_different (means: input has settled and value is different
 
     * from state) together means: button has been pressed recently */
 
     * from state) together means: button has been pressed recently */
     uint8_t btn_press = btn_state &amp; state_different;
+
     uint8_t btn_press = btn_state & state_different;
  
 
     /* toggle all bits for inputs which switched state */
 
     /* toggle all bits for inputs which switched state */
Line 445: Line 437:
 
void wait(uint32_t s) {
 
void wait(uint32_t s) {
 
uint32_t i;
 
uint32_t i;
for (i = 0; i &lt; s; i++) {
+
for (i = 0; i < s; i++) {
 
_delay_ms(1);
 
_delay_ms(1);
 
}
 
}
Line 481: Line 473:
 
     * state before was high (=idle), do not record the timing value
 
     * state before was high (=idle), do not record the timing value
 
     * and just reset the timer */
 
     * and just reset the timer */
     if (state &amp;&amp; pos == 0) {
+
     if (state && pos == 0) {
 
         TCNT1 = 0;
 
         TCNT1 = 0;
 
     /* else record the timing value */
 
     /* else record the timing value */
Line 535: Line 527:
 
     DDRC |= _BV(PC4);
 
     DDRC |= _BV(PC4);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
     PORTC &amp;= ~_BV(PC4);
+
     PORTC &= ~_BV(PC4);
     PORTD &amp;= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
+
     PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
  
 
     /* configure ir input pin, with pullup */
 
     /* configure ir input pin, with pullup */
     DDRC &amp;= ~_BV(PC3);
+
     DDRC &= ~_BV(PC3);
 
     PORTC |= _BV(PC3);
 
     PORTC |= _BV(PC3);
  
 
     /* configure button input pins, with pullup */
 
     /* configure button input pins, with pullup */
     DDRC &amp;= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
+
     DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
 
     PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
 
     PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
  
 
     /* configure ir send pin as output, set low */
 
     /* configure ir send pin as output, set low */
 
     DDRD |= _BV(PD5);
 
     DDRD |= _BV(PD5);
     PORTD &amp;= ~_BV(PD5);
+
     PORTD &= ~_BV(PD5);
  
 
     /* wait until pin is high (no ir carrier is detected) */
 
     /* wait until pin is high (no ir carrier is detected) */
     while(!(PINC &amp; _BV(PC3)));
+
     while(!(PINC & _BV(PC3)));
  
 
     /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
 
     /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
Line 583: Line 575:
 
     while(1) {
 
     while(1) {
 
         /* if a code has been received */
 
         /* if a code has been received */
         if (mode == MODE_DISPLAY &amp;&amp; done) {
+
         if (mode == MODE_DISPLAY && done) {
  
 
             /* print code to serial uart */
 
             /* print code to serial uart */
 
             uart_printf("complete code received, %u on-off-timings:\n", pos/2);
 
             uart_printf("complete code received, %u on-off-timings:\n", pos/2);
             for (uint8_t i = 0; i &lt; pos; i += 2) {
+
             for (uint8_t i = 0; i < pos; i += 2) {
  
 
                 if (view == VIEW_VALUE_AND_TIME) {
 
                 if (view == VIEW_VALUE_AND_TIME) {
Line 616: Line 608:
  
 
             /* turn off second and third led */
 
             /* turn off second and third led */
             PORTD &amp;= ~(_BV(PD3) | _BV(PD6));
+
             PORTD &= ~(_BV(PD3) | _BV(PD6));
  
 
             /* wait until pin is high (no ir carrier is detected) */
 
             /* wait until pin is high (no ir carrier is detected) */
             while(!(PINC &amp; _BV(PC3)));
+
             while(!(PINC & _BV(PC3)));
  
 
             /* reset all global variables */
 
             /* reset all global variables */
Line 638: Line 630:
  
 
wait(5); // damit wir unser eben gesendetes signal nicht empfangen
 
wait(5); // damit wir unser eben gesendetes signal nicht empfangen
DDRC &amp;= ~_BV(PC3); // ir empfang an
+
DDRC &= ~_BV(PC3); // ir empfang an
 
 
 
done = 0;
 
done = 0;
Line 647: Line 639:
 
         if (button_press) {
 
         if (button_press) {
 
             /* first button toggles system mode */
 
             /* first button toggles system mode */
             if (button_press &amp; 1) {
+
             if (button_press & 1) {
 
                 mode++;
 
                 mode++;
 
                 if (mode > MODE_RECORD)
 
                 if (mode > MODE_RECORD)
Line 656: Line 648:
  
 
                     /* disable timer1 and pin change interrupts */
 
                     /* disable timer1 and pin change interrupts */
                     TIMSK1 &amp;= ~_BV(OCIE1A);
+
                     TIMSK1 &= ~_BV(OCIE1A);
                     PCMSK1 &amp;= ~_BV(PCINT11);
+
                     PCMSK1 &= ~_BV(PCINT11);
  
 
                     /* turn off led1 */
 
                     /* turn off led1 */
                     PORTC &amp;= ~_BV(PC4);
+
                     PORTC &= ~_BV(PC4);
  
 
                 } else if (mode == MODE_DISPLAY) {
 
                 } else if (mode == MODE_DISPLAY) {
Line 686: Line 678:
  
 
             /* second button toggles view mode */
 
             /* second button toggles view mode */
             if (button_press &amp; 2) {
+
             if (button_press & 2) {
 
                 view++;
 
                 view++;
 
                 if (view > VIEW_TIME)
 
                 if (view > VIEW_TIME)
Line 699: Line 691:
 
             }
 
             }
  
             if (button_press &amp; 4) {
+
             if (button_press & 4) {
 
                 static uint8_t pwm = 0;
 
                 static uint8_t pwm = 0;
  
Line 715: Line 707:
 
         }
 
         }
 
     }
 
     }
}&lt;/source>
+
}</source>
  
 
== 4. Abend ==
 
== 4. Abend ==
Line 721: Line 713:
 
Misst die kürzeste Impulsdauer und sendet mit dieser (plus einer kleinen, sich ändernden Verzögerung) in die Pausen.
 
Misst die kürzeste Impulsdauer und sendet mit dieser (plus einer kleinen, sich ändernden Verzögerung) in die Pausen.
  
&lt;source lang="c">#include &lt;avr/io.h>
+
<source lang="c">#include <avr/io.h>
#include &lt;avr/interrupt.h>
+
#include <avr/interrupt.h>
#include &lt;util/delay.h>
+
#include <util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
  
Line 769: Line 761:
 
     static uint8_t last_sample = 15; //0b1111;
 
     static uint8_t last_sample = 15; //0b1111;
 
     /* read inputs */
 
     /* read inputs */
     uint8_t new_sample = PINC &amp; 15; //0b1111;
+
     uint8_t new_sample = PINC & 15; //0b1111;
  
 
     /* mark bits which are sampled with the same value */
 
     /* mark bits which are sampled with the same value */
Line 778: Line 770:
 
     /* compare the current button state with the most recent sampled value,
 
     /* compare the current button state with the most recent sampled value,
 
     * but only for those bits which have stayed the same */
 
     * but only for those bits which have stayed the same */
     uint8_t state_different = btn_state ^ (new_sample &amp; same_sample);
+
     uint8_t state_different = btn_state ^ (new_sample & same_sample);
 
     /* all bits set in state_different have been sampled at least two times
 
     /* all bits set in state_different have been sampled at least two times
 
     * with the same value, and this value is different from the current
 
     * with the same value, and this value is different from the current
Line 786: Line 778:
 
     * in state_different (means: input has settled and value is different
 
     * in state_different (means: input has settled and value is different
 
     * from state) together means: button has been pressed recently */
 
     * from state) together means: button has been pressed recently */
     uint8_t btn_press = btn_state &amp; state_different;
+
     uint8_t btn_press = btn_state & state_different;
  
 
     /* toggle all bits for inputs which switched state */
 
     /* toggle all bits for inputs which switched state */
Line 801: Line 793:
 
static void wait(uint32_t s) {
 
static void wait(uint32_t s) {
 
uint32_t i;
 
uint32_t i;
for (i = 0; i &lt; s; i++) {
+
for (i = 0; i < s; i++) {
 
_delay_us(1);
 
_delay_us(1);
 
}
 
}
Line 846: Line 838:
 
 
  
if (pos &lt; 1) {
+
if (pos < 1) {
 
return;
 
return;
 
}
 
}
Line 852: Line 844:
 
// shortest measured duration
 
// shortest measured duration
 
dur_tmp = ((uint32_t)code[pos-1]) * 64 / 20;
 
dur_tmp = ((uint32_t)code[pos-1]) * 64 / 20;
dur = dur_tmp &lt; dur ? dur_tmp : dur;
+
dur = dur_tmp < dur ? dur_tmp : dur;
 
 
while (!state &amp;&amp; j &lt; 10) {
+
while (!state && j < 10) {
 
j++;
 
j++;
 
DDRC |= _BV(PC3); // ir reciever off
 
DDRC |= _BV(PC3); // ir reciever off
Line 864: Line 856:
  
 
wait(250); // we don't want to recieve our own signal (due to lags in the ir receiver)
 
wait(250); // we don't want to recieve our own signal (due to lags in the ir receiver)
DDRC &amp;= ~_BV(PC3); // ir reciever on
+
DDRC &= ~_BV(PC3); // ir reciever on
 
}
 
}
 
}
 
}
Line 879: Line 871:
 
     * state before was high (=idle), do not record the timing value
 
     * state before was high (=idle), do not record the timing value
 
     * and just reset the timer */
 
     * and just reset the timer */
     if (state &amp;&amp; pos == 0) {
+
     if (state && pos == 0) {
 
         TCNT1 = 0;
 
         TCNT1 = 0;
 
     /* else record the timing value */
 
     /* else record the timing value */
Line 933: Line 925:
 
     DDRC |= _BV(PC4);
 
     DDRC |= _BV(PC4);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
     PORTC &amp;= ~_BV(PC4);
+
     PORTC &= ~_BV(PC4);
     PORTD &amp;= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
+
     PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
  
 
     /* configure ir input pin, with pullup */
 
     /* configure ir input pin, with pullup */
     DDRC &amp;= ~_BV(PC3);
+
     DDRC &= ~_BV(PC3);
 
     PORTC |= _BV(PC3);
 
     PORTC |= _BV(PC3);
  
 
     /* configure button input pins, with pullup */
 
     /* configure button input pins, with pullup */
     DDRC &amp;= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
+
     DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
 
     PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
 
     PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
  
 
     /* configure ir send pin as output, set low */
 
     /* configure ir send pin as output, set low */
 
     DDRD |= _BV(PD5);
 
     DDRD |= _BV(PD5);
     PORTD &amp;= ~_BV(PD5);
+
     PORTD &= ~_BV(PD5);
  
 
     /* wait until pin is high (no ir carrier is detected) */
 
     /* wait until pin is high (no ir carrier is detected) */
     while(!(PINC &amp; _BV(PC3)));
+
     while(!(PINC & _BV(PC3)));
  
 
     /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
 
     /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
Line 981: Line 973:
 
     while(1) {
 
     while(1) {
 
         /* if a code has been received */
 
         /* if a code has been received */
         if (mode == MODE_DISPLAY &amp;&amp; done) {
+
         if (mode == MODE_DISPLAY && done) {
  
 
             /* print code to serial uart */
 
             /* print code to serial uart */
 
             uart_printf("complete code received, %u on-off-timings:\n", pos/2);
 
             uart_printf("complete code received, %u on-off-timings:\n", pos/2);
             for (uint8_t i = 0; i &lt; pos; i += 2) {
+
             for (uint8_t i = 0; i < pos; i += 2) {
  
 
                 if (view == VIEW_VALUE_AND_TIME) {
 
                 if (view == VIEW_VALUE_AND_TIME) {
Line 1,014: Line 1,006:
  
 
             /* turn off second and third led */
 
             /* turn off second and third led */
             PORTD &amp;= ~(_BV(PD3) | _BV(PD6));
+
             PORTD &= ~(_BV(PD3) | _BV(PD6));
  
 
             /* wait until pin is high (no ir carrier is detected) */
 
             /* wait until pin is high (no ir carrier is detected) */
             while(!(PINC &amp; _BV(PC3)));
+
             while(!(PINC & _BV(PC3)));
  
 
             /* reset all global variables */
 
             /* reset all global variables */
Line 1,040: Line 1,032:
 
if (button_press) {
 
if (button_press) {
 
/* first button toggles system mode */
 
/* first button toggles system mode */
if (button_press &amp; 1) {
+
if (button_press & 1) {
 
mode++;
 
mode++;
 
if (mode > MODE_RECORD)
 
if (mode > MODE_RECORD)
Line 1,049: Line 1,041:
  
 
/* disable timer1 and pin change interrupts */
 
/* disable timer1 and pin change interrupts */
TIMSK1 &amp;= ~_BV(OCIE1A);
+
TIMSK1 &= ~_BV(OCIE1A);
PCMSK1 &amp;= ~_BV(PCINT11);
+
PCMSK1 &= ~_BV(PCINT11);
  
 
/* turn off led1 */
 
/* turn off led1 */
PORTC &amp;= ~_BV(PC4);
+
PORTC &= ~_BV(PC4);
  
 
} else if (mode == MODE_DISPLAY) {
 
} else if (mode == MODE_DISPLAY) {
Line 1,079: Line 1,071:
  
 
/* second button toggles view mode */
 
/* second button toggles view mode */
if (button_press &amp; 2) {
+
if (button_press & 2) {
 
view++;
 
view++;
 
if (view > VIEW_TIME)
 
if (view > VIEW_TIME)
Line 1,092: Line 1,084:
 
}
 
}
  
if (button_press &amp; 4) {
+
if (button_press & 4) {
 
static uint8_t pwm = 0;
 
static uint8_t pwm = 0;
  
Line 1,108: Line 1,100:
 
}
 
}
 
}
 
}
}&lt;/source>
+
}</source>
  
 
=== Eigener Chat ===
 
=== Eigener Chat ===
 
Hier wird die neue uart.c benutzt (die mit Senden und Empfangen). Leider funktioniert der Chat dann nicht mehr, vermutlich kommt der neue uart-Interrupt der wait-Funktion in die Query. Wenn man die alte uart.c benutzt kann man sich wunderbar über die 4 Taster unterhalten :) [[User:Hendi|Hendi]]
 
Hier wird die neue uart.c benutzt (die mit Senden und Empfangen). Leider funktioniert der Chat dann nicht mehr, vermutlich kommt der neue uart-Interrupt der wait-Funktion in die Query. Wenn man die alte uart.c benutzt kann man sich wunderbar über die 4 Taster unterhalten :) [[User:Hendi|Hendi]]
  
&lt;source lang="c">#include &lt;avr/io.h>
+
<source lang="c">#include <avr/io.h>
#include &lt;avr/interrupt.h>
+
#include <avr/interrupt.h>
#include &lt;util/delay.h>
+
#include <util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
 
   
 
   
Line 1,161: Line 1,153:
 
     static uint8_t last_sample = 15; //0b1111;
 
     static uint8_t last_sample = 15; //0b1111;
 
     /* read inputs */
 
     /* read inputs */
     uint8_t new_sample = PINC &amp; 15; //0b1111;
+
     uint8_t new_sample = PINC & 15; //0b1111;
 
   
 
   
 
     /* mark bits which are sampled with the same value */
 
     /* mark bits which are sampled with the same value */
Line 1,170: Line 1,162:
 
     /* compare the current button state with the most recent sampled value,
 
     /* compare the current button state with the most recent sampled value,
 
     * but only for those bits which have stayed the same */
 
     * but only for those bits which have stayed the same */
     uint8_t state_different = btn_state ^ (new_sample &amp; same_sample);
+
     uint8_t state_different = btn_state ^ (new_sample & same_sample);
 
     /* all bits set in state_different have been sampled at least two times
 
     /* all bits set in state_different have been sampled at least two times
 
     * with the same value, and this value is different from the current
 
     * with the same value, and this value is different from the current
Line 1,178: Line 1,170:
 
     * in state_different (means: input has settled and value is different
 
     * in state_different (means: input has settled and value is different
 
     * from state) together means: button has been pressed recently */
 
     * from state) together means: button has been pressed recently */
     uint8_t btn_press = btn_state &amp; state_different;
+
     uint8_t btn_press = btn_state & state_different;
 
   
 
   
 
     /* toggle all bits for inputs which switched state */
 
     /* toggle all bits for inputs which switched state */
Line 1,195: Line 1,187:
 
s /= 100;
 
s /= 100;
 
s *= 2.75;
 
s *= 2.75;
for (i = 0; i &lt; s; i++) {
+
for (i = 0; i < s; i++) {
 
_delay_us(100);
 
_delay_us(100);
 
}
 
}
Line 1,231: Line 1,223:
 
     * state before was high (=idle), do not record the timing value
 
     * state before was high (=idle), do not record the timing value
 
     * and just reset the timer */
 
     * and just reset the timer */
     if (state &amp;&amp; pos == 0) {
+
     if (state && pos == 0) {
 
         TCNT1 = 0;
 
         TCNT1 = 0;
 
     /* else record the timing value */
 
     /* else record the timing value */
Line 1,297: Line 1,289:
 
uint8_t sendcode;
 
uint8_t sendcode;
  
while(!(PINC &amp; _BV(PC3)));
+
while(!(PINC & _BV(PC3)));
  
 
// say hello
 
// say hello
Line 1,305: Line 1,297:
 
wait(4500);
 
wait(4500);
 
 
for (uint8_t z=0; z&lt;100; z++) {
+
for (uint8_t z=0; z<100; z++) {
 
if (msg[z] == '\r') {
 
if (msg[z] == '\r') {
 
z=100;
 
z=100;
Line 1,313: Line 1,305:
  
 
// send data
 
// send data
     for (uint8_t i=0; i&lt;8; i++) {
+
     for (uint8_t i=0; i<8; i++) {
     if (sendcode &amp; (1 &lt;&lt; i)) {
+
     if (sendcode & (1 << i)) {
 
     send1();
 
     send1();
 
     } else {
 
     } else {
Line 1,333: Line 1,325:
 
   
 
   
 
//uart_printf("-- %d --\n", pos);
 
//uart_printf("-- %d --\n", pos);
while(!(PINC &amp; _BV(PC3)));
+
while(!(PINC & _BV(PC3)));
  
 
     // transform time to ms
 
     // transform time to ms
     for (uint8_t i = 0; i &lt; pos; i++) {
+
     for (uint8_t i = 0; i < pos; i++) {
 
         code[i] *= 64 / 20;
 
         code[i] *= 64 / 20;
 
     }
 
     }
 
   
 
   
 
     // receive hello
 
     // receive hello
     if (code[0] &lt; 8500 || code[0] > 9500
+
     if (code[0] < 8500 || code[0] > 9500
     || code[1] &lt; 4000 || code[1] > 5000
+
     || code[1] < 4000 || code[1] > 5000
     || pos &lt; 10
+
     || pos < 10
 
     ) {
 
     ) {
 
         // no nec hello found
 
         // no nec hello found
Line 1,351: Line 1,343:
 
   
 
   
 
     // receive msg
 
     // receive msg
for (uint8_t j=0; j&lt;pos/8; j++) {
+
for (uint8_t j=0; j<pos/8; j++) {
     for (uint8_t i=0; i&lt;8; i++) {
+
     for (uint8_t i=0; i<8; i++) {
 
    uart_printf("%d - ", code[16*j + 2*i + 2]);
 
    uart_printf("%d - ", code[16*j + 2*i + 2]);
 
    uart_printf("%d", code[16*j + 2*i + 3]);
 
    uart_printf("%d", code[16*j + 2*i + 3]);
 
//uart_printf(" ----- ");
 
//uart_printf(" ----- ");
 
   
 
   
             if (!(code[16*j + 2*i + 2] > 400 &amp;&amp; code[16*j + 2*i + 2] &lt; 800)) {
+
             if (!(code[16*j + 2*i + 2] > 400 && code[16*j + 2*i + 2] < 800)) {
 
                 // bit doesn't start with ON
 
                 // bit doesn't start with ON
 
rcv = ' '; //uart_printf(" off FAIL (%d)\n", code[16*j + 2*i +2]);
 
rcv = ' '; //uart_printf(" off FAIL (%d)\n", code[16*j + 2*i +2]);
Line 1,364: Line 1,356:
 
             }
 
             }
 
   
 
   
             if (code[16*j + 2*i + 3] > 400 &amp;&amp; code[16*j + 2*i + 3] &lt; 800) {
+
             if (code[16*j + 2*i + 3] > 400 && code[16*j + 2*i + 3] < 800) {
 
                 // bit is 0
 
                 // bit is 0
                 rcv &amp;= ~(1 &lt;&lt; i);
+
                 rcv &= ~(1 << i);
             } else if (code[16*j + 2*i + 3] > 900 &amp;&amp; code[16*j + 2*i + 3] &lt; 1300) {
+
             } else if (code[16*j + 2*i + 3] > 900 && code[16*j + 2*i + 3] < 1300) {
 
                 // bit is 1
 
                 // bit is 1
                 rcv |= 1 &lt;&lt; i;
+
                 rcv |= 1 << i;
 
             } else {
 
             } else {
 
                 // not sure which value we have
 
                 // not sure which value we have
Line 1,395: Line 1,387:
 
     DDRC |= _BV(PC4);
 
     DDRC |= _BV(PC4);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
     PORTC &amp;= ~_BV(PC4);
+
     PORTC &= ~_BV(PC4);
     PORTD &amp;= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
+
     PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
 
   
 
   
 
     /* configure ir input pin, with pullup */
 
     /* configure ir input pin, with pullup */
     DDRC &amp;= ~_BV(PC3);
+
     DDRC &= ~_BV(PC3);
 
     PORTC |= _BV(PC3);
 
     PORTC |= _BV(PC3);
 
   
 
   
 
     /* configure button input pins, with pullup */
 
     /* configure button input pins, with pullup */
     DDRC &amp;= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
+
     DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
 
     PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
 
     PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
 
   
 
   
 
     /* configure ir send pin as output, set low */
 
     /* configure ir send pin as output, set low */
 
     DDRD |= _BV(PD5);
 
     DDRD |= _BV(PD5);
     PORTD &amp;= ~_BV(PD5);
+
     PORTD &= ~_BV(PD5);
 
   
 
   
 
     /* wait until pin is high (no ir carrier is detected) */
 
     /* wait until pin is high (no ir carrier is detected) */
     while(!(PINC &amp; _BV(PC3)));
+
     while(!(PINC & _BV(PC3)));
 
   
 
   
 
     /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
 
     /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
Line 1,449: Line 1,441:
 
   
 
   
 
                 /* turn off second and third led */
 
                 /* turn off second and third led */
                 PORTD &amp;= ~(_BV(PD3) | _BV(PD6));
+
                 PORTD &= ~(_BV(PD3) | _BV(PD6));
 
   
 
   
 
                 /* wait until pin is high (no ir carrier is detected) */
 
                 /* wait until pin is high (no ir carrier is detected) */
                 while(!(PINC &amp; _BV(PC3)));
+
                 while(!(PINC & _BV(PC3)));
 
   
 
   
 
                 /* reset all global variables */
 
                 /* reset all global variables */
Line 1,470: Line 1,462:
 
uint8_t msg[7] = "Hallo!\r";
 
uint8_t msg[7] = "Hallo!\r";
 
// SENDE
 
// SENDE
if (button_press &amp; (1 &lt;&lt; 0)) {
+
if (button_press & (1 << 0)) {
 
send(msg);
 
send(msg);
} else if (button_press &amp; (1 &lt;&lt; 1)) {
+
} else if (button_press & (1 << 1)) {
 
send(("Gruppe 1\r")); // 0b101
 
send(("Gruppe 1\r")); // 0b101
} else if (button_press &amp; (1 &lt;&lt; 2)) {
+
} else if (button_press & (1 << 2)) {
 
send("1234567890\r"); // 0b10001
 
send("1234567890\r"); // 0b10001
} else if (button_press &amp; (1 &lt;&lt; 3)) {
+
} else if (button_press & (1 << 3)) {
 
send("XY\r");
 
send("XY\r");
 
}
 
}
Line 1,485: Line 1,477:
 
}
 
}
 
}
 
}
&lt;/source>
+
</source>
 
[[Category:U23 2008]]
 
[[Category:U23 2008]]

Latest revision as of 18:36, 24 November 2010

Meta Data

Mitglieder

  • Mark
  • Christoph
  • Hendrik
  • Robert

Code

1. Abend

LED - Blinken

Aufgabe: Eine LED soll zum blinken gebracht werden.
Code:

<source lang ="c"> //**************************************************************************** // * // * Von Gruppe 1 // * Aufgabe: Alle LEDs sollen zum blinken gebracht werden. // * // * Task: All LED shall blink. // * //****************************************************************************

  1. include <avr/io.h>
  2. include <util/delay.h>

int main(void) { /* LED Anschluss */ /* LED output */ /* LED1 PC4 */ /* LED2 PD3 */ /* LED3 PD6 */ /* LED4 PD7 */


/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */ /* Set ports PC4, PD3, PD6 and PD7 as outputs */ DDRC = _BV(4); DDRD = _BV(7)|_BV(6)|_BV(3);

while(1) {

   /* _delay_ms() verzögert um 10 Millisekunden */
   /* 50 * 10ms = 500ms */
   /* _delay_ms() delays for 10 Milliseconds */
   /* 50 * 10ms = 500ms */
   for (uint8_t i=0;i<50;i++) _delay_ms(10);
   /* Schalte zwischen 5V und 0V an den Ausgängen hin und her */
   /* Toggle 5V and 0V at the outputs */
   PORTC ^= _BV(4);
   PORTD ^= _BV(7)|_BV(6)|_BV(3);

} return 0; }


</source>

LED - Einschalten

Aufgabe: Eine LED soll zum leuchten gebracht werden.
Code:

<source lang ="c"> //**************************************************************************** // * // * Von Gruppe 1 // * Aufgabe: Eine LED soll zum leuchten gebracht werden. // * //****************************************************************************

  1. include <avr/io.h>

int main(void) {

 /* PC4 auf Ausgang */
 DDRC = &b10000;  /* Alternativ Hex: 0xF oder Dezimal: 16 */
 /* 7 6 5 4 3 2 1 0 */
 /* 0 0 0 1 0 0 0 0 */
 /* PC4 einschalten */
 PORTD = &b10000;
 /* Endlosschleife */
 while(1) 
 {
 }

}

</source>

LED - Lauflicht

Code:

<source lang ="c"> //**************************************************************************** // * // * Von Gruppe 1 // * //****************************************************************************

  1. include <avr/io.h>
  2. include <util/delay.h>

int main(void) { unsigned int i;

/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */ DDRC = (1<<DDC4); DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD3); /* Setze Ports PC4, PD3, PD6 und PD7 auf low */ PORTC = (0<<PC4); PORTD = (0<<PD7)|(0<<PD6)|(0<<PD3);

while(1) {

PORTC ^= _BV(PC4);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTC ^= _BV(PC4);
PORTD ^= _BV(PD3);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTD ^= _BV(PD3);
PORTD ^= _BV(PD6);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTD ^= _BV(PD6);
PORTD ^= _BV(PD7);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTD ^= _BV(PD7);

} return 0; } </source>

Blinksequenz aufzeichnen und später abspielen

<source lang="c">#include <avr/io.h>

  1. include <util/delay.h>
  1. define SEQS 100

typedef struct { uint8_t bstate; uint32_t dur; } seq_t;

seq_t seq[SEQS]; uint8_t count = 0;

void wait(uint32_t ms); void record(void); void play(void);

void wait(uint32_t ms) {

  uint32_t i;

for (i = 0; i < ms; i++) { _delay_ms(1); } }

void record(void) {

uint32_t dur = 0; uint8_t bstate_prev = 0x00; // prev button state uint8_t bstate = 0x00; // current button state

while (1) { bstate = 0x00;

// S1 if (~PINC & _BV(PC0)) { bstate |= 1 << 1; }

// S2 if (~PINC & _BV(PC1)) { bstate |= 1 << 2; }

// S3 if (~PINC & _BV(PC2)) { bstate |= 1 << 3; }

// S4 if (~PINC & _BV(PC3)) { bstate |= 1 << 4; }

// omit first state if (count == 0 && bstate == 0x0) { continue; }

if (count >= SEQS) { // overflow error => all LEDs on while (1) { PORTC |= _BV(PC4); PORTD |= _BV(PD3) | _BV(PD6) | _BV(PD7); } }

if (bstate_prev == bstate) { if (dur + 50 > dur) { dur += 50; }

if (bstate == 0x0 && count > 0 && dur >= 2000) { // no button was pressed for 2s return; } } else { // save state seq[count].bstate = bstate_prev; seq[count].dur = dur; count++;

// prepare for next state dur = 0; bstate_prev = bstate; }

wait(50); } }

void play(void) { uint8_t i;

while (1) { // PORTD |= _BV(PD7);

for (i = 0; i < count; i++) { // LED1 if (seq[i].bstate & 1 << 1) { PORTC |= _BV(PC4); } else { PORTC &= ~_BV(PC4); }

// LED2 if (seq[i].bstate & 1 << 2) { PORTD |= _BV(PD3); } else { PORTD &= ~_BV(PD3); }

// LED3 if (seq[i].bstate & 1 << 3) { PORTD |= _BV(PD6); } else { PORTD &= ~_BV(PD6); }

// LED4 if (seq[i].bstate & 1 << 4) { PORTD |= _BV(PD7); } else { PORTD &= ~_BV(PD7); }

wait(seq[i].dur); }

PORTC &= ~_BV(PC4); PORTD &= ~_BV(PD3) & ~_BV(PD6) & ~_BV(PD7); wait(300);

} }


int main(void) { DDRC |= _BV(PC4); DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7); // all LEDs are output

DDRC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC3); // S[1..4] are input PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3); // use pullup for S[1..4]

// wait for pullops to "settle down" wait(1000);

while (1) { record(); play(); } }</source>

2. Abend

Änderungen des IR-Signals werden aufgezeichnet, und auch zeitlich ausgewertet. Messung ist jedoch relativ ungenau. Implementation von Timer / Counter fehlt.

<source lang ="c"> /* ################################### */ /* # IR-Empfang # */ /* # Von Gruppe 1 # */ /* ################################### */ /* # Done: IR-Signale chronologisch # */ /* # aufzeichnen # */ /* ################################### */ /* # Todo: Counter / Timer einbauen # */ /* ################################### */


  1. include <avr/io.h>
  2. include <string.h>
  3. include <stdio.h>
  4. include <avr/pgmspace.h>
  5. include <util/delay.h>
  6. include "uart.h"

int main(void) { int status = 0; int counter = 0;

   /* initialize serial uart */
   uart_init();
   /* configure irrx as input */
   DDRC &= ~_BV(PC3);
   /* init led pin as output */
   DDRD |= _BV(PD3);
   while(1) {
   	counter++;
   	for (int i = 0; i<10; i++)
   	{
   		_delay_us(10);

}

       /* if ir rx is high, turn off led */
       if (PINC & _BV(PC3)) {
       	// Kein IR
           PORTD &= ~_BV(PD3);
           if (status == 1)
           {
           	uart_printf("Ir jetzt aus %u\n",counter);
           	counter = 0;
           }
           status = 0;
           
       } else {
           PORTD |= _BV(PD3);
            if (status == 0)
           {
           	uart_printf("Ir jetzt an %u\n",counter);
           	counter = 0;
           }
           status = 1;
       }
   }

} </source>

3. Abend

IR-Jammer

Sendet, sobald er IR empfängt, für 1000ms und wartet dann 5ms, damit er das ausgesandte Signal nicht wieder empfängt.

<source lang="c">

  1. include <avr/io.h>
  2. include <avr/interrupt.h>
  3. include <util/delay.h>
  4. include "uart.h"

/* constants */

  1. define MAX 160

/* 38khz: freq = F_CPU/(2*prescaler*frequency)

* 20mhz/(2*8*38khz) = ~33
* real frequency: 20mhz/(2*8*33) = ~37878Hz */
  1. define PWM_FREQ 33

/* global variables */

/* allocate 160*2 = 320 byte memory for storing a code,

* this means we can store 80 on/off sequence timings */

volatile uint16_t code[MAX]; /* current index in code[] (default: 0) */ volatile uint8_t pos = 0; /* current pin state (default: high == idle) */ volatile uint8_t state = 1; /* signal for the main application that a code has been received

* (default: 0) */

volatile uint8_t done = 0; /* signal button presses from interrupt to main */ volatile uint8_t button_press; /* current system mode */ enum {

   MODE_OFF = 0,
   MODE_DISPLAY = 1,
   MODE_JAM = 2,
   MODE_RECORD = 3,

} mode = MODE_DISPLAY; /* current viewmode */ enum {

   VIEW_VALUE_AND_TIME = 0,
   VIEW_VALUE = 1,
   VIEW_TIME = 2,

} view = VIEW_VALUE_AND_TIME;

/* call every 10 ms, for buttons at pins PC0-PC3 */ static uint8_t button_sample(void) {

   /* initialize state, buttons are active low! */
   static uint8_t btn_state = 15; //0b1111;
   /* initialize old sample */
   static uint8_t last_sample = 15; //0b1111;
   /* read inputs */
   uint8_t new_sample = PINC & 15; //0b1111;
   /* mark bits which are sampled with the same value */
   uint8_t same_sample = (last_sample ^ ~new_sample);
   /* all bits set in same_sample now have been sampled with the same value
    * at least two times, which means the button has settled */
   /* compare the current button state with the most recent sampled value,
    * but only for those bits which have stayed the same */
   uint8_t state_different = btn_state ^ (new_sample & same_sample);
   /* all bits set in state_different have been sampled at least two times
    * with the same value, and this value is different from the current
    * button state */
   /* if a bit is set in state (means: button is not pressed) AND bit is set
    * in state_different (means: input has settled and value is different
    * from state) together means: button has been pressed recently */
   uint8_t btn_press = btn_state & state_different;
   /* toggle all bits for inputs which switched state */
   btn_state ^= state_different;
   /* store current sample for next time */
   last_sample = new_sample;
   /* if bit is set in btn_press, a button has been pressed
    * (not released yet) */
   return btn_press;

}

void wait(uint32_t s) { uint32_t i; for (i = 0; i < s; i++) { _delay_ms(1); } }

/* set up timer 0 to generate a carrier using pwm at freq on pin OC0B (PD5) */ static void ir_enable(uint8_t freq) {

   /* timer 0: fast pwm mode, clear OC0B on match, prescaler 8 */
   TCCR0A = _BV(WGM00) | _BV(COM0B1);
   TCCR0B = _BV(CS01) | _BV(WGM02);
   /* set frequency */
   OCR0A = freq;
   /* set duty-cycle to 50% */
   OCR0B = freq/2;

}

/* disable timer 0 and pwm generation */ static void ir_disable(void) {

   TCCR0A = 0;
   TCCR0B = 0;

}


/* pin change interrupt 1 service function */ ISR(PCINT1_vect) {

   /* do nothing if we are just processing a code in the main loop,
    * or no more space is available for a timer value */
   if (done || pos == MAX)
       return;
   /* if this would be the first timing value ever recorded, and the
    * state before was high (=idle), do not record the timing value
    * and just reset the timer */
   if (state && pos == 0) {
       TCNT1 = 0;
   /* else record the timing value */
   } else {
       /* store current timer value in code[]
        * and reset the timer */
       code[pos++] = TCNT1;
       TCNT1 = 0;
   }
   /* toggle second led */
   PORTD ^= _BV(PD3);
   /* toggle state */
   state = !state;

}

/* timer 1 compare A interrupt service function */ ISR(TIMER1_COMPA_vect) {

   /* do nothing if we are just processing a code in the main loop */
   if (done)
       return;
   /* if some code has been received */
   if (pos > 0) {
       /* if pos is odd, one last 'off'-timing is missing, fill with zero */
       if (pos % 2 == 1)
           code[pos++] = 0;
       /* signal main */
       done = 1;
       /* turn on third led */
       PORTD |= _BV(PD6);
   }

}

/* timer 2 compare A interrupt service function */ ISR(TIMER2_COMPA_vect) {

   /* sample buttons every 10ms */
   button_press |= button_sample();

}

int main(void) {

   /* initialize uart */
   uart_init();
   uart_printf("rumpus ir analyzer\n");
   /* configure led pins as outputs and turn leds off */
   DDRC |= _BV(PC4);
   DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
   PORTC &= ~_BV(PC4);
   PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
   /* configure ir input pin, with pullup */
   DDRC &= ~_BV(PC3);
   PORTC |= _BV(PC3);
   /* configure button input pins, with pullup */
   DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
   PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
   /* configure ir send pin as output, set low */
   DDRD |= _BV(PD5);
   PORTD &= ~_BV(PD5);
   /* wait until pin is high (no ir carrier is detected) */
   while(!(PINC & _BV(PC3)));
   /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
   PCMSK1 |= _BV(PCINT11);
   PCICR |= _BV(PCIE1);
   /* configure timer1 with prescaler 64 and CTC for measuring ir timings */
   TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12);
   /* configure timer action after 200ms: 20mhz/64/5 */
   OCR1A = F_CPU/5/64;
   /* enable OCR1A interrupt */
   TIMSK1 = _BV(OCIE1A);
   /* configure timer 2 with prescaler 1024 and CTC
    * for button sampling */
   TCCR2A = _BV(WGM21);
   TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
   /* configure compare event a to occur after 10ms and enable interrupt */
   OCR2A = F_CPU/1024/100;
   TIMSK2 = _BV(OCIE2A);
   /* signal user availability by turning on led 1 */
   PORTC |= _BV(PC4);
   /* enable interrupts */
   sei();
   /* signal the user that the analyzer part has started by turning led 1 on */
   PORTC |= _BV(PC3);
   while(1) {
       /* if a code has been received */
       if (mode == MODE_DISPLAY && done) {
           /* print code to serial uart */
           uart_printf("complete code received, %u on-off-timings:\n", pos/2);
           for (uint8_t i = 0; i < pos; i += 2) {
               if (view == VIEW_VALUE_AND_TIME) {
                   uint32_t on, off;
                   /* compute timing in microseconds */
                   on = ((uint32_t)code[i]) * 64 / 20;
                   off = ((uint32_t)code[i+1]) * 64 / 20;
                   uart_printf("  %5lu us (%5u) on, %5lu us (%5u) off\n",
                           on, code[i],
                           off, code[i+1]);
               } else if (view == VIEW_VALUE) {
                   uart_printf("  %5u on, %5u off\n",
                           code[i], code[i+1]);
               } else if (view == VIEW_TIME) {
                   uint32_t on, off;
                   /* compute timing in microseconds */
                   on = ((uint32_t)code[i]) * 64 / 20;
                   off = ((uint32_t)code[i+1]) * 64 / 20;
                   uart_printf("  %5lu us on, %5lu us off\n",
                           on, off);
               }
           }


           /* turn off second and third led */
           PORTD &= ~(_BV(PD3) | _BV(PD6));
           /* wait until pin is high (no ir carrier is detected) */
           while(!(PINC & _BV(PC3)));
           /* reset all global variables */
           pos = 0;
           state = 1;
           done = 0;
       }

if (mode == MODE_JAM) { // hier wird gejammt!

if (!state) { DDRC |= _BV(PC3); // ir empfang aus

ir_enable(PWM_FREQ); wait(1000); ir_disable();

wait(5); // damit wir unser eben gesendetes signal nicht empfangen DDRC &= ~_BV(PC3); // ir empfang an

done = 0; pos = 0; } }

       if (button_press) {
           /* first button toggles system mode */
           if (button_press & 1) {
               mode++;
               if (mode > MODE_RECORD)
                   mode = MODE_OFF;
               if (mode == MODE_OFF) {
                   uart_printf("ir analyzer switched off\n");
                   /* disable timer1 and pin change interrupts */
                   TIMSK1 &= ~_BV(OCIE1A);
                   PCMSK1 &= ~_BV(PCINT11);
                   /* turn off led1 */
                   PORTC &= ~_BV(PC4);
               } else if (mode == MODE_DISPLAY) {
                   uart_printf("scan and display codes\n");
                   /* clear interrupt flags, enable timer1 and pin change interrupts */
                   TIFR1 = _BV(OCIE1A);
                   TIMSK1 |= _BV(OCIE1A);
                   PCMSK1 |= _BV(PCINT11);
                   /* turn on led1 */
                   PORTC |= _BV(PC4);
               } else if (mode == MODE_JAM) {
                   /* clear interrupt flags, enable timer1 and pin change interrupts */
                   TIFR1 = _BV(OCIE1A);
                   TIMSK1 |= _BV(OCIE1A);
                   PCMSK1 |= _BV(PCINT11);
                   uart_printf("jamming mode active\n");
               } else if (mode == MODE_RECORD) {
                   uart_printf("record and replay a code\n");
               }
           }


           /* second button toggles view mode */
           if (button_press & 2) {
               view++;
               if (view > VIEW_TIME)
                   view = VIEW_VALUE_AND_TIME;
               if (view == VIEW_VALUE_AND_TIME)
                   uart_printf("display timer value and time (in us)\n");
               else if (view == VIEW_VALUE)
                   uart_printf("display timer value\n");
               else if (view == VIEW_TIME)
                   uart_printf("display time (in us)\n");
           }
           if (button_press & 4) {
               static uint8_t pwm = 0;
               if (!pwm) {
                   ir_enable(PWM_FREQ);
                   uart_printf("pwm on\n");
               } else {
                   ir_disable();
                   uart_printf("pwm off\n");
               }
               pwm = !pwm;
           }
           button_press = 0;
       }
   }

}</source>

4. Abend

IR-Jammer in schlau

Misst die kürzeste Impulsdauer und sendet mit dieser (plus einer kleinen, sich ändernden Verzögerung) in die Pausen.

<source lang="c">#include <avr/io.h>

  1. include <avr/interrupt.h>
  2. include <util/delay.h>
  3. include "uart.h"

/* constants */

  1. define MAX 160

/* 38khz: freq = F_CPU/(2*prescaler*frequency)

* 20mhz/(2*8*38khz) = ~33
* real frequency: 20mhz/(2*8*33) = ~37878Hz */
  1. define PWM_FREQ 33

/* global variables */

/* allocate 160*2 = 320 byte memory for storing a code,

* this means we can store 80 on/off sequence timings */

volatile uint16_t code[MAX]; /* current index in code[] (default: 0) */ volatile uint8_t pos = 0; /* current pin state (default: high == idle) */ volatile uint8_t state = 1; /* signal for the main application that a code has been received

* (default: 0) */

volatile uint8_t done = 0; /* signal button presses from interrupt to main */ volatile uint8_t button_press; /* current system mode */ enum {

   MODE_OFF = 0,
   MODE_DISPLAY = 1,
   MODE_JAM = 2,
   MODE_RECORD = 3,

} mode = MODE_DISPLAY; /* current viewmode */ enum {

   VIEW_VALUE_AND_TIME = 0,
   VIEW_VALUE = 1,
   VIEW_TIME = 2,

} view = VIEW_VALUE_AND_TIME;

/* call every 10 ms, for buttons at pins PC0-PC3 */ static uint8_t button_sample(void) {

   /* initialize state, buttons are active low! */
   static uint8_t btn_state = 15; //0b1111;
   /* initialize old sample */
   static uint8_t last_sample = 15; //0b1111;
   /* read inputs */
   uint8_t new_sample = PINC & 15; //0b1111;
   /* mark bits which are sampled with the same value */
   uint8_t same_sample = (last_sample ^ ~new_sample);
   /* all bits set in same_sample now have been sampled with the same value
    * at least two times, which means the button has settled */
   /* compare the current button state with the most recent sampled value,
    * but only for those bits which have stayed the same */
   uint8_t state_different = btn_state ^ (new_sample & same_sample);
   /* all bits set in state_different have been sampled at least two times
    * with the same value, and this value is different from the current
    * button state */
   /* if a bit is set in state (means: button is not pressed) AND bit is set
    * in state_different (means: input has settled and value is different
    * from state) together means: button has been pressed recently */
   uint8_t btn_press = btn_state & state_different;
   /* toggle all bits for inputs which switched state */
   btn_state ^= state_different;
   /* store current sample for next time */
   last_sample = new_sample;
   /* if bit is set in btn_press, a button has been pressed
    * (not released yet) */
   return btn_press;

}

static void wait(uint32_t s) { uint32_t i; for (i = 0; i < s; i++) { _delay_us(1); } }

/* set up timer 0 to generate a carrier using pwm at freq on pin OC0B (PD5) */ static void ir_enable(uint8_t freq) {

   /* timer 0: fast pwm mode, clear OC0B on match, prescaler 8 */
   TCCR0A = _BV(WGM00) | _BV(COM0B1);
   TCCR0B = _BV(CS01) | _BV(WGM02);
   /* set frequency */
   OCR0A = freq;
   /* set duty-cycle to 50% */
   OCR0B = freq/2;

}

/* disable timer 0 and pwm generation */ static void ir_disable(void) {

   TCCR0A = 0;
   TCCR0B = 0;

}

static void jam(void) { static uint32_t dur; static uint16_t i; uint8_t j = 0; uint32_t dur_tmp;

if (pos == 0 || done) { dur = 0xFFFFFFFF; }

if (i % 500 == 0) { i=0; if (!state) { uart_printf("-"); } else { uart_printf("."); } } i++;


if (pos < 1) { return; }

// shortest measured duration dur_tmp = ((uint32_t)code[pos-1]) * 64 / 20; dur = dur_tmp < dur ? dur_tmp : dur;

while (!state && j < 10) { j++; DDRC |= _BV(PC3); // ir reciever off

ir_enable(PWM_FREQ); uart_printf("*"); wait(dur+i); ir_disable();

wait(250); // we don't want to recieve our own signal (due to lags in the ir receiver) DDRC &= ~_BV(PC3); // ir reciever on } }

/* pin change interrupt 1 service function */ ISR(PCINT1_vect) {

   /* do nothing if we are just processing a code in the main loop,
    * or no more space is available for a timer value */
   if (done || pos == MAX)
       return;
   /* if this would be the first timing value ever recorded, and the
    * state before was high (=idle), do not record the timing value
    * and just reset the timer */
   if (state && pos == 0) {
       TCNT1 = 0;
   /* else record the timing value */
   } else {
       /* store current timer value in code[]
        * and reset the timer */
       code[pos++] = TCNT1;
       TCNT1 = 0;
   }
   /* toggle second led */
   PORTD ^= _BV(PD3);
   /* toggle state */
   state = !state;

}

/* timer 1 compare A interrupt service function */ ISR(TIMER1_COMPA_vect) {

   /* do nothing if we are just processing a code in the main loop */
   if (done)
       return;
   /* if some code has been received */
   if (pos > 0) {
       /* if pos is odd, one last 'off'-timing is missing, fill with zero */
       if (pos % 2 == 1)
           code[pos++] = 0;
       /* signal main */
       done = 1;
       /* turn on third led */
       PORTD |= _BV(PD6);
   }

}

/* timer 2 compare A interrupt service function */ ISR(TIMER2_COMPA_vect) {

   /* sample buttons every 10ms */
   button_press |= button_sample();

}

int main(void) {

   /* initialize uart */
   uart_init();
   uart_printf("rumpus ir analyzer\n");
   /* configure led pins as outputs and turn leds off */
   DDRC |= _BV(PC4);
   DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
   PORTC &= ~_BV(PC4);
   PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
   /* configure ir input pin, with pullup */
   DDRC &= ~_BV(PC3);
   PORTC |= _BV(PC3);
   /* configure button input pins, with pullup */
   DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
   PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
   /* configure ir send pin as output, set low */
   DDRD |= _BV(PD5);
   PORTD &= ~_BV(PD5);
   /* wait until pin is high (no ir carrier is detected) */
   while(!(PINC & _BV(PC3)));
   /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
   PCMSK1 |= _BV(PCINT11);
   PCICR |= _BV(PCIE1);
   /* configure timer1 with prescaler 64 and CTC for measuring ir timings */
   TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12);
   /* configure timer action after 200ms: 20mhz/64/5 */
   OCR1A = F_CPU/5/64;
   /* enable OCR1A interrupt */
   TIMSK1 = _BV(OCIE1A);
   /* configure timer 2 with prescaler 1024 and CTC
    * for button sampling */
   TCCR2A = _BV(WGM21);
   TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
   /* configure compare event a to occur after 10ms and enable interrupt */
   OCR2A = F_CPU/1024/100;
   TIMSK2 = _BV(OCIE2A);
   /* signal user availability by turning on led 1 */
   PORTC |= _BV(PC4);
   /* enable interrupts */
   sei();
   /* signal the user that the analyzer part has started by turning led 1 on */
   PORTC |= _BV(PC3);
   while(1) {
       /* if a code has been received */
       if (mode == MODE_DISPLAY && done) {
           /* print code to serial uart */
           uart_printf("complete code received, %u on-off-timings:\n", pos/2);
           for (uint8_t i = 0; i < pos; i += 2) {
               if (view == VIEW_VALUE_AND_TIME) {
                   uint32_t on, off;
                   /* compute timing in microseconds */
                   on = ((uint32_t)code[i]) * 64 / 20;
                   off = ((uint32_t)code[i+1]) * 64 / 20;
                   uart_printf("  %5lu us (%5u) on, %5lu us (%5u) off\n",
                           on, code[i],
                           off, code[i+1]);
               } else if (view == VIEW_VALUE) {
                   uart_printf("  %5u on, %5u off\n",
                           code[i], code[i+1]);
               } else if (view == VIEW_TIME) {
                   uint32_t on, off;
                   /* compute timing in microseconds */
                   on = ((uint32_t)code[i]) * 64 / 20;
                   off = ((uint32_t)code[i+1]) * 64 / 20;
                   uart_printf("  %5lu us on, %5lu us off\n",
                           on, off);
               }
           }


           /* turn off second and third led */
           PORTD &= ~(_BV(PD3) | _BV(PD6));
           /* wait until pin is high (no ir carrier is detected) */
           while(!(PINC & _BV(PC3)));
           /* reset all global variables */
           pos = 0;
           state = 1;
           done = 0;
       }

if (mode == MODE_JAM) { jam(); }

if (done) { // code completely detected

           /* reset all global variables */
           pos = 0;
           state = 1;
           done = 0;

}

if (button_press) { /* first button toggles system mode */ if (button_press & 1) { mode++; if (mode > MODE_RECORD) mode = MODE_OFF;

if (mode == MODE_OFF) { uart_printf("ir analyzer switched off\n");

/* disable timer1 and pin change interrupts */ TIMSK1 &= ~_BV(OCIE1A); PCMSK1 &= ~_BV(PCINT11);

/* turn off led1 */ PORTC &= ~_BV(PC4);

} else if (mode == MODE_DISPLAY) { uart_printf("scan and display codes\n");

/* clear interrupt flags, enable timer1 and pin change interrupts */ TIFR1 = _BV(OCIE1A); TIMSK1 |= _BV(OCIE1A); PCMSK1 |= _BV(PCINT11);

/* turn on led1 */ PORTC |= _BV(PC4); } else if (mode == MODE_JAM) { /* clear interrupt flags, enable timer1 and pin change interrupts */ TIFR1 = _BV(OCIE1A); TIMSK1 |= _BV(OCIE1A); PCMSK1 |= _BV(PCINT11);

uart_printf("jamming mode active\n"); } else if (mode == MODE_RECORD) { uart_printf("record and replay a code\n"); } }


/* second button toggles view mode */ if (button_press & 2) { view++; if (view > VIEW_TIME) view = VIEW_VALUE_AND_TIME;

if (view == VIEW_VALUE_AND_TIME) uart_printf("display timer value and time (in us)\n"); else if (view == VIEW_VALUE) uart_printf("display timer value\n"); else if (view == VIEW_TIME) uart_printf("display time (in us)\n"); }

if (button_press & 4) { static uint8_t pwm = 0;

if (!pwm) { ir_enable(PWM_FREQ); uart_printf("pwm on\n"); } else { ir_disable(); uart_printf("pwm off\n"); } pwm = !pwm; }

button_press = 0; } } }</source>

Eigener Chat

Hier wird die neue uart.c benutzt (die mit Senden und Empfangen). Leider funktioniert der Chat dann nicht mehr, vermutlich kommt der neue uart-Interrupt der wait-Funktion in die Query. Wenn man die alte uart.c benutzt kann man sich wunderbar über die 4 Taster unterhalten :) Hendi

<source lang="c">#include <avr/io.h>

  1. include <avr/interrupt.h>
  2. include <util/delay.h>
  3. include "uart.h"

/* constants */

  1. define MAX 160

/* 38khz: freq = F_CPU/(2*prescaler*frequency)

* 20mhz/(2*8*38khz) = ~33
* real frequency: 20mhz/(2*8*33) = ~37878Hz */
  1. define PWM_FREQ 33

/* global variables */

/* allocate 160*2 = 320 byte memory for storing a code,

* this means we can store 80 on/off sequence timings */

volatile uint16_t code[MAX]; /* current index in code[] (default: 0) */ volatile uint8_t pos = 0; /* current pin state (default: high == idle) */ volatile uint8_t state = 1; /* signal for the main application that a code has been received

* (default: 0) */

volatile uint8_t done = 0; /* signal button presses from interrupt to main */ volatile uint8_t button_press; /* current system mode */ enum {

   MODE_OFF = 0,
   MODE_DISPLAY = 1,
   MODE_JAM = 2,
   MODE_RECORD = 3,

} mode = MODE_DISPLAY; /* current viewmode */ enum {

   VIEW_VALUE_AND_TIME = 0,
   VIEW_VALUE = 1,
   VIEW_TIME = 2,

} view = VIEW_VALUE_AND_TIME;

/* call every 10 ms, for buttons at pins PC0-PC3 */ static uint8_t button_sample(void) {

   /* initialize state, buttons are active low! */
   static uint8_t btn_state = 15; //0b1111;
   /* initialize old sample */
   static uint8_t last_sample = 15; //0b1111;
   /* read inputs */
   uint8_t new_sample = PINC & 15; //0b1111;

   /* mark bits which are sampled with the same value */
   uint8_t same_sample = (last_sample ^ ~new_sample);
   /* all bits set in same_sample now have been sampled with the same value
    * at least two times, which means the button has settled */

   /* compare the current button state with the most recent sampled value,
    * but only for those bits which have stayed the same */
   uint8_t state_different = btn_state ^ (new_sample & same_sample);
   /* all bits set in state_different have been sampled at least two times
    * with the same value, and this value is different from the current
    * button state */

   /* if a bit is set in state (means: button is not pressed) AND bit is set
    * in state_different (means: input has settled and value is different
    * from state) together means: button has been pressed recently */
   uint8_t btn_press = btn_state & state_different;

   /* toggle all bits for inputs which switched state */
   btn_state ^= state_different;

   /* store current sample for next time */
   last_sample = new_sample;

   /* if bit is set in btn_press, a button has been pressed
    * (not released yet) */
   return btn_press;

}

static void wait(uint32_t s) { uint32_t i; s /= 100; s *= 2.75; for (i = 0; i < s; i++) { _delay_us(100); } }

/* set up timer 0 to generate a carrier using pwm at freq on pin OC0B (PD5) */ static void ir_enable(uint8_t freq) {

   /* timer 0: fast pwm mode, clear OC0B on match, prescaler 8 */
   TCCR0A = _BV(WGM00) | _BV(COM0B1);
   TCCR0B = _BV(CS01) | _BV(WGM02);

   /* set frequency */
   OCR0A = freq;

   /* set duty-cycle to 1/4 */
   OCR0B = freq/4;

}

/* disable timer 0 and pwm generation */ static void ir_disable(void) {

   TCCR0A = 0;
   TCCR0B = 0;

}


/* pin change interrupt 1 service function */ ISR(PCINT1_vect) {

   /* do nothing if we are just processing a code in the main loop,
    * or no more space is available for a timer value */
   if (done || pos == MAX)
       return;

   /* if this would be the first timing value ever recorded, and the
    * state before was high (=idle), do not record the timing value
    * and just reset the timer */
   if (state && pos == 0) {
       TCNT1 = 0;
   /* else record the timing value */
   } else {
       /* store current timer value in code[]
        * and reset the timer */
       code[pos++] = TCNT1;
       TCNT1 = 0;
   }

   /* toggle second led */
   PORTD ^= _BV(PD3);

   /* toggle state */
   state = !state;

}

/* timer 1 compare A interrupt service function */ ISR(TIMER1_COMPA_vect) {

   /* do nothing if we are just processing a code in the main loop */
   if (done)
       return;

   /* if some code has been received */
   if (pos > 0) {
       /* if pos is odd, one last 'off'-timing is missing, fill with zero */
       if (pos % 2 == 1)
           code[pos++] = 0;

       /* signal main */
       done = 1;

       /* turn on third led */
       PORTD |= _BV(PD6);
   }

}

/* timer 2 compare A interrupt service function */ ISR(TIMER2_COMPA_vect) {

   /* sample buttons every 10ms */
   button_press |= button_sample();

}

// NEC protocol, see http://www.sbprojects.com/knowledge/ir/nec.htm static void send1(void) { // uart_printf("1"); ir_enable(PWM_FREQ); wait(560); ir_disable(); wait(560); wait(560); }

static void send0(void) { // uart_printf("0"); ir_enable(PWM_FREQ); wait(560); ir_disable(); wait(560); }

static void send(uint8_t msg[]) { uint8_t sendcode;

while(!(PINC & _BV(PC3)));

// say hello ir_enable(PWM_FREQ); wait(9000); ir_disable(); wait(4500);

for (uint8_t z=0; z<100; z++) { if (msg[z] == '\r') { z=100; }

sendcode = msg[z];

// send data

   	for (uint8_t i=0; i<8; i++) {
   		if (sendcode & (1 << i)) {
   			send1();
   		} else {
   			send0();
   		}
   	}

}

// enable IR, so we know how long it was off ir_enable(PWM_FREQ); wait(560); ir_disable(); wait(560); }

static void receive(void) {

   uint8_t rcv;

//uart_printf("-- %d --\n", pos); while(!(PINC & _BV(PC3)));

   // transform time to ms
   for (uint8_t i = 0; i < pos; i++) {
       code[i] *= 64 / 20;
   }

   // receive hello
   if (code[0] < 8500 || code[0] > 9500
   	|| code[1] < 4000 || code[1] > 5000
   	|| pos < 10
   ) {
       // no nec hello found

uart_printf("no nec\n"); // return; }

   // receive msg

for (uint8_t j=0; j<pos/8; j++) {

   	for (uint8_t i=0; i<8; i++) {

uart_printf("%d - ", code[16*j + 2*i + 2]); uart_printf("%d", code[16*j + 2*i + 3]); //uart_printf(" ----- ");

           if (!(code[16*j + 2*i + 2] > 400 && code[16*j + 2*i + 2] < 800)) {
               // bit doesn't start with ON

rcv = ' '; //uart_printf(" off FAIL (%d)\n", code[16*j + 2*i +2]);

i=8; continue; // go to next byte

           }

           if (code[16*j + 2*i + 3] > 400 && code[16*j + 2*i + 3] < 800) {
               // bit is 0
               rcv &= ~(1 << i);
           } else if (code[16*j + 2*i + 3] > 900 && code[16*j + 2*i + 3] < 1300) {
               // bit is 1
               rcv |= 1 << i;
           } else {
               // not sure which value we have

rcv = ' '; //uart_printf(" FAIL (%d)\n", code[16*j + 2*i + 3]);

i=8; continue; // go to next byte

           }
   	}

uart_printf("%c", rcv); if (rcv == '\r') { j=pos/8; } uart_printf("\n");

   }

}

int main(void) {

   /* initialize uart */
   uart_init();
   uart_printf("rumpus ir chat\n");

   /* configure led pins as outputs and turn leds off */
   DDRC |= _BV(PC4);
   DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
   PORTC &= ~_BV(PC4);
   PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));

   /* configure ir input pin, with pullup */
   DDRC &= ~_BV(PC3);
   PORTC |= _BV(PC3);

   /* configure button input pins, with pullup */
   DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
   PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);

   /* configure ir send pin as output, set low */
   DDRD |= _BV(PD5);
   PORTD &= ~_BV(PD5);

   /* wait until pin is high (no ir carrier is detected) */
   while(!(PINC & _BV(PC3)));

   /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
   PCMSK1 |= _BV(PCINT11);
   PCICR |= _BV(PCIE1);

   /* configure timer1 with prescaler 64 and CTC for measuring ir timings */
   TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12);
   /* configure timer action after 200ms: 20mhz/64/5 */
   OCR1A = F_CPU/5/64;
   /* enable OCR1A interrupt */
   TIMSK1 = _BV(OCIE1A);

   /* configure timer 2 with prescaler 1024 and CTC
    * for button sampling */
   TCCR2A = _BV(WGM21);
   TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
   /* configure compare event a to occur after 10ms and enable interrupt */
   OCR2A = F_CPU/1024/100;
   TIMSK2 = _BV(OCIE2A);

   /* signal user availability by turning on led 1 */
   PORTC |= _BV(PC4);

   /* enable interrupts */
   sei();

   /* signal the user that the analyzer part has started by turning led 1 on */
   PORTC |= _BV(PC3);

   while(1) {

       /* if a code has been received */
       if (done) {
           	receive();

uart_printf("\n");

               /* turn off second and third led */
               PORTD &= ~(_BV(PD3) | _BV(PD6));

               /* wait until pin is high (no ir carrier is detected) */
               while(!(PINC & _BV(PC3)));

               /* reset all global variables */
               pos = 0;
               state = 1;
               done = 0;
       }

		if (uart_done == 1) {

send(uart_input); uart_len = 0; uart_done = 0; }

if (button_press) { /* first button toggles system mode */ uint8_t msg[7] = "Hallo!\r"; // SENDE if (button_press & (1 << 0)) { send(msg); } else if (button_press & (1 << 1)) { send(("Gruppe 1\r")); // 0b101 } else if (button_press & (1 << 2)) { send("1234567890\r"); // 0b10001 } else if (button_press & (1 << 3)) { send("XY\r"); }


button_press = 0; } } } </source>