Hilfe! 3 Pins gesucht!

Hallo

Ich bastel gerade an einem Projekt herum, das von einem Atmega324p gesteuert wird. Nach einer etwas schweren Geburt rund um den Bootloader und die Fuses, läuft nun soweit alles gut, allerdings vermisse ich drei Pins...
Für die Installation habe ich die Dateien des Gator Boards von Regged Circuits übernommen, das ebenfalls mit einem Atmega324p bestückt ist. Das Pinmapping zu den Arduino Pins dokumentiert er auf dieser Seite: http://www.ruggedcircuits.com/html/arduino.html

Allerdings fehlen in dieser Auflistung die Pins C7, D0 und D1. In der von ihm modifizierten pins_Arduino.c Datei ist die Pinbelegung ebenso aufgeführt, wie auf der oben verlinkten Seite. Wieso hat er diese drei Pins einfach weggelassen? Und was noch viel wichtiger ist, wie kann ich die dennoch benützen?

  • Gibt es eine Möglichkeit, sie durch Verändern der pin_Arduino.c Datei hinzuzufügen? Wäre dazu ein erneutes Installieren des Bootloaders nötig? Würde ich am liebsten vermeiden, wenns geht.
  • Gibt es eine Möglichkeit, die Pins direkt anzusprechen und softwaremässig an eine Variable zu knüpfen, damit man sich danach nicht mehr darum kümmern muss?

Für Lösungsvorschläge eurerseits, wäre ich sehr dankbar :slight_smile:

Gruss

Hitsuji

Hallo,

dann würde ich empfehlen das Datenblatt vom 324p anzuschauen und gucken was an den Pins hängt bzw. wofür die da sind. Wenn das die serielle Schnittstelle 0 ist, dann würde ich diese eigentlich nicht benutzen. Sonst kannste ihn danach vielleicht nicht mehr flashen.

Mit port manipulation kannst Du alle Pins ansprechen. Du mußt dann halt selber schauen welche Bit in welchem Port dem jeweiligen Pin entspricht.
Theorie am Beispiel Arduino http://arduino.cc/en/Reference/PortManipulation:
Für die genaue Ports und die Pin-Entsprechung mußt Du das Datenblatt bemühen.
Viele Grüße Uwe

D0 und D1 sind die Pins für die 1. Hardware Serial Schnittstelle. Die wollte ich später für die Kommunikation mit einem XBee nutzen. Diese kann ich in diesem Fall trotzdem benützen, auch wenn die Pins in der Pindefinition nicht definiert sind? Ebenso Pind PC7?

Die Portmanipulationsbefehle betreffen ja immer den gesamten Port. Müsste ich dann also , um den Pin C7 im Setup als Eingang zu definieren, anschliessend an die pinMode Definitionen der übrigen Pins nochmals den Port C mit Hilfe des Bitwise Or Operators so umstellen, dass alle Pins, ausser der 7., so belassen werden wie sie sind und der 7. auf Eingang gestellt wird?
Und das Auslesen des Zustandes würde dann über den BitRead Befehl gehen?
Klingt etwas umständlich, aber liesse sich ja in eine Funktion verpacken, die dann jeweils aufgerufen wird.

Gibt es eine Möglichkeit, sie durch Verändern der pin_Arduino.c Datei hinzuzufügen?

Ja.
Ob du in deinem Sketch direkt einzelne Bits der Ports ansprichst oder das Pin-Mapping modifizierst, ist Geschmackssache. Wenn der gleiche Sketch nicht auf anderer Hardware laufen soll, und du nur einen Sketch für deinen 324 schreiben willst, ist das direkte Port-Programmieren wohl einfacher.

Wäre dazu ein erneutes Installieren des Bootloaders nötig?

Nein.
Der Bootloader läuft und kann mit allen Pins arbeiten die er braucht. Den brauchst du also weder neu zu übersetzen noch neu in den Flash zu laden.

Der Bootloader liest seriell Daten aus hex Dateien und lädt sie in den Flash. Mit welcher Programmierumgebung diese hex-Datei erstellt wurde (direkt avr-gcc oder Standard-Arduino oder Arduino mit modifizierter pin_Arduino.c ) ist egal ...

Hitsuji:
Die Portmanipulationsbefehle betreffen ja immer den gesamten Port. Müsste ich dann also , um den Pin C7 im Setup als Eingang zu definieren, anschliessend an die pinMode Definitionen der übrigen Pins nochmals den Port C mit Hilfe des Bitwise Or Operators so umstellen, dass alle Pins, ausser der 7., so belassen werden wie sie sind und der 7. auf Eingang gestellt wird?

Du liest einfach den aktuellen Zustand des Ports aus und machst ein Und. z.B.:
DDRC = DDRC & 0x7F;

Das setzt Bit 7 auf 0 und belässt Bits 0-6

Um Bits auf 1 zu setzten braucht man ein Oder. Um Bits auf 0 zu setzten ein Und. Da du Pin 7 als Eingang willst, ist in diesem Fall ein Und nötig.

ok danke :slight_smile:

Nun muss ich doch nochmals nachfragen:

An diesem einen ungemappten Pin hängt nun ein TSOP IR Empfänger. Für die iR Remote Library muss ich einen Pin angeben, an dem der receiver hängt.

Beispiel: int RECV_PIN = 11;

Wie kann ich nun aber die Pin Nummer mit Hilfe der Portbefehle ersetzen? Ginge sowas?

int RECV_PIN = bitRead(PINC, 7);

oder würde das nicht einfach nur eine 1 oder 0 zurück geben und somit auf pin 1 und 0 verweisen?
Bitte um Hilfe! :confused:

digitalWrite(RECV_PIN, bitRead(PINC, 7));

Das sollte PC7 auf Pin 11 ausgeben

Dein Lösungsvorschlag klingt für mich ein wenig so, als wenn dann PC7 quasi auf Pin 11 umgeleitet würde. Pin 11 war aber wohl ein etwas blödes Beispiel, da Pin 11 ja eigentlich anderweitig verwendet wird. Wenn die Funktion der iR library auf den RECV_PIN zugreift, müsste er direkt PC7 auslesen. Würde das mit deinem Vorschlag so funktionieren?

Oder was mir nach wie vor im Kopf rumschwirrt, ist, die Datei pins_arduino.c anzupassen. Was mich bisher irritierte, war, dass den einzelnen Pins scheinbar nirgends die Nummer, mit der sie schlussendlich im Sketch angesprochen werden können, zugewiesen wird. Als ich heute jedoch die Datei genauer anschaute, fiel mir ein, dass die Pinnummer ja die Indexnummer der folgenden drei Arrays sein könnte. Wäre es dann vielleicht möglich, die drei Arrays jeweils um einen Eintrag zu ergänzen, der somit index #29 hätte, um somit einen Pin 29 zu erschaffen? Im folgenden Codestück sind die Ergänzungen bereits eingetragen und mit Kommentaren markiert. Würde das eventuell genügen, damit PC7 als Pin 29 angesprochen werden könnte?

#elif defined(__AVR_ATmega324P__) // GATOR
/* On an ATmega324P, the pin mappings are as shown below. The
 * first 20 pins (D0-D19) are for compatibility with ATmega8
 * and ATmega168 Arduinos. Specifically, the timer pins
 * correspond as do the analog pin numbers to their digital
 * pin counterparts (e.g., AI0-->D14, etc.)
 *
 *      Analog Digital   PWM     Pin
 *     -------+-------+-------+-------
 *            |  D 0  |       |  PC0
 *            |  D 1  |       |  PC1
 *            |  D 2  |       |  PC2
 *            |  D 3  |TIMER2B|  PD6
 *            |  D 4  |       |  PC3
 *            |  D 5  |TIMER0B|  PB4    !SS
 *            |  D 6  |TIMER0A|  PB3
 *            |  D 7  |       |  PD2
 *            |  D 8  |       |  PD3
 *            |  D 9  |TIMER1A|  PD5
 *            |  D 10 |TIMER1B|  PD4
 *            |  D 11 |TIMER2A|  PD7
 *            |  D 12 |       |  PC4
 *            |  D 13 |       |  PC6
 *      AI 0  |  D 14 |       |  PA0
 *      AI 1  |  D 15 |       |  PA1
 *      AI 2  |  D 16 |       |  PA2
 *      AI 3  |  D 17 |       |  PA3
 *      AI 4  |  D 18 |       |  PA4
 *      AI 5  |  D 19 |       |  PA5
 *      AI 6  |  D 20 |       |  PA6
 *      AI 7  |  D 21 |       |  PA7
 *            |  D 22 |       |  PC5
 *            |  D 23 |       |  PB0
 *            |  D 24 |       |  PB1
 *            |  D 25 |       |  PB2
 *            |  D 26 |       |  PB5    MOSI
 *            |  D 27 |       |  PB6    MISO
 *            |  D 28 |       |  PB7    SCK   // <----- in dieser Auflistung fehlt mein vermisster Pin PC7, den ich gerne als 29. Pin dazufügen würde
 */

#define PA 1
#define PB 2
#define PC 3
#define PD 4

// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] = {
	NOT_A_PORT,
	&DDRA,
	&DDRB,
	&DDRC,
	&DDRD,
};

const uint16_t PROGMEM port_to_output_PGM[] = {
	NOT_A_PORT,
	&PORTA,
	&PORTB,
	&PORTC,
	&PORTD,
};

const uint16_t PROGMEM port_to_input_PGM[] = {
	NOT_A_PORT,
	&PINA,
	&PINB,
	&PINC,
	&PIND,
};

const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
	PC, /* D0 : PC0 */
	PC, /* D1 : PC1 */
	PC, /* D2 : PC2 */
	PD, /* D3 : PD6 */
	PC, /* D4 : PC3 */
	PB, /* D5 : PB4 */
	PB, /* D6 : PB3 */
	PD, /* D7 : PD2 */
	PD, /* D8 : PD3 */
	PD, /* D9 : PD5 */
	PD, /* D10 : PD4 */
	PD, /* D11 : PD7 */
	PC, /* D12 : PC4 */
	PC, /* D13 : PC6 */
	PA, /* D14 : PA0 */
	PA, /* D15 : PA1 */
	PA, /* D16 : PA2 */
	PA, /* D17 : PA3 */
	PA, /* D18 : PA4 */
	PA, /* D19 : PA5 */
	PA, /* D20 : PA6 */
	PA, /* D21 : PA7 */
	PC, /* D22 : PC5 */
  PB, /* D23 : PB0 */
  PB, /* D24 : PB1 */
  PB, /* D25 : PB2 */
  PB, /* D26 : PB5 */
  PB, /* D27 : PB6 */
  PB,  /* D28 : PB7 */
  PC  /* D29 : PC7 */   <-------- meine Ergänzung
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
	_BV(0), /* D0 : PC0 */
	_BV(1), /* D1 : PC1 */
	_BV(2), /* D2 : PC2 */
	_BV(6), /* D3 : PD6 */
	_BV(3), /* D4 : PC3 */
	_BV(4), /* D5 : PB4 */
	_BV(3), /* D6 : PB3 */
	_BV(2), /* D7 : PD2 */
	_BV(3), /* D8 : PD3 */
	_BV(5), /* D9 : PD5 */
	_BV(4), /* D10 : PD4 */
	_BV(7), /* D11 : PD7 */
	_BV(4), /* D12 : PC4 */
	_BV(6), /* D13 : PC6 */
	_BV(0), /* D14 : PA0 */
	_BV(1), /* D15 : PA1 */
	_BV(2), /* D16 : PA2 */
	_BV(3), /* D17 : PA3 */
	_BV(4), /* D18 : PA4 */
	_BV(5), /* D19 : PA5 */
	_BV(6), /* D20 : PA6 */
	_BV(7), /* D21 : PA7 */
	_BV(5), /* D22 : PC5 */
  _BV(0), /* D23 : PB0 */
	_BV(1), /* D24 : PB1 */
	_BV(2), /* D25 : PB2 */
	_BV(5), /* D26 : PB5 */
	_BV(6), /* D27 : PB6 */
	_BV(7),  /* D28 : PB7 */ 
	_BV(7)  /* D29 : PC7 */ <-------- meine Ergänzung
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
	NOT_ON_TIMER, /* D0 : PC0 */
	NOT_ON_TIMER, /* D1 : PC1 */
	NOT_ON_TIMER, /* D2 : PC2 */
	TIMER2B,      /* D3 : PD6 (TIMER2B) */
	NOT_ON_TIMER, /* D4 : PC3 */
	TIMER0B,      /* D5 : PB4 (TIMER0B) */
	TIMER0A,      /* D6 : PB3 (TIMER0A) */
	NOT_ON_TIMER, /* D7 : PD2 */
	NOT_ON_TIMER, /* D8 : PD3 */
	TIMER1A,      /* D9 : PD5 (TIMER1A) */
	TIMER1B,      /* D10 : PD4 (TIMER1B) */
	TIMER2A,      /* D11 : PD7 (TIMER2A) */
	NOT_ON_TIMER, /* D12 : PC4 */
	NOT_ON_TIMER, /* D13 : PC6 */
	NOT_ON_TIMER, /* D14 : PA0 */
	NOT_ON_TIMER, /* D15 : PA1 */
	NOT_ON_TIMER, /* D16 : PA2 */
	NOT_ON_TIMER, /* D17 : PA3 */
	NOT_ON_TIMER, /* D18 : PA4 */
	NOT_ON_TIMER, /* D19 : PA5 */
	NOT_ON_TIMER, /* D20 : PA6 */
	NOT_ON_TIMER, /* D21 : PA7 */
	NOT_ON_TIMER, /* D22 : PC5 */
	NOT_ON_TIMER, /* D23 : PB0 */
	NOT_ON_TIMER, /* D24 : PB1 */
	NOT_ON_TIMER, /* D25 : PB2 */
	NOT_ON_TIMER, /* D26 : PB5 */
	NOT_ON_TIMER, /* D27 : PB6 */
	NOT_ON_TIMER, /* D28 : PB7 */
	NOT_ON_TIMER, /* D29 : PC7 */ <-------- meine Ergänzung
};

E: Komma nach der zeitletzten Aufzählung im Array vergessen :wink:

Sorry. Jetzt verstehe ich genau was du wolltest :slight_smile:

Deine Idee ist da sehr gut. Keine Ahnung ob das funktioniert. Aber ausprobieren kann man es mal.

Hey, das funktioniert tatsächlich! :smiley:
iR Receive funktioniert somit.
Nun muss ich noch die library so verändern, dass ich iR Signale über den Timer 0 senden kann. Das könnte etwas schwieriger werden :confused: wahrscheinlich kommen dann noch Fragen dazu...

Auf Timer0 läuft schon millis() und delay(). Wenn du das nicht kaputt machen willst (oder irgendwie daran koppeln willst), verwende Timer1 und höher.

Timer Tutorials gibt es hier gute:
http://maxembedded.com/2011/06/24/avr-timers-timer0-2/

Aber schau sicherheitshalber immer ins Datenblatt wegen den Registern. Die Register weichen zum Teil ganz leicht ab. Auf dem Mega hat z.B. jeder Timer sein eigenes Interrupt Masken Register TIMSKn.

Danke für den Hinweis. Habe irgendwo schonmal gelesen, dass das keine gute Idee sei, am Timer0 etwas zu machen.

Das Problem ist, dass ich total hirnlos meine iR-LED einfach an D3 angeschlossen habe, was weder DigitalPin 3 ist, noch ein PWM Pin und auch überhaupt nichts mit irgendeinem Timer zu tun hat. Nix überlegt... :sweat_smile:

Nun, konnte ich die LED durch ziemlich hässliches umbauen der Platine (Leiterbahnen durchtrennen, Drahtbrücken einlöten) immerhin an einen der Timer0 Pins hängen unter Aufopferung des anderen Pins. Die Anderen Timer/PWM Pins sind zur Zeit mit den Kathoden der RGB-LED's verbunden. Diese umzuhängen würde ziemlich schwierig werden :/. Deshalb wollte ichs mal versuchen, ob es immerhin einigermassen gebraucht werden könnte. Allerdings siehts bis jetzt eher schlecht aus... mal schauen, vielleicht mit noch mehr fliegenden Drähten und durchtrennten Leiterbahnen... :confused:

Es ist zwar möglich im CTC Modus beim Auslösen eines Interrupts automatisch einen bestimmten Pin zu toggeln (mit den Compare Output Mode Bits im Timer Control Register A). Aber man kann das auch per Hand machen und damit beliebige Pins verwenden.

Dazu klinkst du dich dazu einfach in den Compare Interrupt Vektor ein (z.B. TIMER2_COMPA_vect). Siehe dazu der CTC Link im oberen Absatz. Ist da alles erklärt. Da für Timer1 aber das geht analog auf anderen Timern.

Mit direkter Port-Manipulation kannst du dann einen Pin in 2-3 Takt-Zyklen toggeln. Entweder man macht ein XOR auf den Pin. Oder noch einen Takt schneller geht es wenn man eine 1 auf das Eingangsregister PINn schreibt. Siehe hier:
http://www.billporter.info/2010/08/18/ready-set-oscillate-the-fastest-way-to-change-arduino-pins/

Das toggelt den Pin (hier PB0) mit einem XOR:
PORTB ^= (_BV(0));
Das toggelt den Pin mit der anderen Methode:
PINB |= _BV(0);

Das kostet natürlich ein klein wenig Zeit, aber da die Zeit immer konstant ist, sollte das eigentlich keinen Unterschied bei der Frequenz machen.

Ich nehme hier mal an du willst ein 38kHz Signal für deine IR LED erzeugen. Wenn es PWM sein soll wird es kompliziert (das ist der einzige Timer Teil den ich nicht verstehe) und dann geht das nicht auf allen Pins.

Ich verstehe zwar nur Bahnhof bei deinem Post, doch irgendwie klingt er hoffnungserweckend.

Jep, es geht darum, IR Signale zu senden. Um die Modulation mit den 38kHz und die codierten Signale zu erzeugen, benütze ich die iRremote Library von Ken Shirriff (GitHub - Arduino-IRremote/Arduino-IRremote: Infrared remote library for Arduino: send and receive infrared signals with multiple protocols). Denn ich verstehe eigentlich überhaupt nichts von der Hardcoreprogrammiererei, wie sie in diesen Libraries angewendet wird :slight_smile:

Ich werde mir bei Gelegenheit deine Links zu Gemüte führen, jedoch befürchte ich, dass dies meinen Level dann doch etwas übersteigt. Bin eigentlich noch ziemlich neu bei der ganzen Sache und erst noch mit den Grundlagen am herumkämpfen :slight_smile: Solche Dinge, wie dieses hier entsteht eigentlich nur aus der Not heraus :slight_smile:

Wenn ich dich richtig verstanden habe, gibt es eine Möglichkeit, den Timer2 zu benützen, wie ihn die Library normalerweise benützt und die IR LED trotzdem am Pin des Timer0 zu belassen? Und dies, auch wenn an den Pins des Timer2 meine RGB LED's ge-pwm't werden? (über welchen Timer dieses PWM Signal getimed wird, weiss ich nicht. Benütze dazu ganz normal den digitalWrite Befehl).

EDIT: es gibt vielleicht eine einfachere Lösung. Schau dir mal das an:
https://github.com/shirriff/Arduino-IRremote/blob/master/IRremoteInt.h

Da kann man für verschiedene Prozessoren verschiedene Timer definieren. Wenn du dann ein einfach ein #define für denen Prozessor machst könnte das gehen. Oder du änderst das einfach am Ende:

// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
#else
  //#define IR_USE_TIMER1
#define IR_USE_TIMER2
#endif

Das ist was kompiliert wird wenn keine der oberen Optionen zutrifft. Kommentieren da einfach TIMER2 aus und mach den Kommentar bei TIMER1 weg. Dann bist du auf einem anderen Pin. Vielleicht mal schauen welche Ausgänge beim Atmga324 durch Timer1 geschaltet werden...

Was da drin steht sind die Nummern auf dem Arduino Board, aber auf dem blanken Prozessor sind es glaube ich 18 (PD4) und 19 (PD5):

Und dies, auch wenn an den Pins des Timer2 meine RGB LED's ge-pwm't werden?

Das nicht. Wenn du da PWM machst ist Timer2 belegt. Bleibt noch Timer1....

Welche Timer welche PWM Pins kontrollieren steht hier:
http://playground.arduino.cc/Main/TimerPWMCheatsheet

EDIT: Das gilt aber nur für den Uno und Mega. Am besten du schaust direkt auf die Pin-Belegung des Prozessors und suchst nach den OCxxx Pins.

Generell kannst du einem Timer sagen, dass er alle x Zeiteinheiten einen Interrupt auslösen soll. Da wird dann dein Programm unterbrochen und macht kurz was. CTC bedeutet "Clear Timer and Compare ". Das heißt der Timer zählt seinen Wert hoch und vergleicht diesen ständig mit einem Wert den du vorgibst. Wenn dieser Wert erreicht ist, wird ein Interrupt ausgelöst und der Timer auf 0 zurückgesetzt. Die Zeit stellt man über den Timer Takt und den Vergleichswert ein. Da gibt es eine Formel dazu. PWM geht auch grob so ähnlich, nur dass da sich da die Vergleichswerte ständig ändern.

Die ganzen Timer Funktionen die automatisch bestimmte Pins betreiben, haben dazu in einem Status Register ein Bit gesetzt das sagt: "wenn ein Interrupt kommt, toggle deinen Pin"

Aber man kann das auch per Hand machen. Eine Interrupt Service Routine ist nichts anderes als eine spezielle Methode:

ISR (TIMER1_COMPA_vect)
{
}

Diese wird dann jedes mal automatisch ausgeführt wenn dein Timer seinen Vergleichswert erreicht hat. Aber man nimmt da nicht digitalWrite() weil das ewig dauert.

Wobei die IR Remote Lib das nicht so macht, sondern anscheinend PWM mit einem Tastverhältnis von 50%. Da gibt es dann einen Compare Wert für die Low Phase und einen für die High Phase. Aber zig Modi wo man nicht durchblickt.

Bezüglich Pins und so beziehe ich mich jeweils auf dieses Datenblatt: http://www.atmel.com/Images/Atmel-8011-8-bit-AVR-Microcontroller-ATmega164P-324P-644P_datasheet.pdf

Demnach sind die Timer wie folgt mit den Pins verknüpft:

Timer physPin Portpin digital Pin beschaltet mit
Timer0A 43 PB3 6 IR LED
Timer0B 44 PB4 5 Piezo (geht nicht)
Timer1A 14 PD5 9 PWM rot
Timer1B 13 PD4 10 PWM blau
Timer2A 16 PD7 11 i/o Shiftregister data
Timer2B 15 PD6 3 PWM grün

(edit: scheiss Tabelle :.)

Wie du siehst, sind alle Timer Pins mit PWM Funktionen besetzt, ausser das Shiftregister, das ich brauche, um die RGB LED's anzusteuern. Dieser Pin wird als normaler digitaler Pin genutzt.
Da ich nach der Lektüre verschiedener Timersachen es so verstanden habe, dass der Timer zwar irgendwie Chipintern zählt, die Ausgabe, die von der iR Library genutzt wird, aber über die fix festgelegten Pins gemäss Datenblatt erfolgt, habe ich versucht, Timer0 entgegen den Empfehlungen zu nutzen, um nicht die ganze Platine verschandeln zu müssen und die iRremoteInt.h dahingehend verändert:

#ifndef IRremoteint_h
#define IRremoteint_h

#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

// define which timer to use
//
// Uncomment the timer you wish to use on your board.  If you
// are using another library which uses timer2, you have options
// to switch IRremote to use a different timer.

// Arduino Mega
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  //#define IR_USE_TIMER1   // tx = pin 11
  #define IR_USE_TIMER2     // tx = pin 9
  //#define IR_USE_TIMER3   // tx = pin 5
  //#define IR_USE_TIMER4   // tx = pin 6
  //#define IR_USE_TIMER5   // tx = pin 46

// Teensy 1.0
#elif defined(__AVR_AT90USB162__)
  #define IR_USE_TIMER1     // tx = pin 17

// Teensy 2.0
#elif defined(__AVR_ATmega32U4__)
  //#define IR_USE_TIMER1   // tx = pin 14
  //#define IR_USE_TIMER3   // tx = pin 9
  #define IR_USE_TIMER4_HS  // tx = pin 10

// Teensy++ 1.0 & 2.0
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  //#define IR_USE_TIMER1   // tx = pin 25
  #define IR_USE_TIMER2     // tx = pin 1
  //#define IR_USE_TIMER3   // tx = pin 16

// Sanguino
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
  //#define IR_USE_TIMER1   // tx = pin 13
  #define IR_USE_TIMER2     // tx = pin 14

// Atmega8
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
  #define IR_USE_TIMER1   // tx = pin 9

// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
#else
  //#define IR_USE_TIMER1   // tx = pin 9
  //#define IR_USE_TIMER2     // tx = pin 3
  #define IR_USE_TIMER0     // tx = pin 6   <--------------------- nachträglich hinzugefügt
#endif



#ifdef F_CPU
#define SYSCLOCK F_CPU     // main Arduino clock
#else
#define SYSCLOCK 20000000  // main Arduino clock <--------------------- nachträglich angepasst 
#endif

(...)

// defines for timer0 (8 bits)  <--------------------- nachträglich hinzugefügt, alles mögliche von 2B auf 0A gewechselt
#if defined(IR_USE_TIMER0)
#define TIMER_RESET
#define TIMER_ENABLE_PWM     (TCCR0A |= _BV(COM0A1))
#define TIMER_DISABLE_PWM    (TCCR0A &= ~(_BV(COM0A1)))
#define TIMER_ENABLE_INTR    (TIMSK0 = _BV(OCIE0A))
#define TIMER_DISABLE_INTR   (TIMSK0 = 0)
#define TIMER_INTR_NAME      TIMER0_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \
  const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
  TCCR0A = _BV(WGM20); \
  TCCR0B = _BV(WGM22) | _BV(CS20); \
  OCR0A = pwmval; \
  OCR0B = pwmval / 3; \
})
#define TIMER_COUNT_TOP      (SYSCLOCK * USECPERTICK / 1000000)
#if (TIMER_COUNT_TOP < 256)
#define TIMER_CONFIG_NORMAL() ({ \
  TCCR0A = _BV(WGM21); \
  TCCR0B = _BV(CS20); \
  OCR0A = TIMER_COUNT_TOP; \
  TCNT0 = 0; \
})
#else
#define TIMER_CONFIG_NORMAL() ({ \
  TCCR0A = _BV(WGM21); \
  TCCR0B = _BV(CS21); \
  OCR0A = TIMER_COUNT_TOP / 8; \
  TCNT0 = 0; \
})
#endif
//#if defined(CORE_OC0B_PIN)
//#define TIMER_PWM_PIN        CORE_OC0B_PIN  /* Teensy */
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN        9  /* Arduino Mega */
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN        14 /* Sanguino */
#else
#define TIMER_PWM_PIN        6  /* Atmega324p */
#endif

// defines for timer2 (8 bits)
#if defined(IR_USE_TIMER2)
#define TIMER_RESET
#define TIMER_ENABLE_PWM     (TCCR2A |= _BV(COM2B1))
#define TIMER_DISABLE_PWM    (TCCR2A &= ~(_BV(COM2B1)))
#define TIMER_ENABLE_INTR    (TIMSK2 = _BV(OCIE2A))
#define TIMER_DISABLE_INTR   (TIMSK2 = 0)
#define TIMER_INTR_NAME      TIMER2_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \
  const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
  TCCR2A = _BV(WGM20); \
  TCCR2B = _BV(WGM22) | _BV(CS20); \
  OCR2A = pwmval; \
  OCR2B = pwmval / 3; \
})
#define TIMER_COUNT_TOP      (SYSCLOCK * USECPERTICK / 1000000)
#if (TIMER_COUNT_TOP < 256)
#define TIMER_CONFIG_NORMAL() ({ \
  TCCR2A = _BV(WGM21); \
  TCCR2B = _BV(CS20); \
  OCR2A = TIMER_COUNT_TOP; \
  TCNT2 = 0; \
})
#else
#define TIMER_CONFIG_NORMAL() ({ \
  TCCR2A = _BV(WGM21); \
  TCCR2B = _BV(CS21); \
  OCR2A = TIMER_COUNT_TOP / 8; \
  TCNT2 = 0; \
})
#endif
#if defined(CORE_OC2B_PIN)
#define TIMER_PWM_PIN        CORE_OC2B_PIN  /* Teensy */
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN        9  /* Arduino Mega */
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN        14 /* Sanguino */
#else
#define TIMER_PWM_PIN        3  /* Arduino Duemilanove, Diecimila, LilyPad, etc */
#endif

(gekürzt:)

Wie zu erwarten war, funktioniert dies aber nicht wirklich. Die von dir beschriebene Methode, mittels einer Interruptroutine einen anderen Pin als der automatisch zugewiesene zu toggeln leuchtet irgendwie ein, doch wie müsste ich das nun für den konkreten Fall anpassen? Blicke da nicht wirklich durch. Auch kenn ich mich mit der Handhabung dieser ganzen Registersachen nicht wirklich aus.

Das per Hand zu machen ist schwerer als es sich auf den ersten Blick anhört. Ein 38 kHz Signal an sich zu erzeugen ist nicht so schwer. Aber damit es ja nicht getan. Damit muss man dann die Daten modulieren und da wird es sehr kompliziert. Soweit hatte ich noch gar nicht gedacht :frowning:

Abgesehen davon hast du keine Timer mehr mit denen man das machen könnte. Dann ist das sowieso hinfällig.

Die Pin-Belegung ist halt doof rückblickend. Das Schiebregister könnte ganz wo anders sein und dann könnte man PWM grün auf Pin 11 machen.

Ob deine Neu Definition überhaupt so gehen würde, selbst wenn man alles korrekt macht, kann ich nicht sagen. Wie gesagt der PWM Teil ist der Teil der Timer bei denen ich nicht durchblicke. Grob ist mir klar was abläuft, aber nicht im Detail. Gerade weil es da zig verschiedene PWM Optionen gibt.

Wenn überhaupt solltest da aber die Definitionen von Timer1 kopieren. Timer0 und Timer1 sind 16 Bit Timer. Und Timer2 ist ein 8-Bit Timer. Vor allem hat Timer2 andere Einstellungen was die Clock Select Bits in TCCR2B betrifft! Wenn du da die CS Einstellungen von Timer2 nimmst läuft der Timer mit einer andere Frequenz. Und auch bei dem PWM Kram kann es da Unterschiede zwischen Timer2 und den anderen geben.

EDIT:
Sieht nicht gut aus. Die RemoteIR Lib verwendet delay() :frowning:

Siehe Zeile 992, 1006 und 1011. Das geht dann nicht mehr wenn du Timer0 überschreibst

Gemäss Datenblatt ist Timer0 ein 8 Bit Timer. Aber du hast schon recht, die Pinbelegung ist saublöd gewählt. Hab für die IR LED zu wenig recherchiert und den Rest halt so belegt, dass es für das Routing der Platine am günstigsten ist :confused:

Werde wohl entweder mit ein paar fliegenden Drähten versuchen das Zeug umzubelegen oder wenn alles klar ist, wie's funktionieren würde, eine neue, verbesserte Platine herstellen.
Zuerst aber mal kucken, ob alles andere wie gewünscht funktioniert. Ein XBee Sockel ist auch integriert. Da hab ich mich noch nicht dran gemacht. Wenn das funktioniert und ich noch keine Lust habe, eine neue Platine zu ätzen, kann ich ja auch per XBee und einem Steckboard ein IR Proxy bauen :wink:

Vielen Dank auf jeden Fall für deine Bemühungen!