Haskell Arduino Serial I/O
Overview
The Arduino is a popular electronics prototyping platform. It is easy to interface to a computer via a real or emulated (Through USB) serial connection. This write-up details how to communicate with the Arduino in Haskell.
Pre-requisites
- Arduino software installed and working.
- Haskell Platform installed with Serial package from Hackage(cabal install serial)
- A program with serial I/O loaded on the Arduino (The PhysicalPixel example that comes with arduino will work)
Send a simple command
import System.Serial import IO serialCommand :: String -> IO () serialCommand comm = do h <- openSerial "/dev/ttyUSB0" B9600 8 One NoParity Software hPutStr h comm
Serial Monitor
- serialMonitor.hs -- Code that acts like the Arduino serial monitor. Handles input and output of data.
Servo and LED Demo
Quick demo of running a servo motor and LED from Haskell using serialMonitor.hs. H turns on the light, L turns it off, the numbers 0-9 are the step to take (0-180) by 20 degree increments. The Arduino sends back a status after each command, saying either the state of the light, or the degree of the servo.
- serialServo.pde -- Arduino code used in this demo. Moves a servo between 0-180 degrees in 20 degree steps, and turns on a light
Video of serialMonitor.hs program running:
Comments(0)
2010-05-23 22:24:04
HDBC-mysql Example
Overview
HDBC-mysql is a way to talk to mysql using Haskell. Like alot of things in Hackage, there isn't alot of demo code, so here is how I've been using it. Besides the initial connection it provides the same functions/types as the rest of HDBC.
Database Setup
Requires the following MySQL setup:
CREATE DATABASE hdbcTest; GRANT ALL ON hdbcTest.* TO hdbc@'%' IDENTIFIED BY 'hdbc'; use hdbcTest; create table test ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), value varchar(255) );
/var/run/mysqld/mysqld.sock
Change as needed.
Haskell Connection
Simple connection and test:
import Control.Monad
import Database.HDBC
import Database.HDBC.MySQL
main = do
conn <- connectMySQL defaultMySQLConnectInfo {
mysqlHost = "localhost",
mysqlPort = 3306,
mysqlUnixSocket = "/var/run/mysqld/mysqld.sock",
mysqlDatabase = "hdbcTest",
mysqlUser = "hdbc",
mysqlPassword = "hdbc"
}
rows <- quickQuery' conn "SELECT 1 + 1" []
forM_ rows $ row -> putStrLn $ show row
Something a little more complicated. Grab the count of entries, insert that count, and then spit out all the values. After the connection is established (ie the bottom of the last example).
rows <- quickQuery' conn "SELECT count(*) from test" []
run conn ("insert into test (value) values" ++
countString rows) []
rows <- quickQuery' conn "SELECT value from test" []
forM_ rows $ row -> putStrLn $ sqlValue row
That increase each time the code is ran.
Full code of the second example is available here: mysqlTest.hs
Comments(0)
2010-04-03 02:24:09
Streamed web images without flickering
Overview
Putting a stream of images on the web, like from a camera, can be painful. Constantly refreshing the page with a meta tag causes flickering, DOM modification requires busting the cache, and without the cache you again get flickering on the image.
Code
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
function upd(count)
{
$("#capImg").html(
'<img width=384px height=288px src="foo.jpg?' +
count + '">');
count ++;
$("#capImgHidden").html(
'<img width=1px height=1px src="foo.jpg?' +
count + '">');
setTimeout("upd(" + count + ");",500);
}
setTimeout("upd(0);",500);
</script>
<html>
<head>
<title>Image Stream</title>
</head>
<body>
<div id="capImg">
<img src="foo.jpg">
</div>
<BR>
<div id="capImgHidden" style:display="none">
<img width=1 height=1 src="foo.jpg?0">
</div>
</body>
</html>
Explanation
- jQuery is used to modify the html on in the javascript. This is done every 500 milliseconds using setTimeout.
- Each call of the upd function has count incremented by one each time. This is then used as part of the image location (foo.jpg?0, foo.jpg?1, foo.jpg?2), making the browser think each one is a separate location and thus bypassing the cache. We are passing in the number as a GET parameter, which is discarded at the server side since foo.jpg is just a normal image and does not take parameters.
- Since we've busted the cache, the browser downloads a fresh copy of the image each time. The time it takes to do that causes flickering. The trick is to load the image with the same name in a hidden area, which is just a 1x1 image (capImgHidden). For example:
- Display foo.jpg?0, hide foo.jpg?1
- Display foo.jpg?1, hide foo.jpg?2
- Display foo.jpg?2, hide foo.jpg?3
- ...
Conclusion
Works well, and isn't that complicated to implement. Really fast rates (Under 100ms on my machine) will still cause flickering even with caching. Also the data source can produce it's own issues, such as slow writing of files resulting in corrupted images being retrieved.
Comments(0)
2010-01-27 03:15:37
Trackmate Software With PS3 Eye and Processing on Windows
Overview
A very quick tutorial for the entire round trip of setting up the PS3Eye getting the Trackmate Tracker working and using it with Processing. It's mainly a collection of links to avoid googling everything :p
Downloads
- Java Runtime Environment -- Install the latest JRE, it is needed for running standalone Processing apps
- PS3Eye Driver -- Install the software. You have to scroll way down on the page to find the link.
- Trackmate Tracker and Tagger -- Download both and unpack them. No installation required, but it is handy to make shortcuts to the executables.
- Processing -- Download and extract. Again, no installation needed.
- LusidOSC -- Download the simulator and Processing bundle. Just extract the files, no need to install anything.
Setting Up
- Start up Processing. You can immediately close it, but you need to verify it works and let it register filetype handles.
- Open up the LusidOSC simulator, and then open any of the PDE files provided by the LusidOSC bundle. You should be able to move the pieces in the simulator and have them work with the sample applications. Close the simulator when you're ready to proceed.
- Go into a DOS prompt (Start Menu->run, type cmd and hit enter) and then navigate to where the PS3Eye test application was installed (For me it's: cd C:\"Program Files"\AlexP) Run the following command: regsvr32 PS3Eye.ax
- Open up Trackmate Tracker and verify that you can see video (Assuming the PS3 eye is connected). Try hitting s if you have multiple cameras and it's not working, or v to change views.
- To setup the Tracker follow the guide
- Now toggle the view(Press v) till it says it's in "Fast Mode", and rerun one of the sample apps in the LusidOSC Processing bundle. And you're done.
Conclusion
This was easy, but took me a while to figure out where to download everything (Especially the PS3Eye stuff :p). The hardware has been much more of a pain, and I will include a write-up of it when I get it working 100%.
Comments(2)
2009-08-09 23:28:04