Logitech, Inc. Webcam C270 on Raspberry Pi

Just a small note. I tried to get my Logitech, Inc. Webcam C270 running on an raspberry pi v1 running raspbian wheezy and ran into some problems.

The webcam can be used on linux with the uvcvideo kernel module but using uvccapture did not work for me.

$ dmesg
uvcvideo: Found UVC 1.00 device <unnamed> (046d:0825)
input: UVC Camera (046d:0825) as /devices/.../input/input0
usbcore: registered new interface driver uvcvideo

Running uvccapture:

$ uvccapture
ERROR opening V4L interface
: No such file or directory

Mplayer didn’t work either with various settings – producing green only images.

mplayer tv:// -tv driver=v4l2:device=/dev/video0 -vo png -frames 1

Then I found out there is a limited set of formats your camera can deliver and how to display:

$  v4l2-ctl --list-formats -d /dev/video0
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUV 4:2:2 (YUYV)

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'MJPG' (compressed)
        Name        : MJPEG

Seems like I can capture images in YUYV Format and MJPEG directly. This led me to vgrabbj which seems to be a highly flexible image grabber. The following command works for me:

$  vgrabbj -q 100 -i vga -o jpg -f /tmp/snap.jpg -e -d /dev/video0

So, give vgrabbj a try.

Advertisements

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.