Setup PIC Timer with Interrupt Example (18F Family, MikroC)

software development on PIC microcontroler

Setting up a PIC timer to the correct frequency can be a tricky business for the uninitiated Software Engineer (i.e. Me). So I was pretty happy when I came across this great on-line tool whereby you just type in your oscillator frequency and desired interrupt rate and it generates the setup code for you!

For example I have an 8Mhz clock and wanted a 1KHz interrupt on Timer0, I punched that in and the tool said I should use this set-up code:

//
T0CONbits.T08BIT = 0;
T0CONbits.T0CS = 0;
T0CONbits.PSA = 0;
T0CONbits.T0PS2 = 1;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 0;
TMR0H = 0xB;
TMR0L = 0xDC;
T0CONbits.TMR0ON = 1;
//

Happy days!

Now there is a little more to defining the software interrupt handler and enabling the interrupt so I have included the code for a slightly more verbose example that configures and enables Timer0 via mikroC on the PIC18F25K22:

//
void init_timers();
void main() {
  init_timers();
  for (;;) {
    // do something...
  }
}
void init_timers() {
  // Initialise Timer0 for a 1Khz interrupt
  // 8Mhz clock & want 1Khz interrupt
  // See http://www.enmcu.com/software/timer0calculatorandcodegeneration
  // for values.
  //
  INTCON.GIE=1;         //globle interrupt enable
  INTCON.PEIE=1;        //peripharel interrupt enable
  INTCON.TMR0IF = 0x0;  //Clear timer0 overflow interrupt flag
  INTCON.TMR0IE = 1;    //enable the timer0 by setting TRM0IE flag
  T0CON.T08BIT = 0;     // 16 Bit timer
  T0CON.T0CS = 0;       // Internal clock
  T0CON.PSA = 1;        // Set scaler to 1:4
  TMR0H = 0xF8;         // Initial count of 0xF830
  TMR0L = 0x30;
  T0CON.TMR0ON = 1;     // Turn Timer0 on.
}
// interrupt handler for the timer0 overflow
void interrupt(void) {
  // http://www.enmcu.com/software/timer0calculatorandcodegeneration
  
  // Reset the timer count
  TMR0H=0xF8;
  TMR0L=0x30;
  
  // Reset interrupt flag
  INTCON.TMR0IF = 0;
  // Do some work here
}
//

Save 8 bit uncompressed windows bitmap file (.BMP) in c# / .Net

It took me about 3 years to figure this out. In .Net when you save an 8 bit bitmap from software (PixelFormat.Format8bppIndexed) via Save() it is saved by default in a compressed format (as is allowed by the .bmp pseudo-standard).

Now some Machine Vision libraries can’t load compressed 8 bit bitmaps (poor old Cognex, bless) so I had to figure out how to get .Net to save the .bmp file in an uncompressed format.

The following code save the bitmap as 8bit compressed (if the bitmap’s format is PixelFormat.Format8bppIndexed)

 bitmap.Save("it.bmp");

Now Microsoft has not documented this whole area very well, but it is quite easy, you have to manually specify an image encoder and set its ‘Compression’ parameters as in the following code:

  // Make sure that the blighter will be saved
  // uncompressed.
  var enc = GetEncoderInfo("image/bmp");
            
  var parms = new EncoderParameters(1);
         
  var parm = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);
  parms.Param[0] = parm;
  // Save the bitmap.
  bitmap.Save("it.bmp", enc, parms);

Where GetEncoderInfo() is defined as:

private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
    int j;
    ImageCodecInfo[] encoders;
    encoders = ImageCodecInfo.GetImageEncoders();
    for (j = 0; j < encoders.Length; ++j)
    {
        if (encoders[j].MimeType == mimeType)
            return encoders[j];
    }
    return null;
}

Here we set the Encoder.Compression parameter to EncoderValue.CompressionNone and this should ensure that the bitmap is saved uncompressed.

See this post for details of how to save an 8 bit greyscale image to disk from a byte array.

Reference:

http://msdn.microsoft.com/en-us/library/ytz20d80(v=vs.110).aspx

Cross compiling libpng for ARM Linux with Neon and Zlib

libpng is the standard software library for creating .png image files. It can be built for arm with NEON SIMD support. Cross compiling it for ARM is reasonably straight forward. Its only dependency is zlib which configure can have problems finding.

Before building libpng you will first need to compile zlib.

Then download the libpng source from here, un-zip it etc. and then run confgure as follows:

./configure --host=arm-linux-gnueabi CC=arm-linux-gnueabi-gcc \
    AR=arm-linux-gnueabi-ar STRIP=arm-linux-gnueabi-strip RANLIB=arm-linux-gnueabi-ranlib \
   CPPFLAGS="-mfpu=neon -I/path/to/zlib/include/files" LDFLAGS="-L/path/to/zlib/lib/files"  \
   --prefix=/path/to/dir/for/output/files   

In the above command replace:

a.) the path to your zlib include files (probably inside the install directory the the zlib build installed to)
b.) the path to your zlib lib files
c.) The path to the directory into which you want all of the output files installed
d.) change the compiler names (if different from arm-linux-gnueabi-gcc etc.)

Once configure completes you make & install:

make
make install

Now copy the files from the output directory to your ARM device.

Powerline to Connect Broadband Router to wired Network

As most software engineers do, I feel helpless if I loose network or internet access, and so I am glad to report that we are well into week two of using Ethernet over Powerline for connecting our wired network hub to the new eircom efibre router as I mentioned in this previous post.

So far the set-up is working very well indeed – it seems very fast and it has been very reliable so it looks like we have a permanent solution!

C++ thread safe blocking queue using boost

In Software Engineering some patterns reoccur only every few years. The blocking queue pattern is on such for me. Here is a great article on an implementation of a thread-safe blocking queue that uses boost for synchronisation:

http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

I implemented something like this some years ago (without the benefit of boost etc.) and now I need one again and I want to make it bang-up-to-date wrt. C++11 and boost etc., so this article is a real bonus, much thanks to Anthony Williams!

Does my Eircom eFibre modem / router need to be connected to main phone socket?

This is quite a tricky one. Eircom says that your new eFibre fibre broadband modem / router must be connected to your main telephone socket but that they can move this socket by a few metres if you request it. They don’t seem very keen on moving the socket however and it seems to me that moving it isn’t always a great choice – if there are no suitable sockets to move it to then they must messily chase a cable from your main socket up the stairs and over doors etc. to a new socket, and if there are existing sockets they can’t be sure of the quality of the in-place wiring and warn that you could suffer a drop in broadband ‘power’ (whatever that is!) if you choose to use it.

Typically the normal DSL modems could be placed at any telephone socket within your house, you would just use the DSL filter adapters as appropriate. This allowed broadband customers to connect wired printers and NAS devices etc. directly to the router’s Ethernet hub. Now if this router must move to the main socket (which is often just beside the front door) then you may have a problem!

I think that one of the reasons why ericom want the modem plugged into the main socket is that they have built the vDSl filter into the module at the from of the socket – this removes the need for a separate filter but means that all other sockets within the house do not have the vDSL signal. I think that they also want to avoid going near the house’s internal telephone wiring as they can’t be sure its quality (which is fair enough).

Fibre Boradband Socket with built-in vDSL filter

Fibre Boradband Socket with built-in vDSL filter

So how can you connect your existing wired network into your new fibre broadband router if they are physically separated in this way?

Well, one relatively cheap and simple solution is to use an Ethernet over powerline adaptor to run an Ethernet connection from your modem’s hub to your hub elsewhere in the house over the mains wiring – no need for running any cables or for fighting with WiFi bridges etc. just plug one end into your eircom router and the other into your wired network.

Here is a 500Mbps device that PC World has for about 54 euro:

http://www.netgear.com/home/products/networking/powerline/XAVB5201.aspx

 

Powerline in place

Powerline in place

Cross compiling libjpeg-turbo targeting ARM for software jpeg compression

In a quest to get faster software jpeg compression on ARM I cross compiled libjpeg-turbo 1.3.0 and pitted it against standard libjpeg (libjpeg-turbo can be used as a drop in replacement for libjpeg). For 24bit rbg images of size 4096×2000, libjpeg-turbo was about twice as fast as libjpeg. Here’s how I compiled libjpeg-turbo:

First get the source:

wget http://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-1.3.0.tar.gz

Then un-tar it and cd into the main source directory. Then configure for ARM:

 ./configure --host=arm-linux-gnueabi CC=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar \
          STRIP=arm-linux-gnueabi-strip RANLIB=arm-linux-gnueabi-ranlib \
          --prefix=

And make:

make
make install

The output files will be put under the directory that you specified when you configured, copy them onto your ARM device as appropriate.

Making an external connection to a Blaknight MySQL database

You can connect to a Blacknight MySQL database from an external tool (e.g. mysql or mysqlimport commandline) if you change some of the database’s settings. This can be useful if you need to manage your database, for example if you need to perform a large database import (one that is so large it causes phpMyAdmin to time out).

First you need to configure the database to allow external connections, in the Blacknight control panel choose to edit the database’s settings and check the ‘Access from external hosts’ check-box. This change on its own isn’t sufficient, next you must add your ip address to the ‘Access Hosts’ list.

enable_external_access

When on the database properties page, click on the ‘Access Hosts’ tab, click on ‘Add new access host’ and add your ip address. To find your IP address, just google ‘my ip address’ and your address will be displayed near the top of the results page.

add_ip_address_blacknight

Once you have made these changes you should be able to make external connections to the database. When you are finished it is probably a good idea to remove external access again.

You can now do something like import a database, get the hostname from the ‘external hostname’ field on the blacknight control panel:

mysql --host="mysq12666.cp.blacknight.com"   --user='u1273449_the_user' --password="ThePassword" database_name < ./db4.sql

New batteries for my Casio fx-580

The Software Engineer’s mate – a really good scientific calculator, I have just refreshed the batteries in my Casio fx-580, I still haven’t found as good a calculator even though it of 80’s vintage!

The keys are a bit ‘yellowed’ now, bit otherwise its powering along.

casio-fx-580-small

New Scientist Enigma 1780 and Python

Python program to solve New Scientist Engima 1780
Sometimes a body has to take a break from all this Software Engineering stuff and instead delve into some recretional programming, so with this in mind I decide to see if I could write a small python program to solve the New Scientist Enigma #1780. This enigma is kind of like suduku on an icosahedron of all things (a 20 faced thing).

Anyway it was just for fun and I wasn’t looking for the ‘best’ or most ‘elegant’ solution to the problem, just one that kinda worked! So I wrote a little program over Christmas which I got working (more or less).

I enjoyed the challenge decided to try my hand at future enigmas – only to find out that Enigma #1780 was the last one ever, the New Scientist is giving them up – which is a great pity seeing as I have only started to get interested in them.

Today I came across this site which has python solutions for tonnes of Enigmas including 1780, it was on this site that I learned that 1780 is the last enigma. They point out that there is a large archive of enigmas.

In an attempt to codify the puzzle, I decided think about the flattened out icosahedron (its net) as a grid of 4 rows of 5 triangles, in this way an individual triangle can be referenced using a pair of numbers (i, j), where i varies between 0 and 4 and specifies the triangle’s ‘column’ while j specifies its row. Next I tried to come up with some rules that would find the coordinates of all of the triangles ‘connected’ to the triangle at (i, j).

Once all of that is done solving the puzzle given a valid input net is a matter of finding an empty triangle, finding the set of numbers that can go into that triangle, picking one of these numbers and recursively solving the puzzle for the update net, if the recursive solve fails for that number we try the next number and so on….

Anyway, the solve() function is called like this:

solve(start_net, 0)
#
# Try to solve New Scientist Enigma 1780 (the last one!)
#
# Run like:
#
# solve(start_net, 0)
#
all_values = {1, 2, 3, 4, 5}
net_width = 5
net_height = 4;
# get the value at (i, j)
def value_at(net, a):
    i, j = a
    return net[i + j * net_width]
# set the value at (i, j)
def set_value_at(net, a, val):
    i, j = a
    net[i + j * net_width] = val

# Create list to hold net values, initialised with zeros
start_net = [0] * (net_height * net_width)
# insert the starting values
set_value_at(start_net, (0,0), 2)
set_value_at(start_net, (0,1), 5)
set_value_at(start_net, (0,3), 1)
set_value_at(start_net, (4,0), 4)
#set_value_at(start_net, (4,2), 3)
set_value_at(start_net, (4,3), 2)

# loop i around if i > net_width (modulo)    
def mi(i):
    return i % net_width
# The connection rules for each row
i_0 = [lambda i: (mi(i+1), 0), lambda i: (mi(i+2), 0), lambda i: (mi(i+3), 0), lambda i: (mi(i+4), 0), lambda i: (mi(i-1), 1),
       lambda i: (mi(i-1), 2), lambda i: (mi(i), 1), lambda i: (mi(i+1), 2), lambda i: (mi(i+1), 1)]
i_3 = [lambda i: (mi(i+1), 3), lambda i: (mi(i+2), 3), lambda i: (mi(i+3), 3), lambda i: (mi(i+4), 3), lambda i: (mi(i-1), 2),
       lambda i: (mi(i), 1), lambda i: (mi(i), 2), lambda i: (mi(i+1), 1), lambda i: (mi(i+1), 2)]
i_1 = [lambda i: (mi(i-1), 0), lambda i: (mi(i-1), 1), lambda i: (mi(i-1), 2), lambda i: (mi(i-1), 3), lambda i: (mi(i), 0),
       lambda i: (mi(i), 2), lambda i: (mi(i), 3), lambda i: (mi(i+1), 0), lambda i: (mi(i+1), 1)]
i_2 = [lambda i: (mi(i), 0), lambda i: (mi(i), 1), lambda i: (mi(i), 3), lambda i: (mi(i-1), 2), lambda i: (mi(i-1), 3),
       lambda i: (mi(i+1), 0), lambda i: (mi(i+1), 1), lambda i: (mi(i+1), 2), lambda i: (mi(i+1), 3)]
cons = [i_0, i_1, i_2, i_3]
# is a connected to b?
def connected(a,b):
    (i, j) = a
    
    if a == b:
        return True;
    return b in [d(i) for d in cons[j]]
# gets a list of all triangle coordinates
def all_triangles():
    return [(i % net_width, i // net_width) for i in range(0,net_height*net_width) ]
# gets a list of all triangles connectd to a    
def connected_triangles(a):
    return [b for b in all_triangles() if connected(a,b)]
def find_loc_of_first_empty_triangle(net):
    try:
        index = net.index(0)
        return (index % net_width, index // net_width)
    except:
        return None 
# returns a list of all empty triangles
def all_empty_triangles(net):
    return [a for a in all_triangles() if value_at(net, a) == 0]
# returns the possible values (1..5) that can go into
# the triangle a
def possible_values(net, a):
    ct = connected_triangles(a)
    used_values = {value_at(net, t) for t in ct}
    return all_values - used_values - {value_at(net, a)}
    
# solve given a valid input net    
def solve(net, depth):
    print ('solve, depth: ' + str(depth))
    a = find_loc_of_first_empty_triangle(net)
    
    # if there are no free locations then the
    # net if full and we have finished
    if not a:
        print ('net is full ' + str(net))
        return net
    
    # get list of possible values for this triangle
    possible = possible_values(net, a)
    
    # If we can't make a move then we need
    # to backtrack
    if not possible:
        print ('No more possible moves for ' + str(a))
        return []
    
    for v in possible:
        
        # create a copy of our current net
        new_net = list(net)
        
        set_value_at(new_net, a, v)
        result_net = solve(new_net, depth+1) 
        if result_net:
            return result_net
    return []
if __name__ == "__main__":
    res = solve(start_net, 0)
#    

Update, 07/02/2014
The answer to this Enigma as announced here is: 324125, thankfully the same as that announced by the Python program! Unfortunately I didn’t win the competition, but I had loads of fun trying to write some software to solve it! I might try a Haskell version next if I find the time…