Android phone as webcam to capture binary clock patterns

A while ago I got a binary clock for my birthday by some college friends (thank you again at this point). When you watch it from the sofa, you can sometimes see it creating some interesting or funny shapes and I wondered how many of them are there.

Sure, you could write a program to generate all combinations but I wanted to make a photo for each of the clock’s states. Since I don’t have a webcam or something more advanced – the idea was to use my android phone.

Searching for an app, I found this really great and easy one IP Webcam which allows you to take shots via HTTP or and directly grab an image from the video buffer. Luckily this was fast enough to make a picture every second. This was not the case when I tried using the auto focus and normal photo mode.

I wrote a little C program to print out seconds and microseconds to analyze the camera’s delay by taking a shot of the screen. The result surprised me a little since the picture was actually from before it was triggered and not after.
The explanation is at hand, the picture from the camera is buffered on the phone or the app and you simple get a snapshot of what is ready at that time.

I’ll just dump the source code of the program to take a shot every second here and with some interesting pictures I found after recording about ten hours. one to ten o’clock.

/* makeshots.c */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

#define MSSLEEP "./mssleep"
#define CAMERA_LATENCY "350000"
#define CAMERA_URL "\"http://192.168.1.112:8080/shot.jpg\""
// printf
#define TIMEFORMAT "%010ld,%06ld"
// strftime
#define OUTTIMEFORMAT "%H_%M_%S"

#define MINUTE 60l
#define HOUR (60l * MINUTE)
// 86_400 pictures per 24 hours
#define RUNTIME (10l * HOUR + MINUTE)
#define LOOPWAIT_MS 2000

void shoot() {
  char shoot_cmd[256];
  char timestamp[128];
  struct tm tmine;
  time_t rawtime;

  time (&rawtime);
  localtime_r(&rawtime, &tmine);

  strftime(timestamp, 128, OUTTIMEFORMAT, &tmine);
  snprintf(
    shoot_cmd,
    256,
    "("MSSLEEP" "CAMERA_LATENCY"; curl -s -S "CAMERA_URL" -o out/%s.jpg 2>> curl.log) &",
    timestamp
  );
  system(shoot_cmd); // returns immediately
}

int main(int argc, char **argv) {
  struct timeval t;
  struct timezone tz;

  // init
  if (gettimeofday(&t, &tz)) {
    perror("gettimeofday in init failed");
  }
  time_t start_sec = t.tv_sec;
  time_t lastsec   = t.tv_sec;

  while (t.tv_sec - start_sec < RUNTIME) {
    if (gettimeofday(&t, &tz)) {
      perror("gettimeofday in loop failed");
    }
    printf(TIMEFORMAT, (long) t.tv_sec, (long) t.tv_usec);

    // Shoot every second
    if (t.tv_sec - lastsec > 0) {
      lastsec = t.tv_sec;
      shoot();
    }

    usleep(LOOPWAIT_MS);
    // Must be as long as TIMEFORMAT
    printf("\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r");
  }
  printf("\n");
  return EXIT_SUCCESS;
}
/* mssleep.c */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv) {
  if (argc != 2) {
    fprintf(stderr, "%s: <milliseconds>\n", argv[0]);
    return EXIT_FAILURE;
  }

  long ms = atol(argv[1]);
  usleep((useconds_t) ms);
  return EXIT_SUCCESS;
}

I was using C to get a good performance but mostly since it has been a while and I wanted to get my hands on it again. The code runs on mac osx leopard using gcc. curl must be installed.

Advertisements

Annoyme milestone 0.1.0 erreicht

Ich hatte endlich mal wieder ein wenig Zeit und habe beschlossen, dass annoyme den im Wiki definierten milestone 0.1.0 erreicht hat.

Die Änderungen belaufen sich allerdings hauptsächlich auf organisatorische und Paketier-Themen. So war der Milestone definiert als Packaging, documentation, source-forge setup, womit als nächstes dem Ausbau neuer Features nichts mehr im Wege steht.
Die Anwendung ist nun mittels cpack paketierbar und das Ergebnis auch auf der SF Seite verfügbar. Die Projektseite ist https://sourceforge.net/projects/annoyme/ und der Link zum Binary https://sourceforge.net/projects/annoyme/files/

Der Code ist in Github unter dem Tag milestone-0.1.0 oder auf der SF Seite als snapshot verfügbar.

Annoyme

Viele Projekte haben wohl eine Geschichte die dahinter steckt. So auch meine aktuelle kleine Bastelei.

Ich war auf der Arbeit wie immer fleißig am Programmieren und irgendwie ist das Thema aufgekommen, dass ich doch so laut Tippen würde. Ich glaube man könnte mir tatsächlich eine alte mechanische Schreibmaschine unter die Finger legen und würde einfach weiter klimpern.

Daraufhin habe ich jedenfalls entgegnet, dass die Kollegen lieber froh sein sollten, dass ich keine Schreibmaschinensounds, wie im standard ICQ Client, an hätte.

Aus Spass suchte ich nach einem Client unter X der so etwas kann und habe leider nichts gefunden. Ich konnte es kaum verstehen, wo dieses Feature doch derart essenziell ist.

Wie dem auch sei bin ich immer froh wenn ich etwas finde dass es noch nicht gibt – wie oft ist es vorgekommen das ich der Meinung war eine Tolle Idee zu haben und irgendwann feststellen musste, dass es das (leider) schon längst gab. (So wie Instant Messaging über IRC http://www.bitlbee.org/)

Somit habe ich mich nun dran gemacht einen Schreibmaschinensound-Effekt Client für X zu schreiben. Passender weise heißt dieser Annoyme.

Es hat sich herausgestellt, dass das globale empfangen der Tastatur Event nicht ganz so einfach ist wie erwartet aber dank einem funktionierenden XEvIE nun doch möglich ist.

Ich habe mir für das Projekt in C++ einen Account bei github erstellt und werde es darüber pflegen. Ich sehe es als Gelegenheit etwas mehr Erfahrung mit git zu sammeln. Bisher macht es einen relativ benutzerfreundlichen Eindruck.

http://github.com/dedeibel/annoyme/tree/master