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]);
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
2
  • 2
    Just look at at like 283 is a low bit, and 566 is a high bit. So a-m would become a 13 bit number. Loop through those numbers with a for loop (0-8191). Then in the pulsetrain function read one bit, apply the delay of 283 or 566 based on the bit being 0 or 1. Then shift all the bit (left or right), and repeat (13 times). – Gerben Jan 14 '17 at 13:44
  • My problem is not that I cannot program the opener (the above code did what it should) and I also understand the Manchester Coding. I wanted a code that does the same but consists of less than the above 84 lines! I do not know how to handle binary() and DecimalToBinary() (if it is even defined) with an arduino. – Andreas Jan 15 '17 at 10:43
2

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);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.