Changes

Elbex Camera project

16,959 bytes added, 04:44, 15 December 2016
Created page with " So far so good, the cam can be seen on the [[Webcams]] page. == Ingredients == [[Image:Elbex EXC97-9.jpg|thumb|left|500px|The Elbex ECX97-9 PTZ camera]]<br> Image:Camera..."

So far so good, the cam can be seen on the [[Webcams]] page.

== Ingredients ==
[[Image:Elbex EXC97-9.jpg|thumb|left|500px|The Elbex ECX97-9 PTZ camera]]<br>
[[Image:Camera enclosure.jpg|thumb|left|500px|weatherproof enclosure]]<br>
[[Image:Camera in enclosure.jpg|thumb|left|500px|The camera sittting in the enclosure]]<br>
[[Image:Raspberry Pi.jpg|thumb|left|500px|Raspbery Pi as controller]]<br>
[[Image:USB to RS422 converter.jpg|thumb|left|500px|USB to RS422 converter]]<br clear=both>
[[Image:EasyCap frame grabber.jpg|thumb|left|500px|EasyCap frame grabber]]
This grabber comes in multiple flavors, the one I received is based on the USBTV007. I was not able to get this to work on the RPi, hence this item is replaced by a IP-based video grabber, with [http://www.aviosys.com/downloads/manuals/video/9100a.pdf the manual at this link].<br clear=both>
[[Image:Photo Apr 15, 21 17 04.jpg|thumb|left|500px|IP Video 9100A]]
This required a firmware update to yoics firmware, as described [http://support.yoics.com/viewtopic.php?t=152&sid=dffb4e3774acf9a9a07eb5070538d6b2 in this thread]. Not everything was correct, the installed web interface had no way to upload new firmware (as indicated in the thread). http://<cam.ip.add.ress>/System.htm had the necessary controls and allowed the upload to start. However no progress was indicated. After about an hour or more I disconnected the device (fully expecting that it was going to be bricked), and --big surprise-- the new yoics firmware was installed. A detailed listing of camera comands is [http://www.campworld.net/thewiki/pmwiki.php/HWHacking/Aviosys9100 at this link].<br clear=both>
[[Image:Photo Apr 16, 16 28 16.jpg|thumb|left|500px|Ethernet usb pigtail]]<br clear=both>
[[Image:Powered USB hub.jpg|thumb|left|500px|powered USB hub]]<br clear=both>
[[Image:24V to 5V stepdown converter.jpg|thumb|left|500px|stepdown converter to supply power for Raspi and USB devices]]<br>
[[Image:24V power supply.jpg|thumb|left|500px|24V power supply for the camera and the 5V converter]]<br clear=both>

== Hardware build ==
[[Image:Enclosure with hole for camera dome.jpg|thumb|left|800px|after drilling the hole for the camera dome]]<br clear=both>

[[Image:Camera schematics.jpg|thumb|left|800px|overall schematics]]<br clear=both>

After it became clear that the RPi has trouble with USB video capture (not enough USB bandwidth), the re-design now uses a BNC to IP converter. The RPi will proxy the created MJPEG stream to a common web interface.

[[Image:Photo Apr 14, 16 49 21.jpg|thumb|left|800px|overall schematics]]<br clear=both>

== Software implementation ==

=== Operating system setup and configuration ===
* Raspbian Wheezy works ? [http://www.raspberrypi.org/forums/viewtopic.php?f=38&t=52244 3rd post]
==== memeruiz usbtv007 userland driver ====
This driver is implemented in python and uses a v4l loopback to connect to userland programs
* install v4l2-loopback [https://github.com/umlaeute/v4l2loopback]
** this creates a video device under /dev
* install python dependancies
** python-libusb1 [https://pypi.python.org/pypi/libusb1]
** python-libv4l2 [https://pypi.python.org/pypi/v4l2]
** numpy [https://pypi.python.org/pypi/numpy]
* install userland driver
** install from [https://github.com/memeruiz/usbtv007 here], follow the instructions there
* install mplayer
** start with ''mplayer tv:// -tv device=/dev/videoX'', where ''videoX'' is the v4l loopback device

This works with high CPU load on the Lenovo laptop in Ubuntu 12.04. Probably won't work on the Pi.

==== building the native driver ====
* the ultimate thread to build the driver [https://github.com/gkaindl/ambi-tv/issues/7 appears to be at this link]

=== Video capture ===
* some hints building ambi-tv at [https://github.com/gkaindl/ambi-tv this link]
* a ton of good info: [http://wiki.ubuntuusers.de/EasyCAP_DC60_USB_Audio_und_Videograbber]
* getting the driver to work: [http://linuxtv.org/wiki/index.php/Easycap#Making_it_work_4]
* testing and userland stuff [http://wiki.ubuntuusers.de/Videograbbing]

==== IP Video 9100A ====
* by default, the new firmware only displayed black and white images or mjpeg. Only after setting this to a single channel ( <pre>http://<ip>/SetChannel.cgi?Channel=257</pre> for the 1st channel ) did the images and the mjpeg stream display in color.
* installed lighttpd as per [http://www.penguintutor.com/linux/light-webserver these instructions]. Basically:
sudo apt-get install lighttpd
sudo apt-get install mysql-server
sudo apt-get install php5-common php5-cgi php5
sudo apt-get install php5-mysql
sudo lighty-enable-mod fastcgi-php
sudo service lighttpd force-reload</pre>

* added proxy directive to config file in ''/etc/lighttp''
$HTTP["host"] =~ "cam03.home.hentschel.net" { # hostname you want to create
proxy.server = ( "" =>
(
(
"host" => "192.168.2.10", # where you want to proxy to
"port" => 80, # port you want to proxy to
)
)
)
}
* the URL <pre>http://<ip>/Jpeg/CamImg.jpg</pre> gets a current snapshot
* the URL <pre>http://<ip>//GetData.cgi</pre> is supposed to get a mjpeg stream. However, the current proxy settings of lighttp swallow that URL (somehow disable the .cgi extension?) '''Correction:''' Works on FF (Chrome only supports mjpeg in a <img> tag)

=== Camera motion control ===
==== Elbex RS422 protocol ====
<pre>
Protocol to control Elbex cameras through RS422. As you can see, all the codes are in hex form:

PAN LEFT: F8 1F 00 30
PAN RIGHT: F8 1F 00 28
TILT DOWN: F8 1F 00 24
TILT UP: F8 1F 00 22
ZOOM TELE: F8 1F 00 21
ZOOM WIDE: F8 1F 80 20
FOCUS NEAR: F8 1F 40 20
FOCUS FAR: F8 1F 20 20

IRIS AUTO F8 1F 44 40
IRIS MANUAL F8 1F 54 40
IRIS CLOSE F8 1F 10 20
IRIS OPEN F8 1F 08 20

RECALL PRESET 1 F8 1F 01 41
RECALL PRESET 2 F8 1F 02 41
RECALL PRESET 3 F8 1F 03 41
RECALL PRESET 4 F8 1F 04 41
RECALL PRESET 5 F8 1F 05 41
RECALL PRESET 6 F8 1F 06 41
RECALL PRESET 7 F8 1F 07 41
RECALL PRESET 8 F8 1F 08 41
RECALL LAST POSITION F8 1F 00 41

SET PRESET 1 F8 1F 01 42
SET PRESET 2 F8 1F 02 42
SET PRESET 3 F8 1F 03 42
SET PRESET 4 F8 1F 04 42
SET PRESET 5 F8 1F 05 42
SET PRESET 6 F8 1F 06 42
SET PRESET 7 F8 1F 07 42
SET PRESET 8 F8 1F 08 42

PAN SPEED 1 F8 1F 01 40
PAN SPEED 2 F8 1F 02 40
PAN SPEED 3 F8 1F 03 40
PAN SPEED 4 F8 1F 04 40
PAN SPEED 5 F8 1F 05 40
PAN SPEED 6 F8 1F 06 40
PAN SPEED 7 F8 1F 07 40
PAN SPEED 8 F8 1F 08 40

TILT SPEED 1 F8 1F 11 40
TILT SPEED 2 F8 1F 12 40
TILT SPEED 3 F8 1F 13 40
TILT SPEED 4 F8 1F 14 40
TILT SPEED 5 F8 1F 15 40
TILT SPEED 6 F8 1F 16 40
TILT SPEED 7 F8 1F 17 40
TILT SPEED 8 F8 1F 18 40

POWER ON RESET F8 1F F0 40 FD 40
ALL CLEAR F8 1F F0 40 FE 40

Transmission format:

Method: all dual pace synchronization
Speed: 4800 bps
Data length: 8 bit
Setting: no parity, start 1 bit, stop 1 bit, no flow control.

Sending the command once will move the camera only one step; to move continuously send the command repeatedly.
</pre>

Example using command line:

set up comm:
<pre>stty -F /dev/ttyUSB0 speed 4800 cs8 -cstopb -parenb</pre>

send a PAN LEFT command:
<pre>echo -en '\xF0\x1F\x00\x30' > /dev/ttyUSB0</pre>
* -e interprets hex string
* -n does not add newline at end

initial script
<pre>
#!/bin/bash
#/bin/stty -F /dev/ttyUSB0 speed 4800 cs8 -cstopb -parenb
#echo -en '\xF8\x1F\x00\x30' > /dev/ttyUSB0; sleep 0.1;

left= '\xF8\x1F\x00\x30'
right= '\xF8\x1F\x00\x28'
down= '\xF8\x1F\x00\24'
up= '\xF8\x1F\x00\22'
tele= '\xF8\x1F\x00\21'
wide= '\xF8\x1F\x80\20'
near= '\xF8\x1F\x40\20'
far= '\xF8\x1F\x20\20'


move ()
{
COUNTER=0
while [ $COUNTER -lt $2 ]; do
echo -en $1 > /dev/ttyUSB0; sleep 0.1;
let COUNTER+=1;
done
}


case "$1" in
left)
move $left $2
;;

right)
move $right $2
;;
down)
move $down $2
;;

up)
move $up $2
;;
tele)
move $tele $2
;;

wide)
move $wide $2
;;
near)
move $near $2
;;

far)
move $far $2
;;
*)
echo $"Usage: $0 {left|right|} times"
exit 1

esac
</pre>

It turns out that the shitty USB support of the RPi - well known by now - puts a dent into the project: After a few move commands, the RPi just freezes and needs a power-cycle reboot. Looks as even for the simplest tasks, the RPi isn't of much use. There are rumors in some of the forums that FreeBSD as well as ArchLinux may behave a tad better. FreeBSD is what I'll try next.

=== FreeBSD implementation ===
* install FreeBSD as per [https://wiki.freebsd.org/action/recall/FreeBSD/arm/Raspberry%20Pi this page]
* before doing anything else, reboot twice. This will expand the root partition to the disk size, which enables installing ports.
* if you see random boot errors with ''error 19'' (esp. if not power cycling), add '''hw.bcm2835.sdhci.hs=0''' to ''/boot/loader.conf'' [http://lists.freebsd.org/pipermail/freebsd-arm/2013-August/006424.html]
* install lighttp as per [http://www.cyberciti.biz/tips/howto-install-lighttpd-on-freebsd.html these instructions] - this will take quite awhile
* I wound up using sqlite and php5
* some helpful hints are also [http://www.palebluedot.nl/jml/computer-stuff/3-linux/33-webcam-streaming-with-raspberry-pi.html at this link]
* after installing bash, setting up lighttp as proxy, and porting the control scripts to FreeBSD, we're in business. The FreeBSD serial driver works like a charm
* however, driving the serial commands via bash, and starting external commands to talk to the serial port makes things very slow
* re-implement the control scripts for the camera in Perl, here the script
<pre>
use strict;
#use Time::HiRes;
# Define command map
my %commandMap =
(
left => "\xF8\x1F\x00\x30",
right => "\xF8\x1F\x00\x28",
down => "\xF8\x1F\x00\x24",
up => "\xF8\x1F\x00\x22",
tele => "\xF8\x1F\x00\x21",
wide => "\xF8\x1F\x80\x20",
near => "\xF8\x1F\x40\x20",
far => "\xF8\x1F\x20\x20",
tspeed => "\xF8\x1F\x17\x40",
pspeed => "\xF8\x1F\x07\x40",

sp01 => "\xF8\x1F\x01\x42",
sp02 => "\xF8\x1F\x02\x42",
sp03 => "\xF8\x1F\x03\x42",
sp04 => "\xF8\x1F\x04\x42",
sp05 => "\xF8\x1F\x05\x42",
sp06 => "\xF8\x1F\x06\x42",
sp07 => "\xF8\x1F\x07\x42",
sp08 => "\xF8\x1F\x08\x42",

rp01 => "\xF8\x1F\x01\x41",
rp02 => "\xF8\x1F\x02\x41",
rp03 => "\xF8\x1F\x03\x41",
rp04 => "\xF8\x1F\x04\x41",
rp05 => "\xF8\x1F\x05\x41",
rp06 => "\xF8\x1F\x06\x41",
rp07 => "\xF8\x1F\x07\x41",
rp08 => "\xF8\x1F\x08\x41"
);

# Get command line arguments
my ($command, $repeat) = @ARGV;
$repeat = 1 if $repeat == '';

# Do we recognize the command?
if (!exists $commandMap{$command}) {
print "Usage: {left|right|down|up|tele|wide|near|far|tspeed|pspeed} times";
exit;
}

# Open camera serial port
open(CAMERA, ">/dev/ttyU0")
# open(CAMERA, ">camera.log")
or die "cannot open camera serial port: $!";

# Send command to camera
for (my $count = 1; $count <= $repeat; $count++) {
print CAMERA $commandMap{$command};
# Sleep for 0.1 seconds
# Time::HiRes::sleep(0.01);
}

# Close camera serial port
close(CAMERA);
</pre>
* glue script between perl and php (not really needed)
<pre>
#!/bin/tcsh
/usr/bin/perl /usr/local/bin/cam.pl $1 $2
</pre>
* adding php scripts to control via web interface, example script, one each for each command
<pre>
<?php
system('/usr/local/bin/cam left 10');
?>
</pre>
* implementing simple web interface
<pre>
<html>
<head>
<title>Camera</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript">
// send the input to the cgi script
// note: sending 3x the input for every keypress, to make the movement smoother
var submitInput = function(input) {
$.post("/" + input + ".php");
};

// submit input when someone presses a key down
$(document).keydown(function(event) {
console.log(event.keyCode);
switch(event.keyCode) {
case 82:
submitInput('RP01');
break;
case 83:
submitInput('left');
break;
case 68:
submitInput('right');
break;
case 69:
submitInput('up');
break;
case 88:
submitInput('down');
break;
case 37:
submitInput('left');
break;
case 39:
submitInput('right');
break;
case 38:
submitInput('up');
break;
case 40:
submitInput('down');
break;
default:
}
});
</script>
<style type="text/css">
table tr, table td {
border: 1px solid black;
padding: 5px;
width: 25px;
height: 35px;
text-align: center;
}
table {
float: left;
margin: 5px;
}
</style>
</head>
<body>
<div>
<table><tr><td>
<img src="/GetData.cgi"/>
</td></tr></table>
<br clear="both">
<table>
<tr>
<td></td>
<td><a href="#" onClick="submitInput('uleft');">&#9700;</a></td>
<td><a href="#" onClick="submitInput('up');">&#9650;</a></td>
<td><a href="#" onClick="submitInput('uright');">&#9701;</a></td>
<td></td>
</tr>
<tr>
<td><a href="#" onClick="submitInput('leftfast');">&#9664;&#9664;</a></td>
<td><a href="#" onClick="submitInput('left');">&#9664;</a></td>
<td><a href="#" onClick="submitInput('rp01');">&#8962;</a></td>
<td><a href="#" onClick="submitInput('right');">&#9654;</a></td>
<td><a href="#" onClick="submitInput('rightfast');">&#9654;&#9654;</a></td>
</tr>
<tr>
<td></td>
<td><a href="#" onClick="submitInput('dleft');">&#9699;</a></td>
<td><a href="#" onClick="submitInput('down');">&#9660;</a></td>
<td><a href="#" onClick="submitInput('dright');">&#9698;</a></td>
<td></td>
</tr>
</table>
<table>
<tr>
<td><a href="#" onClick="submitInput('telefast');">10x</a></td>
<td><a href="#" onClick="submitInput('tele');">In</a></td>
<td><a href="#" onClick="submitInput('fnear');">Near</a></td>
<td><a href="#" onClick="submitInput('fnearfast');">10x</a></td>
</tr>
<tr>
<td></td>
<td>Zoom</td>
<td>Focus</td>
<td></td>
</tr>
<tr>
<td><a href="#" onClick="submitInput('widefast');">10x</a></td>
<td><a href="#" onClick="submitInput('wide');">Out</a></td>
<td><a href="#" onClick="submitInput('ffar');">Far</a></td>
<td><a href="#" onClick="submitInput('ffarfast');">10x</a></td>
</tr>
</table>
<table>
<tr>
<td><a href="#" onClick="submitInput('rp01');">1</a></td>
<td><a href="#" onClick="submitInput('rp02');">2</a></td>
<td><a href="#" onClick="submitInput('rp03');">3</a></td>
</tr>
<tr>
<td><a href="#" onClick="submitInput('rp04');">4</a></td>
<td><a href="#" onClick="submitInput('rp05');">5</a></td>
<td><a href="#" onClick="submitInput('rp06');">6</a></td>
</tr>
<tr>
<td><a href="#" onClick="submitInput('rp07');">7</a></td>
<td><a href="#" onClick="submitInput('rp08');">8</a></td>
<td></td>
</tr>
</table>
</div>
</body>
</html>
</pre>


=== Automated daily reboot ===
The cam tends to hang every three or so days, and I have been unable to find out why. All the indications point towards the IP Cam server, but even the RPi stops responding after a few days to ping. As a stop gap measure, a automated daily restart needs to be implemented, which can be started via the FreeBSD cron daemon. In order to also reboot the video server, the following command was found in the html source of its web interface:

http://<cam.host.name.or.ip>/Reboot.cgi?RebootNow=1

This restarts the video server.
Rebooting the entire camera also disconnects any clients that have been "hanging on" for longer than necessary.
Bureaucrat, administrator
963
edits