Executing Gummiworms The trials and tribulations of a grumpy curmudgeonly old git

31Mar/130

OSHW Document Jam

oshw-logo-200-pxIn 26 days, the weekend of April 26th the OSHWA, Open Source Hardware Association, is holding a Document Jam at ITP-NYU in NYC to help standardize and improve the how Open Source Hardware projects are documented so that others can replicate them and so that future generations of hackers, tinkerers and makers won't lose the knowledge previous generations have discovered. Unfortunately i'll probably not be able to make it and I really don't have the skills that will be needed as although I am often asked to help friends by proof reading and idiot proofing, I am darn good at it too even if I do say so myself, My super power is that i'm a tiny bit of an OCD pedant when it comes to typos & grammer in other peoples documents. I really don't have any hardware skills other than following instructions and even then it'll probably take me a few goes to get it right & even though I could probably help with some of the documentation and design stuff I really don't do well in crowds so Hack-a-thons & Jams are things I try to avoid. I can cope with crowds in large open spaces but i'd be a gibbering wreak anywhere else.

However if you think you can contribute, the problem statement is here and the how to contribute is here and if you have an account on Trello you can help with some of the pre-event stuff here. I'm not seeing many people using the Trello board so if you think you can help check it out and start using it.

The Guidelines for Participation to the First OSHW Doc Jam can be found here

 

Share
23Mar/130

RaspberryHunt Part 2

CAM00148The stepper motor I want to use to move the TSL2561 sensor along a track arrived on Thursday and i've wired it up and tested it and it works very well for what I want however, i'm going to be busy for a few days so i'll not be able to build the track, case and transfer the circuits to veroboard until next weekend at the earliest. So rather than leave anyone hanging if they are interested in this I thought i'd write up what I have so far so they can replicate it if they want.

As far as the hardware is concerned what I did was combine two circuits available from Adafruit. The "using an L293D" circuit from lesson 10 by Simon Monk   and a RaspberryPi'd version of the circuit wiring the TSL2561 by LadyAda and just for kicks bunged an LED on the Raspberry Pi's GPIO pin 21. As you can see from the photo below (and above) it is a bit of a rat's nest but it worked first time so I have to be doing something right especially as so far touch wood no computers have yet been harmed.

CAM00146
Once I move this to veroboard the TSL2561 board & the LED will be put on a small piece of veroboard with some longish wires mounted on a track to be moved along it by the stepper motor and the stepper motor circuit will be mounted on to of the Raspberry Pi somehow.

For the software I used a slightly modified & wiringPi'd & C'd version of Adafruit's Arduino TSL2561 C++ code, the header & the functions, along with Gordon Drogon's wiringPi library and knocked up a very quick & dirty program that sort of works well enough for testing.

pi@raspberrypi ~/raspberryhunt $ cat raspberryhunt.c
/**************************************************************
* RaspberryHunt version 0.4a *
* By Russell "ukscone" Davis *
* 2013-03-22 *
* Portions Copyright Adafruit, wiringPi is GPL3 Gordon Drogon *
***************************************************************/
#include
#include
#include
#include

#include "Adafruit_TSL2561.h"
#include "wiringPi.h"
#include "wiringPiI2C.h"

/* Global Variables */
typedef int bool;
#define true 1
#define false 0

int _fd;
int _addr;
int _gain;
int _integrationtime;
bool _autogain;

#define VER "0.4a"

#define LED_PIN 21
#define ON 1
#define OFF 0
#define setupLed pinMode
#define led digitalWrite

#define ENABLE_PIN 18
#define COIL_A_1_PIN 4
#define COIL_A_2_PIN 17
#define COIL_B_1_PIN 23
#define COIL_B_2_PIN 24

#define gpioDirection pinMode
#define powerCoil digitalWrite

/* Stepper Motor Handling */

void setupStepperMotor(void) {
gpioDirection(ENABLE_PIN, OUTPUT);
gpioDirection(COIL_A_1_PIN, OUTPUT);
gpioDirection(COIL_A_2_PIN, OUTPUT);
gpioDirection(COIL_B_1_PIN, OUTPUT);
gpioDirection(COIL_B_2_PIN, OUTPUT);
}

void doStep(int s1, int s2, int s3, int s4) {
powerCoil(COIL_A_1_PIN, s1);
powerCoil(COIL_A_2_PIN, s2);
powerCoil(COIL_B_1_PIN, s3);
powerCoil(COIL_B_2_PIN, s4);
}

void stepForward(int delay_ms, int steps) {
int i;
for(i=0; i<=steps; i++) {
doStep(ON, OFF, ON, OFF);
delay(delay_ms);
doStep(OFF, ON, ON, OFF);
delay(delay_ms);
doStep(OFF, ON, OFF, ON);
delay(delay_ms);
doStep(ON, OFF, OFF, ON);
delay(delay_ms);
}
}

void stepBackward(int delay_ms, int steps) {
int i;
for(i=0; i<=steps; i++) {
doStep(ON, OFF, OFF, ON);
delay(delay_ms);
doStep(OFF, ON, OFF, ON);
delay(delay_ms);
doStep(OFF, ON, ON, OFF);
delay(delay_ms);
doStep(ON, OFF, ON, OFF);
delay(delay_ms);
}
}

/* TSL2561 Functions (Copied from Adafruit_TSL2561.cpp at https://github.com/adafruit/Adafruit_TSL2561) */
/* enable TSL2561 by setting the control bit to 0x03 */
int enable() {
return wiringPiI2CWriteReg8(_fd, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,\
TSL2561_CONTROL_POWERON);
}

/* turn off the TSL2561 to save power */
int disable() {
return wiringPiI2CWriteReg8(_fd, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, \
TSL2561_CONTROL_POWEROFF);
}

void getData (uint16_t *broadband, uint16_t *ir)
{
enable();

/* Wait x ms for ADC to complete */
switch (_integrationtime)
{
case TSL2561_INTEGRATIONTIME_13MS:
delay(14);
break;
case TSL2561_INTEGRATIONTIME_101MS:
delay(102);
break;
default:
delay(403);
break;
}

/* Reads a two byte value from channel 0 (visible + infrared) */
*broadband = wiringPiI2CReadReg16(_fd, TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);

/* Reads a two byte value from channel 1 (infrared) */
*ir = wiringPiI2CReadReg16(_fd, TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);

/* Turn the device off to save power */
disable();
}

void setIntegrationTime(int time)
{
enable();

/* Update the timing register */
wiringPiI2CWriteReg8(_fd, TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, time | _gain);

/* Update value placeholders */
_integrationtime = time;

disable();
}

void setGain(int gain) {

enable();
wiringPiI2CWriteReg8(_fd, TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integrationtime | gain);
_gain = gain;
disable();
}

void enableAutoGain(bool enable)
{
_autogain = enable ? true : false;
}

uint32_t getFullLuminosity()
{
enable();

switch (_integrationtime)
{
case TSL2561_INTEGRATIONTIME_13MS:
delay(14);
break;
case TSL2561_INTEGRATIONTIME_101MS:
delay(102);
break;
default:
delay(403);
break;
}

uint32_t x;
x = wiringPiI2CReadReg16(_fd,TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
x <<= 16;
x |= wiringPiI2CReadReg16(_fd,TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);

disable();

return x;
}

void getLuminosity (uint16_t *broadband, uint16_t *ir)
{
bool valid = false;

/* If Auto gain disabled get a single reading and continue */
if(!_autogain)
{
getData (broadband, ir);
return;
}

/* Read data until we find a valid range */
bool _agcCheck = false;
do
{
uint16_t _b, _ir;
uint16_t _hi, _lo;
int _it = _integrationtime;

/* Get the hi/low threshold for the current integration time */
switch(_it)
{
case TSL2561_INTEGRATIONTIME_13MS:
_hi = TSL2561_AGC_THI_13MS;
_lo = TSL2561_AGC_TLO_13MS;
break;
case TSL2561_INTEGRATIONTIME_101MS:
_hi = TSL2561_AGC_THI_101MS;
_lo = TSL2561_AGC_TLO_101MS;
break;
default:
_hi = TSL2561_AGC_THI_402MS;
_lo = TSL2561_AGC_TLO_402MS;
break;
}

getData(&_b, &_ir);

/* Run an auto-gain check if we haven't already done so ... */
if (!_agcCheck)
{
if ((_b < _lo) && (_gain == TSL2561_GAIN_1X))
{
/* Increase the gain and try again */
setGain(TSL2561_GAIN_16X);
/* Drop the previous conversion results */
getData(&_b, &_ir);
/* Set a flag to indicate we've adjusted the gain */
_agcCheck = true;
}
else if ((_b > _hi) && (_gain == TSL2561_GAIN_16X))
{
/* Drop gain to 1x and try again */
setGain(TSL2561_GAIN_1X);
/* Drop the previous conversion results */
getData(&_b, &_ir);
/* Set a flag to indicate we've adjusted the gain */
_agcCheck = true;
}
else
{
/* Nothing to look at here, keep moving ....
Reading is either valid, or we're already at the chips limits */
*broadband = _b;
*ir = _ir;
valid = true;
}
}
else
{
/* If we've already adjusted the gain once, just return the new results.
This avoids endless loops where a value is at one extreme pre-gain,
and the the other extreme post-gain */
*broadband = _b;
*ir = _ir;
valid = true;
}
} while (!valid);
}

uint32_t calculateLux(uint16_t broadband, uint16_t ir)
{
unsigned long chScale;
unsigned long channel1;
unsigned long channel0;

/* Make sure the sensor isn't saturated! */
uint16_t clipThreshold;
switch (_integrationtime)
{
case TSL2561_INTEGRATIONTIME_13MS:
clipThreshold = TSL2561_CLIPPING_13MS;
break;
case TSL2561_INTEGRATIONTIME_101MS:
clipThreshold = TSL2561_CLIPPING_101MS;
break;
default:
clipThreshold = TSL2561_CLIPPING_402MS;
break;
}

/* Return 0 lux if the sensor is saturated */
if ((broadband > clipThreshold) || (ir > clipThreshold))
{
return 0;
}

/* Get the correct scale depending on the intergration time */
switch (_integrationtime)
{
case TSL2561_INTEGRATIONTIME_13MS:
chScale = TSL2561_LUX_CHSCALE_TINT0;
break;
case TSL2561_INTEGRATIONTIME_101MS:
chScale = TSL2561_LUX_CHSCALE_TINT1;
break;
default: /* No scaling ... integration time = 402ms */
chScale = (1 << TSL2561_LUX_CHSCALE);
break;
}

/* Scale for gain (1x or 16x) */
if (!_gain) chScale = chScale << 4;

/* Scale the channel values */
channel0 = (broadband * chScale) >> TSL2561_LUX_CHSCALE;
channel1 = (ir * chScale) >> TSL2561_LUX_CHSCALE;

/* Find the ratio of the channel values (Channel1/Channel0) */
unsigned long ratio1 = 0;
if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;

/* round the ratio value */
unsigned long ratio = (ratio1 + 1) >> 1;

unsigned int b, m;

#ifdef TSL2561_PACKAGE_CS
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C))
{b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;}
else if (ratio <= TSL2561_LUX_K2C)
{b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;}
else if (ratio <= TSL2561_LUX_K3C)
{b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;}
else if (ratio <= TSL2561_LUX_K4C)
{b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;}
else if (ratio <= TSL2561_LUX_K5C)
{b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;}
else if (ratio <= TSL2561_LUX_K6C)
{b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;}
else if (ratio <= TSL2561_LUX_K7C)
{b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;}
else if (ratio > TSL2561_LUX_K8C)
{b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;}
#else
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
{b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
else if (ratio <= TSL2561_LUX_K2T)
{b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
else if (ratio <= TSL2561_LUX_K3T)
{b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
else if (ratio <= TSL2561_LUX_K4T)
{b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
else if (ratio <= TSL2561_LUX_K5T)
{b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
else if (ratio <= TSL2561_LUX_K6T)
{b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
else if (ratio <= TSL2561_LUX_K7T)
{b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
else if (ratio > TSL2561_LUX_K8T)
{b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
#endif

unsigned long temp;
temp = ((channel0 * b) - (channel1 * m));

/* Do not allow negative lux value */
if (temp < 0) temp = 0;

/* Round lsb (2^(LUX_SCALE-1)) */
temp += (1 << (TSL2561_LUX_LUXSCALE-1));

/* Strip off fractional portion */
uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;

/* Signal I2C had no errors */
return lux;
}

/* main() */
void main(void) {
_addr = TSL2561_ADDR_FLOAT;
_fd = wiringPiI2CSetup(_addr);
_integrationtime = TSL2561_INTEGRATIONTIME_402MS;

uint32_t shot;
uint16_t broadband, ir;
int hits;

int forever = true;
int sensitivity = 100; /* this is a percentage */

wiringPiSetupGpio ();
setupLed(LED_PIN, OUTPUT);
setupStepperMotor();

setGain(TSL2561_GAIN_16X);

printf("Welcome to RaspberryHunt version %s\n",VER);
printf("By Russell \"ukscone\" Davis 2013-03-22\n");

uint32_t baseline_lux;
getLuminosity(&broadband, &ir);
baseline_lux = calculateLux(broadband, ir);

hits = 0;

while(forever) {
stepForward(10, 10);
getLuminosity(&broadband, &ir);
shot = calculateLux(broadband, ir);
led(LED_PIN, OFF);
if (shot > (baseline_lux+((baseline_lux/100)*sensitivity))) {
hits++;
led(LED_PIN, ON);
printf("*** Hit *** Current number of hits=%d\n",hits);
}
}
}

As you can see from the video below the stepper motor, sensor & led all work together and once it's all mounted nicely in a pretty case and solid, stable track with some proper software it should be quite good & the same hardware should work for a variety of light based experiments such as my original goal.

YouTube Preview Image

As I said at the top of this post i'm going to be busy with some other projects that have a greater priority for a week to ten days but if anyone has any questions or wants to do something like this drop me a line & i'll try to help.

[note: please don't laugh at the code, i knw it's rubbish but it does what I need for the time being and i'll eventually write a nice pretty SDL version with lots of sound effects and pretty graphics and use events rather than a big loop with individual checks of the sensor & small movements of the motor.]

Share
20Mar/130

RaspberryHunt Part 1

CAM00143About three decades ago I was on work experience in the Physics department at Leicester Poly and in-between watching the IETS (Inelastic Electron Tunneling Spectroscopy) experiments (lots of fun liquid gases to play with) & playing on the Commodore PET & BBC Micros I was assigned the task of automating the Double-slit experiment. In the time I was on work experience I got most of the hardware & software completed, however, due to a slight miscalculation and misreading of the schematic the first two test runs were also the last two test runs as I sent 240v from the mains straight into the BBC Micro and all the magic smoke escaped with a lot of sparks and loud noises. Over the years I have often thought i'd like to revisit the project and do it correctly this time without harming any innocent computers so when I was looking for a project to do to give my brain a break from moderating the Raspberry Pi forums & some things I am doing for friends I remembered the double-slit experiment and decided that the Raspberry Pi would be perfect as even if I made a mistake at most it's only a $35 computer that would have to die.

30 years ago I used a pretty hefty stepper motor, some photodarlingtons & a bucketful of resistors, ic's and odds and sods. When I looked on Adafruit for the parts i'd need I found that it looked like the bucket of parts could be reduced down to a TSL2561 Digital luminosity/lux/light sensor , a L293D Dual H-Bridge driver , a stepper motor , and a few wires. Rather than about £150 worth of parts this time I could get everything for under $30. Unfortunately when I went to place my order everything but the TSL2561 was out of stock so I ordered that & asked for an email when the rest was back in stock (and I was able to order them last Saturday). The TSL2561 arrived on last friday & while I wait for the stepper motor to arrive I was looking for something to do with the TSL2561 to test it and while I was testing it I came up with the idea that rather than automate the double-slit experiment I could make a target shooting game instead and it'd probably be more fun than some dry educational physics experiment :)

So far I have wired up the TSL2561 to the Raspberry Pi's I2C, connected an LED to a GPIO pin on breadboard

raspberryhunt

and written a basic skeleton of the software using Gordon Drogon's wiringPi & Adafruit's Arduino C++ header for the TSL2561 and it seems to work very well YouTube Preview Image. Once the stepper motor arrives i'll wire that up and make the target (the TSL2561) move, make proper PCB for it and add some graphics and sounds.

Rather than using a stepper motor to move the light sensor along a horizontal track you could mount the sensor to Alex Eames Flag waving kit to make a more compact device.

I do seem to have hit one stumbling block that might need a bit of finagling to get around. I was going to use cheap 99cent store "laser" pointers as "guns" but it looks like they might be banned in NYC as a couple of years ago you could get them everywhere in NYC but I went in over 25 99cent stores in the last couple of days & none had them for sale and one store owner said "no! cost much money for ticket" which I take to mean they are now illegal in NYC.

 

[I also did work experience at Leicester Uni & did even more damage to poor innocent computers although this time I was able to fix them so it only cost me one round for the students & head of dept rather than the seven at the Poly]

 

 

 

 

 

 

 

 

 

Share
1Mar/130

Happy Anniversary Raspberry Pi

rp.o_qrcodeA couple of days ago I realized that I hadn't written a blog post in a while and had been working on one about using a "hacked" Vonage vPhone usb dongle on the Raspberry Pi but as today is the 1 year anniversary, I won't say birthday as it was released on the 29th of February of a leap year, of the Raspberry Pi's release into the wild I have decided to just say "a hacked Vonage vPhone works really well on the Raspberry Pi, use the right tools to delete the CD partition and repartition & format & you have a nice orange usb dongle with a headphone jack & Mic input with 256MB of flash storage on it to put your windows, mac & linux IAX/SIP softphones on" and instead write a quick blog post about the Raspberry Pi.

The Raspberry Pi in case you've been living in a cave for the last 18months or so is an approximately credit card sized (i think they are off by a couple of micro-millimeters on one of the dimensions, but don't hold me to that) 700Mhz ARMv6 based SBC with USB, HDMI Out, Composite Out, Audio Out, SD card for storage and OS, in the case of the Model B Ethernet and depending on model & revision 256MB or 512MB of RAM that sells for $25/$35 plus local Tax, Shipping & Handling.

Originally designed by Eben Upton et al for the purposes of halting the decline in the level of programming & engineering skills of students entering the UK's university system, in particular those entering Cambridge as by tradition Cambridge University's courses of study have an extremely compressed time span and if you aren't already at a reasonable level of knowledge & skill you'll never get through it in one piece, and as a side effect increasing the size of the pool of skilled programmers and engineers available to industry. Basically Eben & his colleagues wanted to reproduce the effects of the reasonably easily available tinkerable with Home Micros in the 1980s had for British industry. I think they are not only succeeding with that aim but have also had some unintended consequences. They've created a whole new niche of computing device, the small and tiny usable general purpose computer, spawned several new businesses (and helped others expand), including case manufacturers, add-on board manufacturers and at least a couple of authors. They've also put the Maker community in the spotlight and made the general public aware of it's existence and they've sparked the interest of young and old alike in learning, building and doing things especially together. There is nothing that warms the heart more than seeing a video of a youngster with their father, mother or grandparent building or programming something together and getting it to work.

This time last year I wrote a quick blog post about how the Raspberry Pi launch broke the internet :)  http://russelldavis.org/2012/02/29/how-to-break-the-internet-in-10-easy-steps/ This year the blog post should really be titled "How the Raspberry Pi saved the world", over dramatic i know but  in some ways it does feel like it.

So Bravo Eben, David, Pete, Jack, Alan, Robert and not forgetting  Liz, Mooncake, James, James, Dom, Alex, Clive, Gordon & Rob

See you this time next year.

 

Share
23Jan/130

Whose Raspberry Pi is online (or any other XMPP enabled device)

xmpp-raspiMany years ago, around 2001/2 to be precise ralphm made something called the Jabber World Map, and the Jabber fish bowl and the Jabber Christmas Tree and the ..., [see http://ralphm.net/worldhttp://ralphm.net/ ] , and at least two Jabber IM clients, BuddySpace & Tkabber had functions where your contact list could be displayed as a map or graphic.  

Unfortunately BuddySpace & ralphm's web maps haven't been updated in several years & Tkabber hasn't had a stable release in about 3 years although the svn version does run very well on the Raspberry Pi. We do have something very similar to ralphm's Jabber World Map with @Ryanteck's RasTrack, which is very good.Screen Shot 2013-01-23 at 1.07.21 PMBut it isn't quite what I want as I want to have something can be private to me, or my group and can be used  at a variety of levels, house, building, club, village, town,... or with non-traditional maps and is easy to setup, deploy & take down (if it's only to be used for a short time).

The Prosody XMPP server that I talked about it an earlier post is perfect to do something like this as not only does it run very well on the raspberry Pi, is easy to setup, it comes with a 3rd party webpresence module that only requires installing into your modules directory, editing a config file and restarting the Prosody server and it's ready to use.

The mod_webpresence module is not part of the Prosody core so you'll need to  download it from http://code.google.com/p/prosody-modules/wiki/mod_webpresence (If you are using the stable Prosody, version 8.2, from the raspbian repos due to API changes between the stable and unstable branch you'll need to use the 8.x compatible version from  http://0-8.prosody-modules.googlecode.com/hg/ . which unfortunately isn't quite as good as the version for use with unstable prosody but it'll do the job although some of the nicer things such as user supplied icons don't work). If you are using the 0.9 branch of prosody copy the icons/ directory & the mod_webpresence.lua file to your prosody modules directory, if you are using the 8.x branch then just copy the mod_webpresence.lua file. The modules directory will be in one of several locations depending on on you installed Prosody. If you installed it from the raspbian repos then it'll be in /usr/lib/prosody/modules, if you installed from source then it'll probably be in /usr/local/lib/prosody/modules or if you changed the prefix when building and installing then it'll be in [prefix]/lib/prosody/modules e.g. /home/ukscone/prosody-0.9/lib/prosody/modules

Once you have copied the module you'll need to edit the config file for the prosody VirtualHost, in my case I added the line

"webpresence"; to the modules_enabled section in birstall.leicestershire.lan.cfg.lua

 

modules_enabled = {
"roster"; -- Allow users to have a roster. Recommended ;) 
 "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
 "tls"; -- Add support for secure TLS on c2s/s2s connections
 "dialback"; -- s2s dialback support
 "disco"; -- Service discovery
 "private"; -- Private XML storage (for room bookmarks, etc.)
 "vcard"; -- Allow users to set vCards
 "version"; -- Replies to server version requests
 "uptime"; -- Report how long server has been running
 "time"; -- Let others know the time here on this server
 "ping"; -- Replies to XMPP pings with pongs
 "register"; -- Allow users to register on this server using a client and change passwords
 "adhoc"; -- Support for "ad-hoc commands" that can be executed with an XMPP client
 "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
 "posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
 "announce"; -- Send announcement to all online users
 "welcome"; -- Welcome users who register accounts
 "motd"; -- Send a message to users when they log in
 "legacyauth"; -- Legacy authentication. Only used by some old clients and bots.
 "webpresence";
};

Once you've added the line to *.cfg.lua for your server, restart Prosody and test it using the webpresence url.

Screen Shot 2013-01-23 at 2.09.07 PMScreen Shot 2013-01-23 at 2.09.23 PMScreen Shot 2013-01-23 at 2.09.38 PMNow you know that it is working for one user you can now create a webpage to display the presence status for several users. In theory Prosody has a module to act as a webserver for static html files however i've never been able to get it to work correctly so I installed apache2 on my my raspberry pi but any method of serving webpages will do as long as it can "see" the url that the webpresence module produces. My html skills are very bad, non-existant, consist of being able to cut & paste and add text so I knocked up a simple webpage that uses a graphic of the floorplan of my apartment and uses absolute positioning to position the icons. [note: i know it's rubbish html & probably the wrong way to do it so you don't need to tell me :) ]

 

<html>
<head>
<style>
html {
 background: url(floorplan.png) no-repeat center center fixed;
 -webkit-background-size: 400px 600px;
 -moz-background-size: 400px 600px
 -o-background-size: 400px 600px;
 background-size: 400px 600px;
 background-color: #0c47ef;
}
.tooltip {
 border-bottom: 1px dotted #000000; color: #000000; outline: none;
 cursor: help; text-decoration: none;
 position: relative;
 }
 .tooltip span {
 margin-left: -999em;
 position: absolute;
 }
 .tooltip:hover span {
 border-radius: 5px 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; 
 box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1); -webkit-box-shadow: 5px 5px rgba(0, 0, 0, 0.1); -moz-box-shadow: 5px 5px rgba(0, 0, 0, 0.1);
 font-family: Calibri, Tahoma, Geneva, sans-serif;
 position: absolute; left: 1em; top: 2em; z-index: 99;
 margin-left: 0; width: 250px;
 }
 .tooltip:hover em {
 font-family: Candara, Tahoma, Geneva, sans-serif; font-size: 1.2em; font-weight: bold;
 display: block; padding: 0.2em 0 0.6em 0;
 }
 .classic { padding: 0.8em 1em; }
 * html a:hover { background: transparent; }
 .classic {background: #FFFFAA; border: 1px solid #FFAD33; }
</style>
</head>
<body>
<center><h1>Who is home & online?</h1></center>

<div style="position:absolute; top:540; left:500;">
<a class="tooltip" href="#">
<img src="http://birstall.leicestershire.lan:5280/status/linda/" />
Linda
<span class="classic">Linda</span>
</a>
</div>
<div style="position:absolute; top:100; left:500;">
<a class="tooltip" href="#">
<img src="http://birstall.leicestershire.lan:5280/status/john/" />
John
<span class="classic">John</span>
</a>
</div>
<div style="position:absolute; top:400; left:500;">
<a class="tooltip" href="#">
<img src="http://birstall.leicestershire.lan:5280/status/admin/" />
Russell
<span class="classic">Russell</span>
</a>
</div>
</body>
</html>

which gives me a webpage that looks vaguely like this.
Screen Shot 2013-01-23 at 2.15.39 PM
If you have better css/html skills then you can do all sorts of fun & fancy things and you can use any background graphic you like, say the map of your school, town, a Christmas tree, ... Of course for anyone on your map/graphic to appear as online they'll need to be signed in to your prosody server using an IM client that supports XMPP or have an XMPP bot running on their Raspberry Pi. Most modern multiprotocol IM clients support XMPP, including, but not limited to pidgin, adium, centerim, IM+ and there are serveral XMPP clients that run very well on the Raspberry Pi including Tkabber. You could also write an XMPPBot for people to run on their Raspberry Pi, there are several XMPP libraries available for languages like Python, lua, php,... that make it very easy to write your own bot or client. A quick google will lead you to them. This doesn't scale that well, probably no more than a couple of hundred users max but it is very flexible and will do for smaller (semi-)private groups and there is lots of room for improvement and hacking and doing fun things with.

[note: if you are using the 0.9+ branch of prosody & the mod_webpresence module you can change the icons in the icons directory that the webpresence module uses, if you are using 8.x branch then the icons are "hardcoded" into the lua source of the module so changing them isn't just a case of dropping them into the icons directory and you can read more about the Prosody, the  webpresence module, and the other modules available at http://prosody.im/ &  http://code.google.com/p/prosody-modules/wiki/mod_webpresencehttp://code.google.com/p/prosody-modules/]

Share
18Jan/137

Setting up Prosody on the Raspberry Pi for house/apartment/secret club house-wide chatroom

Screen Shot 2013-01-18 at 5.12.32 PMAlthough I only live with 4 others, wife, son & 2 cats, in a small 5 room apartment most evenings we are in different rooms, or in the summer 3 different floors, wearing headphones chilling to our own choices in music & tv. As I think it's uncouth to yell out of the window or across the apartment to get someone's attention I setup a Raspberry Pi Model B as an XMPP server running MUC. As it's only for 3 people, unless we have visitors, I chose to run Prosody, it's pretty lightweight, easy to setup, the stable version is in the raspbian repos & i've used it before. I've also used and run ejabberd, openfire, tigase, jabberd,... but IMHO they are heavier on resources and a bit harder to setup, and are overkill for my needs and anyway I like lua.

 

As stable Prosody, currently 8.2,  is in the raspbian repos you install it via apt.

sudo apt-get install prosody

which will install (if they are not already installed)

liblua5.1-0 lua-event lua-expat lua-filesystem lua-sec lua-socket prosody
 ssl-cert

Once Prosody is installed you'll need to create a config file & add some users.

First create an admin user for the server. As Prosody is running on birstall.leicestershire.lan, i'll use admin@birstall.leicestershire.lan as my admin account & create it using the prosodyctl utility.

sudo prosodyctl adduser admin@birstall.leicestershire.lan

which will ask you to enter a password for that user (twice)

Enter new password: 
Retype new password:

[As i'm going to disallow in-band registration i also created accounts for my wife & son & a non-admin account for myself after creating the admin account also using prosodyctl. But if you are going to allow users to create their own accounts you can  just skip to creating the config file.]

sudo prosodyctl adduser linda@birstall.leicestershire.lan
sudo prosodyctl adduser john@birstall.leicestershire.lan
sudo prosodyctl adduser russell@birstall.leicestershire.lan

Now you need to create a config file. It's written in lua, but you don't need to know lua to create it as it's pretty human readable.

Create a file in /etc/prosody/conf.avail with the filename of FQDN of the host Prosody is running on and a suffix of .cfg.lua using whatever editor you are comfortable with, in my case I happen to like vi/vim so i'll use that.

sudo vi /etc/prosody/conf.avail/birstall.leicestershire.lan.cfg.lua

My configuration file looks like this.

VirtualHost "birstall.leicestershire.lan" -- FQDN of host server is running on
admins = {"admin@birstall.leicestersire.lan"} -- admin account
modules_enabled = {

                "roster"; -- Allow users to have a roster. Recommended ;) 
                "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
                "tls"; -- Add support for secure TLS on c2s/s2s connections
                "disco"; -- Service discovery
                "private"; -- Private XML storage (for room bookmarks, etc.)
                "vcard"; -- Allow users to set vCards
                "legacyauth"; -- Legacy authentication. Only used by some old clients and bots.
                "version"; -- Replies to server version requests
                "uptime"; -- Report how long server has been running
                "time"; -- Let others know the time here on this server
                "ping"; -- Replies to XMPP pings with pongs
                "adhoc"; -- Support for "ad-hoc commands" that can be executed with an XMPP client
                "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
                "announce"; -- Send announcement to all online users
                "welcome"; -- Welcome users who register accounts
                "motd"; -- Send a message to users when they log in
                "posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
                 --"register"; -- Uncomment to enable mod_register
};
-- allow_registration = true -- Uncomment to llow users to register new accounts
motd_text = [[This is a private xmpp server. if you are not authorized please logoff immediately.]]
welcome_message = [[$username welcome to $host]]
disallow_s2s = true -- This is a private server so no federation
Component "conference.birstall.leicestershire.lan" "muc"
name = "MUC"
restrict_room_creation = admin -- only admin user can create a new MUC

[If you want to allow in-band registration, users can register an account from their XMPP client, uncomment the

"register"; -- Enable mod_register

&

allow_registration = true -- Allow users to register new accounts

lines.]

After you have created & saved the configuration file you need to create a symlink to it in the /etc/prosody/conf.d directory.

sudo ln -s /etc/prosody/conf.avail/birstall.leicestershire.lan.cfg.lua /etc/prosody/conf.d/birstall.leicestershire.lan.cfg.lua

[Change birstall.leicestershire.lan to your hosts name]

And then start Prosody

sudo /etc/init.d/prosody start

Actually you are restarting it as it's already running as you installed it using apt and it'll start automatically when you reboot as well. You can now login to the server, if you are the admin user create muc/chatrooms, im logged in users and do all the other things you can do using xmpp by using any xmpp compliant client such as adium, pidgin, Tkabber, psi, ...

This is just a very simple setup that works for my needs as I don't need to worry about setting up SRV records, portforwarding, federation or even much security. If you want to do a more complicated setup or just read a bit more about XMPP look at these sites.

http://prosody.im

http://xmpp.org

Share
2Jan/130

Patch for Hexxeh’s rpi-update

rp.o_qrcodeHexxeh's rpi-update is a great utility to keep your Raspberry Pi firmware either up to date or on the bleeding edge but over the last couple of weeks it has on occasion been failing and stalling without giving any clue as to what was wrong. After a few days it really started to annoy me so I did a quick search and replace on --quiet to see what the problem was and after turning off the self update function of the script (I forgot to do that and spent 20minutes wondering why my changes weren't being preserved :) ) I discovered that it would sometimes fail on "compressed objects", I'm not sure why other than it's probably just one of those things as on the new run of the script it would normally work. While I was looking through Hexxeh's script I found what I considered a bug, if you choose install a specific commit the .firmware_revision file in /boot isn't updated with that commit value, an annoyance, the script defaults to self updating, and a lack of functionality, the to show error messages. So i've put together a small patch, currently version 3.

 

The changes i've made to Hexxeh's script that is available at https://github.com/Hexxeh/rpi-update are

 

1. Make it default to not updating itself (you can revert to it's old behaviour by using the envvar UPDATE_SELF=1)

2. It now writes the firmware revision of a user selected commit to /boot/.firmware_revision which stops it saying your firmware is up to date when you move from a old commit to the current head.

3. 3 levels, ok 4 if you count silent of verboseness. You select the verboseness using the envvar VERBOSE.

if the envvar doesn't exist or is 0 then the script is as per normal. if VERBOSE=1 then all git & wget commands display their actions, if VERBOSE=2 then you get output from git, wget, tar & cp, and if VERBOSE=3 then you get output from git, wget, tar, cp & rm

 

e.g. if you run rpi-update after applying the patch then

sudo UPDATE_SELF=0 VERBOSE=1 rpi-update

the the script will not update itself if there are changes and it will display the output of git,wget but not  cp, tar &  rm

 

the patch against Hexxeh's rpi-update commit de54b22c4eff6e06fd0e090a84fcdedcbdc1dd28 is here

Share
2Oct/120

A few useful Raspberry Pi bash alias’s

Yesterday someone (not named to protect the wazzock) said their codecs had stopped working and for about an hour we couldn't work out why. Then all of a sudden we worked out why. Case matters to vcgencmd commands doh! mpg2 is wrong MPG2 is right :) so this morning I decided to knock up a couple of oneliners/alias's so that we won't make that mistake again.

WVC1 codec
alias hasVC1='/opt/vc/bin/vcgencmd codec_enabled WVC1 | grep enabled > /dev/null ; RETVAL=$?
[ $RETVAL -eq 0 ] && echo True
[ $RETVAL -ne 0 ] && echo False '

 

MPG2 codec
alias hasMPG2='/opt/vc/bin/vcgencmd codec_enabled MPG2 | grep enabled > /dev/null ; RETVAL=$?
[ $RETVAL -eq 0 ] && echo True
[ $RETVAL -ne 0 ] && echo False '
H.264 codec
alias hasH264='/opt/vc/bin/vcgencmd codec_enabled H264 | grep enabled > /dev/null ; RETVAL=$?
[ $RETVAL -eq 0 ] && echo True
[ $RETVAL -ne 0 ] && echo False '

[these are just quick & dirty alias's but they work so don't knock it :) ]

Share
22Sep/121

Using sshfs on the Raspberry Pi (or how not to wear out your SDCard)

This is just a quick & dirty post as an aide-mémoire for me on how to setup sshfs and in particular on the Raspberry Pi.

On the Raspberry Pi (sshfs client)

sudo apt-get install sshfs fuse fuse-utils libfuse2

sudo usermod -a -G fuse <username>

On the Host computer (sshfs server)

mkdir <directory to mount via sshfs>

On the Raspberry Pi

mkdir <mount point>

sshfs <server username>@<server ip/name>:<directory to mount via sshfs>  <mount point>

 

The above will ask you for a password each time you run sshfs. if you want to use it passwordless then

on the Raspberry Pi

ssh-keygen -t rsa

and press enter to all the questions and copy the ~/.ssh/id_rsa.pub file to the host computer as ~/.ssh/authorized_keys

On the Host Computer

ssh-keygen -t rsa

and press enter to all the questions and copy the ~/.ssh/id_rsa.pub file to the Raspberry Pi as ~/.ssh/authorized_keys

 

once you have setup sshfs do all your compiling on the Raspberry Pi in the <mount point> directory and you'll not be slowly wearing out your SD Card :) . Also a nice side effect of using sshfs is that if you are cross compiling on your host computer you can just copy the programs you build to the directory that is mounted via sshfs and it'll be automagically available on your Raspberry Pi.

Share
25Aug/120

(I HAZ NEW TOYZ :) ) Unpacking a FriendlyARM Mini210S from Industrial ARMWorks Inc.

A couple of weeks a fellow #raspberrypi irc channel user called ReggieUK suggested to those awfully nice chaps at Industrial ARMWorks Inc. that I might be a good person to get sent a FriendlyARM Mini210S (a Samsung S5PV210, based ARM Cortex ™-A8, running at 1GHz with 512MB RAM & 4GB onboard NAND Flash) to play with and break er I mean test, fix & port stuff to and being the awfully nice chaps that they are they agreed and it arrived today. Actually it arrived yesterday but the postman (never) rings once let alone twice so I didn't know until I checked the mailbox in the evening and saw the "we tried to deliver but you ignored us" note. I wandered up to the post office as soon as they were open this morning and picked it up :) and after removing a pair of furry critters from my desk I started to unpack it.

 

 

As well as the actual friendlyarm mini210s they included a few extras like hdmi cable, ethernet cable, sdio wifi card, a camera module, a small prototyping board,... (see i told you they are really nice chaps)

If you buy a mini210s from Industrial ARMWorks they include the touch screen display, power supply & the HDMI cable but I think the sdio wifi card, prototype board & the camera module are additional purchases.

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

The Mini210s can run Android, Linux (yeah i know Android IS Linux but ... :) ) & WinCE 6.0 and comes with Android installed by default.

 

 

 

 

 

 

 

After i've had a bit of a play with Android for a few days i'll be replacing the Android install on the onboard NAND to Linux but for now i'm having fun messing with Android as you'll be surprised to know this is my only Android based device other than my nookcolor which is still running the stock firmwware so is limited to the B&N store for apps.

So far after a few hours playing and messing around i'm really liking the Mini210S and i can think of quite a few projects I can use it for although we all know what one of the first things i'll do after installing Linux on it is build OpenCOBOL for it and run a few benchmarks :) yeah I know i'm completely nuts :)

Share