Arduino Quine

One of the things programmers tend to learn how to do in every language they know is how to write a quine – that is, a program that echoes its own source code out to the user, without reading the source code directly. This is an inherently recursive operation, so language-based tricks are needed to get it to work.

The Arduino is programmed in C++, however, there is no std::cout. Instead, user input is usually through the USART on the Arduino, and as such needs to initialize and print out from that port.

Traditionally, C/C++ quines are written using the preprocessor and the printf command, as it allows for simple replacement of strings with characters, thereby overcoming the recursive operation. As such, I use the sprintf command below (Arduino’s HardwareSerial doesn’t support formatted prints, sadly enough).

The quine below is for the Arduino Duemilanove or Uno (or any other, based on the ATMega328P microcontroller):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define d "\"
#define e "rn"
#define b """
#define a "%s#define d %s%s%s%s%s#define e %s%sr%sn%s%s#define b %s%s%s%s%s#define a %s%s%s%svoid setup()%s{%s  Serial.begin(115200);%s  DDRB |= (1 << 5);%s}%svoid loop()%s{%s  char buf[632];%s  sprintf(buf,a,e,b,d,d,b,e,b,d,d,b,e,b,d,b,b,e,b,a,b,e,e,e,e,e,e,e,e,e,e,e);%s  Serial.println(buf);%s  PORTB ^= (1 << 5);%s  delay(1000);%s}"
void setup()
{
  Serial.begin(115200);
  DDRB |= (1 << 5);
}
void loop()
{
  char buf[632];
  sprintf(buf,a,e,b,d,d,b,e,b,d,d,b,e,b,d,b,b,e,b,a,b,e,e,e,e,e,e,e,e,e,e,e,e,e);
  Serial.println(buf);
  PORTB ^= (1 << 5);
  delay(1000);
}

For the Arduino Mega, the port access statements that define the LED pin need to be changed to PB7 instead of PB5:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define d "\"
#define e "rn"
#define b """
#define a "%s#define d %s%s%s%s%s#define e %s%sr%sn%s%s#define b %s%s%s%s%s#define a %s%s%s%svoid setup()%s{%s  Serial.begin(115200);%s  DDRB |= (1 << 7);%s}%svoid loop()%s{%s  char buf[632];%s  sprintf(buf,a,e,b,d,d,b,e,b,d,d,b,e,b,d,b,b,e,b,a,b,e,e,e,e,e,e,e,e,e,e,e);%s  Serial.println(buf);%s  PORTB ^= (1 << 7);%s  delay(1000);%s}"
void setup()
{
  Serial.begin(115200);
  DDRB |= (1 << 7);
}
void loop()
{
  char buf[632];
  sprintf(buf,a,e,b,d,d,b,e,b,d,d,b,e,b,d,b,b,e,b,a,b,e,e,e,e,e,e,e,e,e,e,e,e,e);
  Serial.println(buf);
  PORTB ^= (1 << 7);
  delay(1000);
}

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>