Yes, timing is a mess and libraries fill memory up.
This is how I send IR, 4 bits, IR LED positive on pin 0, negative on pin 1, no resistors, works up to about one meter distance with le LED I had at home.
const byte irPin = 0; //IR LED connected to digital 0
const byte irground = 1;
const int freq = 38000;
const byte BIT_PER_BLOCK = 4; // my protocol uses 4 bits, 1 nibble.
const int start_bit = 2510; //start bit threshold (microseconds)
const int zero = 2990;
const int uno = 3900;
const int space = 1400;
byte result = 0;
void setup() {
pinMode(irPin, OUTPUT);
pinMode(1, OUTPUT); //(pin 1 to ground)
}
void ir_bitbang (byte pin, byte ground, int hz, int tempus)
{
digitalWrite(ground,LOW); // (enables IR led)
tone(pin, hz); // start bit
delayMicroseconds(tempus);
noTone();
digitalWrite(ground,HIGH);
delayMicroseconds(space);
}
void loop()
{
ir_bitbang (irPin, irground, freq, start_bit); // start bit
ir_bitbang (irPin, irground, freq, zero); // bit3
ir_bitbang (irPin, irground, freq, uno); // bit2
ir_bitbang (irPin, irground, freq, zero); // bit1
ir_bitbang (irPin, irground, freq, uno); // bit0
delay(1500);
}