4

I am completely new to programming and I am trying a brute force programming on my garage door opener. I want to use an Arduino for learning purposes. I wrote the following program that finally did what it should and now I am wondering whether there is a shorter code that does the same. Is anyone able to help me in that matter?

I do know that about 2^12 possibilities existed so I ran through all of them. I also knew that some parts of the "pulsetrain" (the set of necessary pulses) start with a particular sequence that is always the same (for all "brute forced" trains) and that the closing sequence is also always identical. I then simply wrote that down in the following, nasty code:

/*
  Transmitter is connected to Arduino Pin #2
*/

void setup() {
  pinMode(2, OUTPUT);
}

void pulsetrain(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m) {
  PORTD &= ~_BV(PD2);
  //set to LOW, hardwired to make it faster, see http://www.instructables.com/id/Arduino-is-Slow-and-how-to-fix-it/?ALLSTEPS
  delayMicroseconds(283); // (D2)
  PORTD |= _BV(PD2); //set to HIGH
  delayMicroseconds(566);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(283);
  PORTD |= _BV(PD2);
  delayMicroseconds(566);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(a);
  PORTD |= _BV(PD2);
  delayMicroseconds(b);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(c);
  PORTD |= _BV(PD2);
  delayMicroseconds(d);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(e);
  PORTD |= _BV(PD2);
  delayMicroseconds(f);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(g);
  PORTD |= _BV(PD2);
  delayMicroseconds(h);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(i);
  PORTD |= _BV(PD2);
  delayMicroseconds(j);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(k);
  PORTD |= _BV(PD2);
  delayMicroseconds(l);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(m);
  PORTD |= _BV(PD2);
  delayMicroseconds(283);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(566);
  PORTD |= _BV(PD2);
  delayMicroseconds(283);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(566);
  PORTD &= ~_BV(PD2); // last LOW
}

void loop() {
  int signals[2] = {283, 566};
  for (int a = 0; a < 2;  a++) {
    for (int b = 0; b < 2;  b++) {
      for (int c = 0; c < 2;  c++) {
        for (int d = 0; d < 2;  d++) {
          for (int e = 0; e < 2;  e++) {
            for (int f = 0; f < 2;  f++) {
              for (int g = 0; g < 2;  g++) {
                for (int h = 0; h < 2;  h++) {
                  for (int i = 0; i < 2;  i++) {
                    for (int j = 0; j < 2;  j++) {
                      for (int k = 0; k < 2;  k++) {
                        for (int l = 0; l < 2;  l++) {
                          for (int m = 0; m < 2;  m++) {
                            pulsetrain(signals[a], signals[b], signals[c], signals[d], signals[e], signals[f], signals[g], signals[h], signals[i], signals[j], signals[k], signals[l], signals[m]);
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
dda
  • 1,595
  • 1
  • 12
  • 17
AndreasL
  • 41
  • 1

1 Answers1

1

All those variables a, b, etc. are just the individual bits of a 13-bit number. When you loop through all combinations, you are actually looping through all the possible numeric values of a 13-bit number. This can be simplified as this (warning: not tested):

void setup() {
    pinMode(2, OUTPUT);
}

// the bitstream is: 0.101x xxxx.xxxx xxxx.0101
void pulsetrain(uint16_t code) {
    uint32_t bitstream = (((uint32_t) code) << 4) | 0x0a0005UL;
    for (uint8_t i = 0; i < 21; i++) {
        PIND = _BV(PD2);    // toggle pin
        if (bitstream & 0x100000)
            delayMicroseconds(566);
        else
            delayMicroseconds(283);
        bitstream <<= 1;
    }
    PORTD &= ~_BV(PD2); // last LOW
}

void loop() {
    for (uint16_t code = 0; code < 0x2000; code++) {
        pulsetrain(code);
    }
}
Mikael Patel
  • 7,989
  • 2
  • 16
  • 21
Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81