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

From C4 Wiki
Jump to: navigation, search
(Eigener Chat (Test))
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<br />
+
* Mark&lt;br />
* Christoph<br />
+
* Christoph&lt;br />
* Hendrik<br />
+
* Hendrik&lt;br />
* Robert<br />
+
* Robert&lt;br />
  
 
= Code =
 
= Code =
Line 11: Line 19:
 
: Aufgabe: Eine LED soll zum blinken gebracht werden.
 
: Aufgabe: Eine LED soll zum blinken gebracht werden.
 
: Code:
 
: Code:
<source lang ="c">
+
&lt;source lang ="c">
 
//****************************************************************************
 
//****************************************************************************
 
// *  
 
// *  
Line 21: Line 29:
 
//****************************************************************************
 
//****************************************************************************
  
#include <avr/io.h>
+
#include &lt;avr/io.h>
#include <util/delay.h>
+
#include &lt;util/delay.h>
  
 
int main(void)
 
int main(void)
Line 45: Line 53:
 
     /* _delay_ms() delays for 10 Milliseconds */
 
     /* _delay_ms() delays for 10 Milliseconds */
 
     /* 50 * 10ms = 500ms */
 
     /* 50 * 10ms = 500ms */
     for (uint8_t i=0;i<50;i++) _delay_ms(10);
+
     for (uint8_t i=0;i&lt;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 56: Line 64:
  
  
</source>
+
&lt;/source>
<br />
+
&lt;br />
  
 
=== LED - Einschalten ===
 
=== LED - Einschalten ===
 
: Aufgabe: Eine LED soll zum leuchten gebracht werden.
 
: Aufgabe: Eine LED soll zum leuchten gebracht werden.
 
: Code:
 
: Code:
<source lang ="c">
+
&lt;source lang ="c">
 
//****************************************************************************
 
//****************************************************************************
 
// *  
 
// *  
Line 70: Line 78:
 
//****************************************************************************
 
//****************************************************************************
  
#include <avr/io.h>
+
#include &lt;avr/io.h>
  
 
int main(void)
 
int main(void)
 
{
 
{
 
   /* PC4 auf Ausgang */
 
   /* PC4 auf Ausgang */
   DDRC = &b10000;  /* Alternativ Hex: 0xF oder Dezimal: 16 */
+
   DDRC = &amp;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 = &b10000;
+
   PORTD = &amp;b10000;
  
 
   /* Endlosschleife */
 
   /* Endlosschleife */
Line 88: Line 96:
 
}
 
}
  
</source>
+
&lt;/source>
 
=== LED - Lauflicht ===
 
=== LED - Lauflicht ===
 
: Code:
 
: Code:
<source lang ="c">
+
&lt;source lang ="c">
 
//****************************************************************************
 
//****************************************************************************
 
// *  
 
// *  
Line 98: Line 106:
 
//****************************************************************************
 
//****************************************************************************
  
#include <avr/io.h>
+
#include &lt;avr/io.h>
#include <util/delay.h>
+
#include &lt;util/delay.h>
  
 
int main(void)
 
int main(void)
Line 106: Line 114:
  
 
/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */
 
/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */
DDRC = (1<<DDC4);
+
DDRC = (1&lt;&lt;DDC4);
DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD3);
+
DDRD = (1&lt;&lt;DDD7)|(1&lt;&lt;DDD6)|(1&lt;&lt;DDD3);
 
/* Setze Ports PC4, PD3, PD6 und PD7 auf low */
 
/* Setze Ports PC4, PD3, PD6 und PD7 auf low */
PORTC = (0<<PC4);
+
PORTC = (0&lt;&lt;PC4);
PORTD = (0<<PD7)|(0<<PD6)|(0<<PD3);
+
PORTD = (0&lt;&lt;PD7)|(0&lt;&lt;PD6)|(0&lt;&lt;PD3);
  
 
while(1)
 
while(1)
 
{
 
{
 
  PORTC ^= _BV(PC4);
 
  PORTC ^= _BV(PC4);
  for (i=0;i<50;i++) _delay_loop_2(0);
+
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
 
  PORTC ^= _BV(PC4);
 
  PORTC ^= _BV(PC4);
 
  PORTD ^= _BV(PD3);
 
  PORTD ^= _BV(PD3);
  for (i=0;i<50;i++) _delay_loop_2(0);
+
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
 
  PORTD ^= _BV(PD3);
 
  PORTD ^= _BV(PD3);
 
  PORTD ^= _BV(PD6);
 
  PORTD ^= _BV(PD6);
  for (i=0;i<50;i++) _delay_loop_2(0);
+
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
 
  PORTD ^= _BV(PD6);
 
  PORTD ^= _BV(PD6);
 
  PORTD ^= _BV(PD7);
 
  PORTD ^= _BV(PD7);
  for (i=0;i<50;i++) _delay_loop_2(0);
+
  for (i=0;i&lt;50;i++) _delay_loop_2(0);
 
  PORTD ^= _BV(PD7);
 
  PORTD ^= _BV(PD7);
  
Line 130: Line 138:
 
return 0;
 
return 0;
 
}
 
}
</source>
+
&lt;/source>
  
 
=== Blinksequenz aufzeichnen und später abspielen ===
 
=== Blinksequenz aufzeichnen und später abspielen ===
<source lang="c">#include <avr/io.h>
+
&lt;source lang="c">#include &lt;avr/io.h>
#include <util/delay.h>
+
#include &lt;util/delay.h>
  
 
#define SEQS 100
 
#define SEQS 100
Line 153: Line 161:
 
   uint32_t i;
 
   uint32_t i;
  
for (i = 0; i < ms; i++) {
+
for (i = 0; i &lt; ms; i++) {
 
_delay_ms(1);
 
_delay_ms(1);
 
}
 
}
Line 168: Line 176:
  
 
// S1
 
// S1
if (~PINC & _BV(PC0)) {
+
if (~PINC &amp; _BV(PC0)) {
bstate |= 1 << 1;
+
bstate |= 1 &lt;&lt; 1;
 
}
 
}
  
 
// S2
 
// S2
if (~PINC & _BV(PC1)) {
+
if (~PINC &amp; _BV(PC1)) {
bstate |= 1 << 2;
+
bstate |= 1 &lt;&lt; 2;
 
}
 
}
  
 
// S3
 
// S3
if (~PINC & _BV(PC2)) {
+
if (~PINC &amp; _BV(PC2)) {
bstate |= 1 << 3;
+
bstate |= 1 &lt;&lt; 3;
 
}
 
}
  
 
// S4
 
// S4
if (~PINC & _BV(PC3)) {
+
if (~PINC &amp; _BV(PC3)) {
bstate |= 1 << 4;
+
bstate |= 1 &lt;&lt; 4;
 
}
 
}
  
 
// omit first state
 
// omit first state
if (count == 0 && bstate == 0x0) {
+
if (count == 0 &amp;&amp; bstate == 0x0) {
 
continue;
 
continue;
 
}
 
}
Line 205: Line 213:
 
}
 
}
  
if (bstate == 0x0 && count > 0 && dur >= 2000) {
+
if (bstate == 0x0 &amp;&amp; count > 0 &amp;&amp; dur >= 2000) {
 
// no button was pressed for 2s
 
// no button was pressed for 2s
 
return;
 
return;
Line 230: Line 238:
 
// PORTD |= _BV(PD7);
 
// PORTD |= _BV(PD7);
 
 
for (i = 0; i < count; i++) {
+
for (i = 0; i &lt; count; i++) {
 
// LED1
 
// LED1
if (seq[i].bstate & 1 << 1) {
+
if (seq[i].bstate &amp; 1 &lt;&lt; 1) {
 
PORTC |= _BV(PC4);
 
PORTC |= _BV(PC4);
 
} else {
 
} else {
PORTC &= ~_BV(PC4);
+
PORTC &amp;= ~_BV(PC4);
 
}
 
}
  
 
// LED2
 
// LED2
if (seq[i].bstate & 1 << 2) {
+
if (seq[i].bstate &amp; 1 &lt;&lt; 2) {
 
PORTD |= _BV(PD3);
 
PORTD |= _BV(PD3);
 
} else {
 
} else {
PORTD &= ~_BV(PD3);
+
PORTD &amp;= ~_BV(PD3);
 
}
 
}
  
 
// LED3
 
// LED3
if (seq[i].bstate & 1 << 3) {
+
if (seq[i].bstate &amp; 1 &lt;&lt; 3) {
 
PORTD |= _BV(PD6);
 
PORTD |= _BV(PD6);
 
} else {
 
} else {
PORTD &= ~_BV(PD6);
+
PORTD &amp;= ~_BV(PD6);
 
}
 
}
  
 
// LED4
 
// LED4
if (seq[i].bstate & 1 << 4) {
+
if (seq[i].bstate &amp; 1 &lt;&lt; 4) {
 
PORTD |= _BV(PD7);
 
PORTD |= _BV(PD7);
 
} else {
 
} else {
PORTD &= ~_BV(PD7);
+
PORTD &amp;= ~_BV(PD7);
 
}
 
}
  
Line 262: Line 270:
 
}
 
}
  
PORTC &= ~_BV(PC4);
+
PORTC &amp;= ~_BV(PC4);
PORTD &= ~_BV(PD3) & ~_BV(PD6) & ~_BV(PD7);
+
PORTD &amp;= ~_BV(PD3) &amp; ~_BV(PD6) &amp; ~_BV(PD7);
 
wait(300);
 
wait(300);
  
Line 274: Line 282:
 
DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7); // all LEDs are output
 
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
+
DDRC &amp;= ~_BV(PC0) &amp; ~_BV(PC1) &amp; ~_BV(PC2) &amp; ~_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 284: Line 292:
 
play();
 
play();
 
}
 
}
}</source>
+
}&lt;/source>
  
 
== 2. Abend ==
 
== 2. Abend ==
Line 290: Line 298:
 
Ä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.
  
<source lang ="c">
+
&lt;source lang ="c">
 
/* ###################################  */
 
/* ###################################  */
 
/* #          IR-Empfang            #  */
 
/* #          IR-Empfang            #  */
Line 302: Line 310:
  
  
#include <avr/io.h>
+
#include &lt;avr/io.h>
#include <string.h>
+
#include &lt;string.h>
#include <stdio.h>
+
#include &lt;stdio.h>
#include <avr/pgmspace.h>
+
#include &lt;avr/pgmspace.h>
#include <util/delay.h>
+
#include &lt;util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
  
Line 317: Line 325:
  
 
     /* configure irrx as input */
 
     /* configure irrx as input */
     DDRC &= ~_BV(PC3);
+
     DDRC &amp;= ~_BV(PC3);
  
 
     /* init led pin as output */
 
     /* init led pin as output */
Line 324: Line 332:
 
     while(1) {
 
     while(1) {
 
     counter++;
 
     counter++;
     for (int i = 0; i<10; i++)
+
     for (int i = 0; i&lt;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 & _BV(PC3)) {
+
         if (PINC &amp; _BV(PC3)) {
 
         // Kein IR
 
         // Kein IR
             PORTD &= ~_BV(PD3);
+
             PORTD &amp;= ~_BV(PD3);
 
             if (status == 1)
 
             if (status == 1)
 
             {
 
             {
Line 350: Line 358:
 
     }
 
     }
 
}
 
}
</source>
+
&lt;/source>
  
 
== 3. Abend ==
 
== 3. Abend ==
Line 356: Line 364:
 
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.
  
<source lang="c">
+
&lt;source lang="c">
#include <avr/io.h>
+
#include &lt;avr/io.h>
#include <avr/interrupt.h>
+
#include &lt;avr/interrupt.h>
#include <util/delay.h>
+
#include &lt;util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
  
Line 405: Line 413:
 
     static uint8_t last_sample = 15; //0b1111;
 
     static uint8_t last_sample = 15; //0b1111;
 
     /* read inputs */
 
     /* read inputs */
     uint8_t new_sample = PINC & 15; //0b1111;
+
     uint8_t new_sample = PINC &amp; 15; //0b1111;
  
 
     /* mark bits which are sampled with the same value */
 
     /* mark bits which are sampled with the same value */
Line 414: Line 422:
 
     /* 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 & same_sample);
+
     uint8_t state_different = btn_state ^ (new_sample &amp; 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 422: Line 430:
 
     * 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 & state_different;
+
     uint8_t btn_press = btn_state &amp; state_different;
  
 
     /* toggle all bits for inputs which switched state */
 
     /* toggle all bits for inputs which switched state */
Line 437: Line 445:
 
void wait(uint32_t s) {
 
void wait(uint32_t s) {
 
uint32_t i;
 
uint32_t i;
for (i = 0; i < s; i++) {
+
for (i = 0; i &lt; s; i++) {
 
_delay_ms(1);
 
_delay_ms(1);
 
}
 
}
Line 473: Line 481:
 
     * 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 && pos == 0) {
+
     if (state &amp;&amp; pos == 0) {
 
         TCNT1 = 0;
 
         TCNT1 = 0;
 
     /* else record the timing value */
 
     /* else record the timing value */
Line 527: Line 535:
 
     DDRC |= _BV(PC4);
 
     DDRC |= _BV(PC4);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
     PORTC &= ~_BV(PC4);
+
     PORTC &amp;= ~_BV(PC4);
     PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
+
     PORTD &amp;= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
  
 
     /* configure ir input pin, with pullup */
 
     /* configure ir input pin, with pullup */
     DDRC &= ~_BV(PC3);
+
     DDRC &amp;= ~_BV(PC3);
 
     PORTC |= _BV(PC3);
 
     PORTC |= _BV(PC3);
  
 
     /* configure button input pins, with pullup */
 
     /* configure button input pins, with pullup */
     DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
+
     DDRC &amp;= ~(_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 &= ~_BV(PD5);
+
     PORTD &amp;= ~_BV(PD5);
  
 
     /* wait until pin is high (no ir carrier is detected) */
 
     /* wait until pin is high (no ir carrier is detected) */
     while(!(PINC & _BV(PC3)));
+
     while(!(PINC &amp; _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 575: Line 583:
 
     while(1) {
 
     while(1) {
 
         /* if a code has been received */
 
         /* if a code has been received */
         if (mode == MODE_DISPLAY && done) {
+
         if (mode == MODE_DISPLAY &amp;&amp; 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 < pos; i += 2) {
+
             for (uint8_t i = 0; i &lt; pos; i += 2) {
  
 
                 if (view == VIEW_VALUE_AND_TIME) {
 
                 if (view == VIEW_VALUE_AND_TIME) {
Line 608: Line 616:
  
 
             /* turn off second and third led */
 
             /* turn off second and third led */
             PORTD &= ~(_BV(PD3) | _BV(PD6));
+
             PORTD &amp;= ~(_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 & _BV(PC3)));
+
             while(!(PINC &amp; _BV(PC3)));
  
 
             /* reset all global variables */
 
             /* reset all global variables */
Line 630: Line 638:
  
 
wait(5); // damit wir unser eben gesendetes signal nicht empfangen
 
wait(5); // damit wir unser eben gesendetes signal nicht empfangen
DDRC &= ~_BV(PC3); // ir empfang an
+
DDRC &amp;= ~_BV(PC3); // ir empfang an
 
 
 
done = 0;
 
done = 0;
Line 639: Line 647:
 
         if (button_press) {
 
         if (button_press) {
 
             /* first button toggles system mode */
 
             /* first button toggles system mode */
             if (button_press & 1) {
+
             if (button_press &amp; 1) {
 
                 mode++;
 
                 mode++;
 
                 if (mode > MODE_RECORD)
 
                 if (mode > MODE_RECORD)
Line 648: Line 656:
  
 
                     /* disable timer1 and pin change interrupts */
 
                     /* disable timer1 and pin change interrupts */
                     TIMSK1 &= ~_BV(OCIE1A);
+
                     TIMSK1 &amp;= ~_BV(OCIE1A);
                     PCMSK1 &= ~_BV(PCINT11);
+
                     PCMSK1 &amp;= ~_BV(PCINT11);
  
 
                     /* turn off led1 */
 
                     /* turn off led1 */
                     PORTC &= ~_BV(PC4);
+
                     PORTC &amp;= ~_BV(PC4);
  
 
                 } else if (mode == MODE_DISPLAY) {
 
                 } else if (mode == MODE_DISPLAY) {
Line 678: Line 686:
  
 
             /* second button toggles view mode */
 
             /* second button toggles view mode */
             if (button_press & 2) {
+
             if (button_press &amp; 2) {
 
                 view++;
 
                 view++;
 
                 if (view > VIEW_TIME)
 
                 if (view > VIEW_TIME)
Line 691: Line 699:
 
             }
 
             }
  
             if (button_press & 4) {
+
             if (button_press &amp; 4) {
 
                 static uint8_t pwm = 0;
 
                 static uint8_t pwm = 0;
  
Line 707: Line 715:
 
         }
 
         }
 
     }
 
     }
}</source>
+
}&lt;/source>
  
 
== 4. Abend ==
 
== 4. Abend ==
Line 713: Line 721:
 
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.
  
<source lang="c">#include <avr/io.h>
+
&lt;source lang="c">#include &lt;avr/io.h>
#include <avr/interrupt.h>
+
#include &lt;avr/interrupt.h>
#include <util/delay.h>
+
#include &lt;util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
  
Line 761: Line 769:
 
     static uint8_t last_sample = 15; //0b1111;
 
     static uint8_t last_sample = 15; //0b1111;
 
     /* read inputs */
 
     /* read inputs */
     uint8_t new_sample = PINC & 15; //0b1111;
+
     uint8_t new_sample = PINC &amp; 15; //0b1111;
  
 
     /* mark bits which are sampled with the same value */
 
     /* mark bits which are sampled with the same value */
Line 770: Line 778:
 
     /* 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 & same_sample);
+
     uint8_t state_different = btn_state ^ (new_sample &amp; 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 778: Line 786:
 
     * 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 & state_different;
+
     uint8_t btn_press = btn_state &amp; state_different;
  
 
     /* toggle all bits for inputs which switched state */
 
     /* toggle all bits for inputs which switched state */
Line 793: Line 801:
 
static void wait(uint32_t s) {
 
static void wait(uint32_t s) {
 
uint32_t i;
 
uint32_t i;
for (i = 0; i < s; i++) {
+
for (i = 0; i &lt; s; i++) {
 
_delay_us(1);
 
_delay_us(1);
 
}
 
}
Line 838: Line 846:
 
 
  
if (pos < 1) {
+
if (pos &lt; 1) {
 
return;
 
return;
 
}
 
}
Line 844: Line 852:
 
// 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 < dur ? dur_tmp : dur;
+
dur = dur_tmp &lt; dur ? dur_tmp : dur;
 
 
while (!state && j < 10) {
+
while (!state &amp;&amp; j &lt; 10) {
 
j++;
 
j++;
 
DDRC |= _BV(PC3); // ir reciever off
 
DDRC |= _BV(PC3); // ir reciever off
Line 856: Line 864:
  
 
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 &= ~_BV(PC3); // ir reciever on
+
DDRC &amp;= ~_BV(PC3); // ir reciever on
 
}
 
}
 
}
 
}
Line 871: Line 879:
 
     * 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 && pos == 0) {
+
     if (state &amp;&amp; pos == 0) {
 
         TCNT1 = 0;
 
         TCNT1 = 0;
 
     /* else record the timing value */
 
     /* else record the timing value */
Line 925: Line 933:
 
     DDRC |= _BV(PC4);
 
     DDRC |= _BV(PC4);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
     PORTC &= ~_BV(PC4);
+
     PORTC &amp;= ~_BV(PC4);
     PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
+
     PORTD &amp;= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
  
 
     /* configure ir input pin, with pullup */
 
     /* configure ir input pin, with pullup */
     DDRC &= ~_BV(PC3);
+
     DDRC &amp;= ~_BV(PC3);
 
     PORTC |= _BV(PC3);
 
     PORTC |= _BV(PC3);
  
 
     /* configure button input pins, with pullup */
 
     /* configure button input pins, with pullup */
     DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
+
     DDRC &amp;= ~(_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 &= ~_BV(PD5);
+
     PORTD &amp;= ~_BV(PD5);
  
 
     /* wait until pin is high (no ir carrier is detected) */
 
     /* wait until pin is high (no ir carrier is detected) */
     while(!(PINC & _BV(PC3)));
+
     while(!(PINC &amp; _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 973: Line 981:
 
     while(1) {
 
     while(1) {
 
         /* if a code has been received */
 
         /* if a code has been received */
         if (mode == MODE_DISPLAY && done) {
+
         if (mode == MODE_DISPLAY &amp;&amp; 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 < pos; i += 2) {
+
             for (uint8_t i = 0; i &lt; pos; i += 2) {
  
 
                 if (view == VIEW_VALUE_AND_TIME) {
 
                 if (view == VIEW_VALUE_AND_TIME) {
Line 1,006: Line 1,014:
  
 
             /* turn off second and third led */
 
             /* turn off second and third led */
             PORTD &= ~(_BV(PD3) | _BV(PD6));
+
             PORTD &amp;= ~(_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 & _BV(PC3)));
+
             while(!(PINC &amp; _BV(PC3)));
  
 
             /* reset all global variables */
 
             /* reset all global variables */
Line 1,032: Line 1,040:
 
if (button_press) {
 
if (button_press) {
 
/* first button toggles system mode */
 
/* first button toggles system mode */
if (button_press & 1) {
+
if (button_press &amp; 1) {
 
mode++;
 
mode++;
 
if (mode > MODE_RECORD)
 
if (mode > MODE_RECORD)
Line 1,041: Line 1,049:
  
 
/* disable timer1 and pin change interrupts */
 
/* disable timer1 and pin change interrupts */
TIMSK1 &= ~_BV(OCIE1A);
+
TIMSK1 &amp;= ~_BV(OCIE1A);
PCMSK1 &= ~_BV(PCINT11);
+
PCMSK1 &amp;= ~_BV(PCINT11);
  
 
/* turn off led1 */
 
/* turn off led1 */
PORTC &= ~_BV(PC4);
+
PORTC &amp;= ~_BV(PC4);
  
 
} else if (mode == MODE_DISPLAY) {
 
} else if (mode == MODE_DISPLAY) {
Line 1,071: Line 1,079:
  
 
/* second button toggles view mode */
 
/* second button toggles view mode */
if (button_press & 2) {
+
if (button_press &amp; 2) {
 
view++;
 
view++;
 
if (view > VIEW_TIME)
 
if (view > VIEW_TIME)
Line 1,084: Line 1,092:
 
}
 
}
  
if (button_press & 4) {
+
if (button_press &amp; 4) {
 
static uint8_t pwm = 0;
 
static uint8_t pwm = 0;
  
Line 1,100: Line 1,108:
 
}
 
}
 
}
 
}
}</source>
+
}&lt;/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]]
  
<source lang="c">#include <avr/io.h>
+
&lt;source lang="c">#include &lt;avr/io.h>
#include <avr/interrupt.h>
+
#include &lt;avr/interrupt.h>
#include <util/delay.h>
+
#include &lt;util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
 
   
 
   
Line 1,153: Line 1,161:
 
     static uint8_t last_sample = 15; //0b1111;
 
     static uint8_t last_sample = 15; //0b1111;
 
     /* read inputs */
 
     /* read inputs */
     uint8_t new_sample = PINC & 15; //0b1111;
+
     uint8_t new_sample = PINC &amp; 15; //0b1111;
 
   
 
   
 
     /* mark bits which are sampled with the same value */
 
     /* mark bits which are sampled with the same value */
Line 1,162: Line 1,170:
 
     /* 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 & same_sample);
+
     uint8_t state_different = btn_state ^ (new_sample &amp; 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,170: Line 1,178:
 
     * 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 & state_different;
+
     uint8_t btn_press = btn_state &amp; state_different;
 
   
 
   
 
     /* toggle all bits for inputs which switched state */
 
     /* toggle all bits for inputs which switched state */
Line 1,187: Line 1,195:
 
s /= 100;
 
s /= 100;
 
s *= 2.75;
 
s *= 2.75;
for (i = 0; i < s; i++) {
+
for (i = 0; i &lt; s; i++) {
 
_delay_us(100);
 
_delay_us(100);
 
}
 
}
Line 1,223: Line 1,231:
 
     * 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 && pos == 0) {
+
     if (state &amp;&amp; pos == 0) {
 
         TCNT1 = 0;
 
         TCNT1 = 0;
 
     /* else record the timing value */
 
     /* else record the timing value */
Line 1,289: Line 1,297:
 
uint8_t sendcode;
 
uint8_t sendcode;
  
while(!(PINC & _BV(PC3)));
+
while(!(PINC &amp; _BV(PC3)));
  
 
// say hello
 
// say hello
Line 1,297: Line 1,305:
 
wait(4500);
 
wait(4500);
 
 
for (uint8_t z=0; z<100; z++) {
+
for (uint8_t z=0; z&lt;100; z++) {
 
if (msg[z] == '\r') {
 
if (msg[z] == '\r') {
 
z=100;
 
z=100;
Line 1,305: Line 1,313:
  
 
// send data
 
// send data
     for (uint8_t i=0; i<8; i++) {
+
     for (uint8_t i=0; i&lt;8; i++) {
     if (sendcode & (1 << i)) {
+
     if (sendcode &amp; (1 &lt;&lt; i)) {
 
     send1();
 
     send1();
 
     } else {
 
     } else {
Line 1,325: Line 1,333:
 
   
 
   
 
//uart_printf("-- %d --\n", pos);
 
//uart_printf("-- %d --\n", pos);
while(!(PINC & _BV(PC3)));
+
while(!(PINC &amp; _BV(PC3)));
  
 
     // transform time to ms
 
     // transform time to ms
     for (uint8_t i = 0; i < pos; i++) {
+
     for (uint8_t i = 0; i &lt; pos; i++) {
 
         code[i] *= 64 / 20;
 
         code[i] *= 64 / 20;
 
     }
 
     }
 
   
 
   
 
     // receive hello
 
     // receive hello
     if (code[0] < 8500 || code[0] > 9500
+
     if (code[0] &lt; 8500 || code[0] > 9500
     || code[1] < 4000 || code[1] > 5000
+
     || code[1] &lt; 4000 || code[1] > 5000
     || pos < 10
+
     || pos &lt; 10
 
     ) {
 
     ) {
 
         // no nec hello found
 
         // no nec hello found
Line 1,343: Line 1,351:
 
   
 
   
 
     // receive msg
 
     // receive msg
for (uint8_t j=0; j<pos/8; j++) {
+
for (uint8_t j=0; j&lt;pos/8; j++) {
     for (uint8_t i=0; i<8; i++) {
+
     for (uint8_t i=0; i&lt;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 && code[16*j + 2*i + 2] < 800)) {
+
             if (!(code[16*j + 2*i + 2] > 400 &amp;&amp; code[16*j + 2*i + 2] &lt; 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,356: Line 1,364:
 
             }
 
             }
 
   
 
   
             if (code[16*j + 2*i + 3] > 400 && code[16*j + 2*i + 3] < 800) {
+
             if (code[16*j + 2*i + 3] > 400 &amp;&amp; code[16*j + 2*i + 3] &lt; 800) {
 
                 // bit is 0
 
                 // bit is 0
                 rcv &= ~(1 << i);
+
                 rcv &amp;= ~(1 &lt;&lt; i);
             } else if (code[16*j + 2*i + 3] > 900 && code[16*j + 2*i + 3] < 1300) {
+
             } else if (code[16*j + 2*i + 3] > 900 &amp;&amp; code[16*j + 2*i + 3] &lt; 1300) {
 
                 // bit is 1
 
                 // bit is 1
                 rcv |= 1 << i;
+
                 rcv |= 1 &lt;&lt; i;
 
             } else {
 
             } else {
 
                 // not sure which value we have
 
                 // not sure which value we have
Line 1,387: Line 1,395:
 
     DDRC |= _BV(PC4);
 
     DDRC |= _BV(PC4);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
 
     DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
     PORTC &= ~_BV(PC4);
+
     PORTC &amp;= ~_BV(PC4);
     PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
+
     PORTD &amp;= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
 
   
 
   
 
     /* configure ir input pin, with pullup */
 
     /* configure ir input pin, with pullup */
     DDRC &= ~_BV(PC3);
+
     DDRC &amp;= ~_BV(PC3);
 
     PORTC |= _BV(PC3);
 
     PORTC |= _BV(PC3);
 
   
 
   
 
     /* configure button input pins, with pullup */
 
     /* configure button input pins, with pullup */
     DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
+
     DDRC &amp;= ~(_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 &= ~_BV(PD5);
+
     PORTD &amp;= ~_BV(PD5);
 
   
 
   
 
     /* wait until pin is high (no ir carrier is detected) */
 
     /* wait until pin is high (no ir carrier is detected) */
     while(!(PINC & _BV(PC3)));
+
     while(!(PINC &amp; _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,441: Line 1,449:
 
   
 
   
 
                 /* turn off second and third led */
 
                 /* turn off second and third led */
                 PORTD &= ~(_BV(PD3) | _BV(PD6));
+
                 PORTD &amp;= ~(_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 & _BV(PC3)));
+
                 while(!(PINC &amp; _BV(PC3)));
 
   
 
   
 
                 /* reset all global variables */
 
                 /* reset all global variables */
Line 1,462: Line 1,470:
 
uint8_t msg[7] = "Hallo!\r";
 
uint8_t msg[7] = "Hallo!\r";
 
// SENDE
 
// SENDE
if (button_press & (1 << 0)) {
+
if (button_press &amp; (1 &lt;&lt; 0)) {
 
send(msg);
 
send(msg);
} else if (button_press & (1 << 1)) {
+
} else if (button_press &amp; (1 &lt;&lt; 1)) {
 
send(("Gruppe 1\r")); // 0b101
 
send(("Gruppe 1\r")); // 0b101
} else if (button_press & (1 << 2)) {
+
} else if (button_press &amp; (1 &lt;&lt; 2)) {
 
send("1234567890\r"); // 0b10001
 
send("1234567890\r"); // 0b10001
} else if (button_press & (1 << 3)) {
+
} else if (button_press &amp; (1 &lt;&lt; 3)) {
 
send("XY\r");
 
send("XY\r");
 
}
 
}
Line 1,477: Line 1,485:
 
}
 
}
 
}
 
}
</source>
+
&lt;/source>
 
[[Category:U23 2008]]
 
[[Category:U23 2008]]

Revision as of 10:07, 24 November 2010



Under Construction! Please Visit Reserve Page. Page Will Be Available Shortly


CLICK HERE


Meta Data

Mitglieder

  • Mark<br />
  • Christoph<br />
  • Hendrik<br />
  • Robert<br />

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> <br />

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>