Wednesday, December 28, 2011

Kindle conversion

I got a Kindle for Christmas! (thanks Granny). However like many people I ran into the problem with converting .epub to .mobi where the converted files have huge margins on the left hand side of the screen. After some research I found a series of forum post suggesting various solutions but all of them were very manual processes and I wanted something that would just do it for me.

So what I've got here is a simple shell script that does it all for you. You will need to install calibre since it uses the command line tools from that to do the actual conversion but it will automatically convert and sort the formatting out for you.

I'll probably end up redoing it all in python so that it will work on windows.

mkdir _temp
mkdir converted

for file in "$@"
do
echo "Converting \"$file\""

cp -f "$file" _temp/.

filename=$( echo "$file" | sed 's/^.*\///' )
file_type=$( echo "$filename" | sed 's/^.*\.//' )
new_file=$( echo "$filename" | sed 's/[^.]*$/mobi/' )

# if .epub
if [[ $file_type == "epub" ]]
then
# if the metadata is lacking language information then set it to en
lang_meta=$( ebook-meta "_temp/$filename" | egrep "^Language" )
if [[ !( -n "$lang_meta" ) ]]
then
echo "Changing metadata language"
ebook-meta -l en "_temp/$file" >/dev/null 2>&1
fi

# edit the stylesheet to get rid of the massive gap on the left
unzip -f "_temp/$filename" stylesheet.css >/dev/null 2>&1
sed -i 's/margin-left:.*;/margin-left: 0;/g' stylesheet.css
zip "_temp/$filename" stylesheet.css >/dev/null 2>&1
fi

ebook-convert "_temp/$filename" "_temp/$new_file" > /dev/null
#wine kindlegen "_temp/$filename"

mv -f "_temp/$new_file" converted/.
done

rm -r _temp

Monday, February 14, 2011

NXT and I2C

Lets face it I am a terrible blogger, but no one reads this anyway so who cares.

Anyway recently I had some serious grief getting a Devantech CMPS03 digital compass to work with a Lego NXT. The info doesn't appear to be anywhere else on line and I couldn't find a decent I2C example in nxc.

Here is some basic code showing how to get it working.

#define cmpAddr 0xC0 // Machine address of the compass
#define cmpPort S1 // Port that the compass is plugged in to

byte bufLSWrite[] = {cmpAddr, 0x01, 0xC1}; // Written to the compass... (Compass, give me data from register 1, now)

// Take a compass reading
int compassReading()
{
byte r;
byte outbuf[1];
byte byteNumber;
int result;
byteNumber = 1; // Read byte 1

while (I2CCheckStatus(cmpPort) == STAT_COMM_PENDING);

if (I2CBytes(cmpPort, bufLSWrite, byteNumber, outbuf))
{ r = outbuf[0];
}
else
{ r = -1;
}

result = r;

return result;
}

task main()
{
int reading;
int counter = 0;

SetSensorLowspeed(cmpPort);

while( true )
{ reading = compassReading();

NumOut( 1, LCD_LINE1, counter++, false );
NumOut( 1, LCD_LINE3, reading, false );

Wait(1000);
}
}

This is actually just a stepping stone to getting the sensor to work via NXT++ from my netbook but I'll post that code later.

Wednesday, July 14, 2010

How's this for a project name, "The Doom chair"?

It's been a while and I will be posting details explaining just wtf this project actual is later but for the moment check out video of what I am working on at the moment.

Friday, September 4, 2009

MCP42XXX digital potentiometer

It took me a while to figure out how to use the MCP42100 digital pot ic chips to work. Here is the code I use.


/* Control the MCP42XXX series of digital potentiometers. */
class MCP42XXX
{ protected:
byte ss;
byte clk;
byte mosi;

void spi_transfer( byte val )
{ int i;

digitalWrite( this->clk, LOW );

for( i=1; i<=8; ++i )
{ if( val > 127 )
digitalWrite( this->mosi, HIGH );
else
digitalWrite( this->mosi, LOW );

digitalWrite( this->clk, HIGH );
val = val << 1;
digitalWrite( this->clk, LOW );
}
}

public:
/* Set the ss (Slave Select), clk (clock) and
mosi (Master Output Slave Input) pins. */
MCP42XXX( byte ss, byte clk, byte mosi )
{ this->ss = ss;
this->clk = clk;
this->mosi = mosi;

pinMode( this->ss, OUTPUT );
pinMode( this->clk, OUTPUT );
pinMode( this->mosi, OUTPUT );
digitalWrite( this->ss, HIGH );
digitalWrite( this->clk, HIGH );

this->set( 2, 127 );
}

/* Select the potentiometer to control and set the value.
If pot = 0 set value for potentiometer 0, if pot = 1 set
value for potentiometer 1, if pot = 2 set value for both
potentiometers.
val can go from 0 to 255. */
void set( byte pot, byte val )
{ byte pot_code;

switch( pot )
{ case 0: pot_code = B00010001;
break;
case 1: pot_code = B00010010;
break;
case 2: pot_code = B00010011;
break;
default:
return;
};

digitalWrite( this->ss, LOW );

this->spi_transfer( pot_code );
this->spi_transfer( val );

digitalWrite( this->ss, HIGH );
}
};

Tuesday, August 18, 2009

Laziness

Well it's been a while since I posted, if I'm going to bugger off after only 6 posts I'm probably going to end up doing it again at some point. Anyways! have been working on projects even if I haven't been updating on them.

So hexapod is on hold until I can get some beefier servos but have managed to get a hold of a power wheelchair at long last (I have been after one of these for a while). It's an old one so it doesn't have a 2nd joystick port on it so to get it controlable from an arduino/pc took some work.

The control box is there on the left hand side, it was an old Dynamic which died shortly after I got it so I'm not going into the control system I tried to use since I can only assume I managed to kill the it.

I managed to get a replacement though (don't know who made it). The problem with this new one was that the arduino wasn't able to simulate the output from the joystick on its own.

You can see that the joystick is just two potentiometers at right angles to each other, the difference with this 2nd setup is that the pots are positioned 45 degrees off the direction of travel. It means that each pot is in direct control of one of the motors, from my point of view it makes the code a lot easier. But the way that the rest of the control box uses the current flowing through the joystick means that the arduino can't do it on its own. In the end I decided to use a MCP42100 digital potentiometer ic to simulate the two potentiometers, that only left the problem of controlling the MCP.

The MCP code was pretty easy once I got my head round it. It's an SPI bus device. Credit to http://little-scale.blogspot.com/2008/05/four-midi-controlled-digital-pots-via.html and http://www.arduino.cc/en/Tutorial/SPIDigitalPot.

But here is the code.
#define SS 2
#define CLK 4
#define MOSI 3

byte pot0 = B00010001; // write to pot 0
byte pot1 = B00010010; // write to pot 1
byte pots = B00010011; // write to both

void setup()
{ Serial.begin( 9600 );

pinMode( SS, OUTPUT );
pinMode( CLK, OUTPUT );
pinMode( MOSI, OUTPUT );

digitalWrite( SS, HIGH );
digitalWrite( CLK, HIGH );

set_mcp_pot( pots, potval );
}

void loop()
{ set_mcp_pot( pot0, 255 );
delay( 3000 );

set_mcp_pot( pot1, 255 );
delay( 3000 );

set_mcp_pot( pots, 0 );
delay( 3000 );
}

void set_mcp_pot( byte pot, byte val )
{ digitalWrite( SS, LOW );

spi_transfer( pot );
spi_transfer( val );

digitalWrite( SS, HIGH );
}

void spi_transfer( byte working )
{ int i;

digitalWrite( CLK, LOW );

for( i=1; i<=8; ++i ) { if( working > 127 )
digitalWrite( MOSI, HIGH );
else
digitalWrite( MOSI, LOW );

digitalWrite( CLK, HIGH );
working = working << 1;
digitalWrite( CLK, LOW );
}
}

I have also managed to get it working with the digital compass to do the heading following that I wanted. I'll post that code later once I've checked the wheelchair batteries, I think they are having issues now....

Wednesday, June 17, 2009

So little time....

I'm going to get around to posting the laser plans for the hexapod and posting updates info on the compass project I swear but I have been having job interviews and visiting universities and just generally running around.
Trust me driving to Plymouth from Brighton for an open day is not fun. Plymouth uni is doing some seriously scary cool stuff with robotics though, if you ever get a chance to check out their department, do.

Tuesday, June 2, 2009

Charlotte's Web


So I finally got the parts to put the hexapod together, need to get some beefier servos to replace the lifting ones on this since these can only just manage it. Besides that one hicup it's going well. I need to tweek the design just the tiniest little bit and then I can post the files. The controller works fine too, I'm using a roboduino nano and that's hooked up to Texas Instruments TLC5940. The tlc5940 is a 16 channel pwn chip, mainly used for leds but it can run servos too, there is even a software library http://www.arduino.cc/playground/Learning/TLC5940.