Showing posts with label raspberry pi. Show all posts
Showing posts with label raspberry pi. Show all posts

Monday, August 3, 2015

8MP Aliexpress ELP Webcam

I've recently been thinking about using the Raspberry Pi for image processing and wanted to use a Logitech C525 web cam that I'd bought earlier in the year.  It quickly became apparent that its resolution was less than expected and although it'd probably be fine, I didn't want the image quality to be the limiting factor of my project.  The next step was to start looking around for cheap web cams on my favourite Chinese sites.

I wanted a reasonable image quality and resolution for a decent price, and luckily enough it turns out that this isn't too hard to find.  A store on AliExpress called Ailipu Technology was selling an ELPCCTV brand 8 MP USB web cam for approximately 85 AUD.  I'll get into the specs later on, but first I want to look at the construction as it differs from a standard retail web cam.

WebCam
ELP-USB8MP02G-L75
The camera is a cubic shape made of an extruded 40 mm aluminium profile with metallic front and back plates.  The camera is mounted to the front plate with a manually adjustable lens protruding out approximately 10mm.

WebCam
Back of Web Cam
The USB cable is removable and is connected with a 4 pin locking connector on the back plate.  I assume this allows easier installation if it's used as a security camera.  Most of the products the company sell are marketed to the security industry.

Connector
Web Cam Connector
At the bottom of the connector in the image above you can just see a small metal ball that's used as part of the locking mechanism.

Connector
Web Cam Connector
The outer part of the connector in the image above is a retractable shell that locks the plug in place when it's inserted.

So now for the specs.  The camera has a claimed resolution of 3264 x 2448 and uses a Sony IMX179 sensor.  It turns out that this seems to be the same sensor used in the Nexus 5 phone from 2013.  The business model that the company appears to use is it to take old excess phone image sensors (could possibly be a lower grade) and re purpose them as web cams.  The sales page claims 15 frames per second at maximum resolution but that seems a little far fetched.  I've only been able to get 2 fps which seems more realistic for a USB limited connection.

Before using the camera I wanted to be certain that the stated resolution was real and not some made up interpolated number.  In the past I've seen webcams that market themselves at the interpolated resolution which in my opinion is a blatant lie.  To do this I found an ISO12233 test chart from Cornell University and used it to verify the cameras specifications.

The process is simple, take some photos of a high quality printed version of the chart, and then analyse the image to observe the resolution limits.  I went to the local office supply store and had an A1 version of the test chart printed for a couple of dollars and then glued it to 600 x 900 mm Masonite panel that had been painted black.

Test Pattern
ISO 12233 Test Chart
As you can see from my test apparatus below, this wasn't going to be a very scientific test.  The test pattern isn't completely perpendicular to the camera, but by doing the test outside I got as much light as possible on the board to take a good image.  For my analysis I'm only testing the vertical resolution just to double check the claims the manufacturer made.

Calibration Setup
Test Set-up
First up is the 8 MP ELP camera with a 3264 x 2448 sized image.

Test Pattern
ELP Camera Test Image
The lines on the vertical resolution test marker start to merge at about the 1400 lines per picture height mark.  As the picture in the image is 1750 pixels high, this mean that the image is a total of  1400*(2448/1750) = 1958 lines high.  This may seem small but it's 80 percent of the stated vertical resolution, and when you consider the non ideal test arrangement, and my eyeballing of the resolution chart, I'm satisfied that the resolution claims are correct.

Test Pattern
ELP Camera Resolution Limit
While I was at it I thought I'd test some other web cams.  First up is the Logitech C525 Auto focus camera.
WebCam
Logitech C525 Web Cam
The test shot is at its maximum resolution of 1392 x 768.

Test Pattern
Logitech C525 Camera Test Image
In this case the markers merge at the 650 lines per picture mark.  As the picture is 600 pixels high this means that there should be 650 * (768/600) = 832 lines in the image.  Once again this is 8 percent higher than the stated resolution and when you take into account the errors in the measurement method, I'm happy that the stated resolution is correct.

Test Pattern
Logitech C525 Camera Resolution Limit
Finally, let's test my old C120 camera.

WebCam
Logitech C120 Web Cam
It produces and image with a resolution of 640 x 480.

Test Pattern
Logitech C120 Test Image
You're going to have to take my word for it, but the test markers merge at about the 350 vertical lines per image mark.  As the picture is 347 pixels high, the total image has a resolution of 350*(480/347) = 484 lines, which agrees with the specified resolution.

Test Pattern
Logitech C120 Camera Resolution Limit
In the end I'm verry happy with the camera it a good resolution and image quality for the price.

Thursday, July 23, 2015

Controlling a USB Relay with a Raspberry Pi

I love the Raspberry Pi.  It allows me to prototype ideas quickly and without too much effort, but one thing I despise is the GPIO.  Maybe despise is too harsh, but it's a clunky way to interface electronics to what is for all intents and purposes a striped down personal computer.  Don't get me wrong, the GPIO needs to be there and I've made use of it before, but if I want to quickly prototype something I have to spend time figuring out how to use it and then I've got jumper wires all over the place.  I much prefer to use devices that are connected to the USB port.  They can be easily reused on other computers and the final solution is much neater.

Recently I've been toying around with a project that needs to switch a load on and off.  It's a low voltage LED light so nothing too complicated, and I have no problem figuring out how to switch the load via a transistor connected to one of the GPIO pins, but everything gets messy and then I have to do up a small prototype board to mount the parts on.  You know what would come in handy?  A USB controlled relay.  Unsurprisingly someone has already thought of that, they're all over eBay and Aliexpress, some are controlled as USB HID devices and some use the good ol' USB to UART method.  I bought a couple of the USB to UART style devices from www.lctech-inc.com to play around with, and at $10 AUD each it's not worth my time to come up with a custom solution.

Electronics
Top Side of PCB
There's not much to the module.  As you can see above it's what you'd expect.  A USB connector, a relay, a set of terminal, and a few electronic components.  When plugged in, you send commands to it over a virtual com port to turn the relay on and off.  There are two status LEDs, one to indicate the device has power and another to indicate the relay is active.  Couldn't be easier.

Electronics
PCB Mounted Relay
The Songle relay used seems to be the de-facto standard in this area of the market.  It's a standard NC/NO relay that can be switched by applying 5 Volts to the coil.  The data sheet isn't too clear but requires 90 mA or less to actuate the relay.  The contact resistance of 100 milliOhm isn't the worst I've seen either.

Between coil & contact - 1500VAC 50/60HZ (1 minute)
Between contacts - 1000VAC 50/60HZ (1 minute)

The relay is sufficiently rated for mains voltage use and has adequate isolation, but I wouldn't use it.  I don't like running mains voltage through random crap I bought off eBay.  Besides that, even if the relay is rated for 10 Amps, I'd be surprised if the tracks on the PCB (hidden under the relay) are up to the job.  The connector definitely looks like it's not rated for that much current.  Based on that, this device will only be used for low voltage medium current applications.

Electronics
CH340T USB to Serial Controller
As mentioned before, the relay is controlled by sending commands over a USB to serial converter.  In this case a CH340T IC is used.  The only data sheet I could find for this chip was in Chinese and wasn't very helpful.  The Raspberry Pi has the drivers by default and I've read that the latest versions of Windows do as well.  Disappointingly, the serial number of the devices aren't set or are unable to be read in Linux.  This has the side effect that you can't connect two of these relays to a computer and deterministically know which relay is which.  In Linux, if two devices are plugged in at once they enumerate at /dev/ttyUSB0 and /dev/ttyUSB1, but you can't be certain that they enumerate in the same order if you reboot.  I'd hoped that I'd be able to tell them apart by reading the serial number of the USB devices, but as they aren't set, no luck.  It doesn't really matter, I only need to use one of them, but if I did need to use 2 devices I could buy a two relay board.

Edit - Bingo.  I think I've found a way to do it by using the physical mapping of the ports.

pi@raspberrypi ~ $ ls -l /dev/ttyUSB0
crw-rw---T 1 root dialout 188, 0 Jul 22 19:46 /dev/ttyUSB0


pi@raspberrypi ~ $ ls -l /sys/dev/char/188:0
lrwxrwxrwx 1 root root 0 Jul 22 20:01 /sys/dev/char/188:0 -> ../../devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3.1/1-1.3.1.3/1-1.3.1.3:1.0/ttyUSB0/tty/ttyUSB0

pi@raspberrypi ~ $ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/5p, 480M
        |__ Port 1: Dev 3, If 0, Class=vend., Driver=smsc95xx, 480M
        |__ Port 3: Dev 5, If 0, Class=hub, Driver=hub/4p, 480M
            |__ Port 1: Dev 7, If 0, Class=hub, Driver=hub/4p, 480M
                |__ Port 3: Dev 20, If 0, Class=vend., Driver=ch341, 12M
                |__ Port 4: Dev 10, If 0, Class=stor., Driver=usb-storage, 480M
            |__ Port 3: Dev 8, If 0, Class=vend., Driver=r8712u, 480M
        |__ Port 5: Dev 9, If 0, Class=HID, Driver=usbhid, 1.5M


The 1-1.3.1.3:1.0 string describes the physical layout of the USB device.  The device is plugged into port three of the first hub which is plugged into port one of the second hub which is plugged into the Raspberry Pi on port 3.  I've highlighted the important bits to make it a bit clearer.  BTW The reason I use two hubs is because I have a USB 3.0 hub connected to the Pi and the USB 1.0 USB to serial converter needs to be connected to a USB 2.0 hub for the pi to see it.  It's a bug with the Pi.

Electronics
Bottom Side of PCB
The quality of the board isn't too bad.  All the SMT parts that are automatically placed have nice clean solder joints, but the hand soldered through hole parts leave a lot to be desired.  There's a lot of flux residue on the board and the pads are too small causing the solder to ball up on the leads resulting in weak joints.  I have to give them points for routing out an isolation slot in the board though.

Operation is pretty self evident.  The SOT-23 transistor Q1 is used to apply current to the coil of the relay.  If you look at the top of the board there's also a reverse biased diode placed across the relay coil to stop back EMF spikes.

Electronics
IC with Markings Scratch Off
The IC on the top handles the USB to serial conversion, but the serial commands still need to be interpreted and used to control the relay.  I assume the IC on the bottom side of the board with its markings removed is some sort of micro-controller to do this.

Controlling the relay is dead simple

You first need to configure the serial port at 9600 baud with a character size of 8 bits.

stty -F /dev/ttyUSB0 speed 9600 cs8

Then you send the command (in hex of course) A0 01 00 A1 to close the contacts

echo -n -e '\xA0\x01\x00\xA1' > /dev/ttyUSB0

Then you send the command A0 01 01 A2 to open the contacts.

echo -n -e '\xA0\x01\x01\xA2' > /dev/ttyUSB0

Tablet and Relay
Testing the Relay
I think these are great for prototyping.  Not only can I use this on a Raspberry Pi, I can use it on a desktop computer or possibly a phone or tablet (not tested).  It's also great for people that are coming from the software world who may not be comfortable interfacing with the GPIO port of the Pi.  They can plug it in and deal with what they know best (software), and within a few minutes control devices like fans, pumps, lights or whatever else you could imagine.

Sunday, July 12, 2015

Raspberry Pi USB Webcam Testing

This post will unfortunately be very short.  I was playing around with a webcam connected to a Raspberry Pi, and just as I was starting to make headway I got sick.  I was using a Logitech C525 to take still images.

webcam
Logitech C525


I got far enough into the project to realize that the camera didn't have enough resolution for what I wanted to do.  So I need to look at other options.

Just to document what I've done I'll include the commands I was using here.  fswebcam was used to take the still images and uvcdynctrl is used to configure the camera, but it's poorly documented and I'm still trying to figure out how to use it.  You may need to install packages to use these commands.


fswebcam  -r 1920x1080 -s brightness=70% -s gain=50% -S 10 test.jpg
uvcdynctrl -L a.txt
uvcdynctrl -s "Focus (absolute)" 220


I promise I'll do better next week.

Sunday, May 10, 2015

The Effect Of Heavy Rain On RDS Message Reception

In a recent post I demonstrated how to log RDS messages from FM radio stations.  As a follow up, I thought I'd share an interesting result I observed while logging data over a two week period.  I set up the equipment as described, and for most of the logging period everything worked as planned.  The receiver decoded around 13 messages per minute, sometimes more, sometimes less, but most importantly the messages were almost error free.

On the last day of logging I checked the progress and noticed that the messages contained a lot of errors, not only that, the number of messages received per minute had dropped to one or two.  I'd like to build suspense, but I knew what was wrong immediately, we were experiencing some of the heaviest rain Brisbane had seen in years.  The rain was degrading the signal from the radio station to a point that still allowed audio to be heard, but prevented decoding of RDS messages.

I thought it'd be cool to create a visual aid to compare historical weather data to the logged RDS messages.  Radar data from www.theweatherchaser.com was added to a graph showing how many messages were received in each 6 minute period over the two week long experiment.  6 minutes was chosen as this is the length of time between radar frames.  The frames for the animation were created using python and matplotlib.
VirtualDub was then used to convert the image sequence into a video.



I wouldn't say that there's a strong correlation between the radar images and the frequency of the received messages.  It's important to remember that the radar only shows rainfall.  There could be cloud cover or lighting strikes effecting the radio transmission that doesn't appear on the radar.  The number Hopefully it's obvious that this isn't a tightly controlled experiment, just a bit of fun. 

The file used to create the above animation can be found here.
It can't be used to recreate the animation as the source data is missing.  When learning how to use matplotlib I had trouble finding out how to do certain things.  I though placing the file here might help someone in same situation in the future.

Saturday, April 18, 2015

Using a Raspberry Pi to Log Songs Played on a Radio Station

I recently came up with an idea that required me to build a device to log the songs played on a radio station.  There are a few ways to go about this, you could scrape the data from their streaming radio service, you could use something like Shazam to identify the songs and record them, or you could use the RDS data encoded in the radio signal.  I decided to go the RDS way.

Nearly everyone is familiar with the RDS data stream even if they don't know it.  Newer car stereos that display the current song playing get this from the RDS data.  The FM radio station is first demodulated.  In this demodulated signal at 57 kHz there is double side-band suppressed carrier that contains the RDS data.

The initial method I chose to receive this signal didn't work.  I planned to use a software defined radio approach using an RTL-SDR dongle and a Raspberry Pi, but I just couldn't get it to work.  After some Googling I came up with Plan B.  Use an FM radio receiver IC that contained an RDS decoder and connect that to a Raspberry Pi.  Luckily, Sparkfun had a breakout board for the si470x that was perfect for the job.

I didn't want this to be a massive project so I grabbed publicly available code and modified it for my purposes.  The code was tested until it could run for long periods without crashing.  There's no exception handling, I just reduced the errors until the system was stable.  I could have spent another couple days making it "perfect", but what's the point, this isn't a product or a permanent installation, it has to run for a week or so and give me usable data, and it's doing that.  Currently at around 45 hours.

The code for this project is available from github.  I urge you to have a read of the README file there it contains more information about the code.



Based on code from


RDS receiver and logger
Raspberry Pi and si470x based RDS receiver/logger
The system above looks complicated, but it really isn't.  The white brick in the lower left is a USB power supply.  The Raspberry Pi is the device at the top left, connected to it by jumper wires is the si470x breakout board.  The Pi is also connected to a USB 3 hub that has a Wi-Fi dongle and a USB 2 hub connected to it.  That may sound strange, but the Pi can't recognise USB 1.1 devices plugged into a USB 3 hub, so you need a USB 2 hub in there to allow the connection of the mouse and keyboard.  Yeah, I could have done this via an SSH terminal, but as I was connecting wires directly to the Pi it just seemed easier to be at the device while I did it.

The software is simple as well.  I modified the original code to just constantly poll the si470x receiver, log the RDS messages with timestamps and station frequency, and then rotate the logs hourly.  The script was also configured to run as a background service on start-up.  So if it loses power, it should just automatically start logging again.

I also planned to run the dropbox_uploader utility on a schedule with a cron job to backup the log files.  I wrote the script to do this, but it seemed easy enough to run it manually every now and then.

Log file
RDS log file
The RF signal chain is important, you need a good signal to get the RDS data.  Even if you can hear the station clearly you still might not be able to receive song names.  The si470x breakout board uses the headphone wiring as the FM radio antenna, just like most phones, if you want the radio to work you have to use some type of headphone.  The presence on a human body also boosts the signal.  This is a nice solution in most cases, but I couldn't sit there wearing headphones for a week.  Well, I could but I don't think I'd have a job at the end of the project.  I guess that'd be a bad thing, maybe.

To get a good signal I took a folded dipole antenna made of ribbon cable I just happened to have and used that, I put it on a table and put some books on the end to stop it rolling up.

Antenna
300 ohm Folded dipole ribbon cable antenna
The folded dipole has a 300 ohm balanced output, but I needed a 75 ohm unbalanced signal, so the antenna was connected to a balun.

Balun
300 - 75 Ohm Balun
To get the coax signal into the breakout board I used a simple adapter.  In terms of impedance matching it's not ideal, but I did the best I could with the rest of the chain so it turned out OK.

coax to 3.5 mm adapter
Coax to 3.5mm plug
Connecting the Raspberry Pi to the si470x breakout board is relatively easy, just be careful GPIO 23 is actually pin 16, don't know who came up with that idea.
Connection Diagram
Add caption
I had a lot of fun with this project. It took a week of coding and fiddling in my spare time to get it working.  I'm pretty happy with that.  I'm usually more self concious about my coding ability, but you know what, who cares.  I made something that does what I want, and if anyone has issues with my code they're more than welcome to improve it and do whatever they want with it.  I'd love that.  That's why it's out there, to help the next person that comes along.