Pages

Saturday, March 19, 2016

Hex Grid Area

Consider the hex grid. Take a single hex on that grid; it has perimeter 0, and area 1. Then consider the ring of hexes around that hex; it has perimeter 6 and area 7. As you consider larger and larger hexagonal areas, an interesting pattern emerges:

size          1: perimeter=0,                   area=1
size         10: perimeter=54,                 area=271
size        100: perimeter=594,               area=29701
size       1000: perimeter=5994,             area=2997001
size      10000: perimeter=59994,           area=299970001
size     100000: perimeter=599994,         area=29999700001
size    1000000: perimeter=5999994,       area=2999997000001
size   10000000: perimeter=59999994,     area=299999970000001
size  100000000: perimeter=599999994,   area=29999999700000001
size 1000000000: perimeter=5999999994, area=2999999997000000001

I've just learned that the complete sequence of hexagonal areas (not just the powers of ten) is registered in the OEIS as A003215 (aka the "crystal ball sequence for hexagonal lattice").

Sunday, September 27, 2015

Hide ActionBar Title

So I'm new to Android development, and was playing around with a sample application template. Using the ActionBar to place tabbed navigation up top, but I want to hide the title. Using the FEATURE_NO_TITLE method crashes (and yes it was before setContentView). Tried many different android:theme settings in the manifest. Nothing worked.

Then I stumbled upon this, which did work:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set up the action bar.
    final ActionBar actionBar = getActionBar();
    actionBar.setDisplayOptions(0); // <----- THIS IS THE PART THAT WORKED.
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // etc...
}
Also worth noting that in my case I'm not displaying an options menu, via:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return false;
}

Wednesday, November 13, 2013

Sparkfun SerLCD Baud Issue

After trying desperately to search for an answer to this seemingly well-known problem, I stumbled upon the solution late last night. If you're unfamiliar, the problem is to do with changing the baud-rate which Sparkfun's SerLCD (mine is version 2.5) operates. Keeping this short, your mileage may vary, but for me the solution is: wait until the splash screen is gone before sending the baud-changing command. It's undocumented, and I haven't tried disabling the splash screen yet, but that worked like a charm for me. Suddenly I can use any baud rate I desire.

(edit) to be clear, I'm talking like 5 full seconds of waiting before sending the baud-change command.

Thursday, April 19, 2012

ATtiny PWM (updated)

This is a re-post of my original ATtiny85 entry. My original was sarcastic, irritated, and (although it worked) lacked helpful comments. So now I've spent some time reading over the datasheet until I understood every single bit function. This program cycles red, green and blue on an RGB LED using the three PWM pins available to an ATtiny85, which are driven by both of the ATtiny85's Timer/Counters (the comments are wide, you may want to copy-paste this code into another editor to read them better).

/*
all my ATtiny85 chips have their 8MHz fuse set
by default they run at 1MHz, so adjust accordingly
this constant is used by delay.h, so make sure it stays above the include
*/
#define F_CPU 8000000

/*
io.h provides lots of handy constants
delay.h provides _delay_ms and _delay_us functions
*/
#include <avr/io.h>
#include <util/delay.h>

/*
program entry-point
*/
void main()
{
    /*
    Starting values for red, green and blue
    */
    uint8_t r=0, g=85, b=170;
   
    /*
    Port B Data Direction Register (controls the mode of all pins within port B)
    DDRB is 8 bits: [unused:unused:DDB5:DDB4:DDB3:DDB2:DDB1:DDB0]
    1<<DDB4: sets bit DDB4 (data-direction, port B, pin 4), which puts PB4 (port B, pin 4) in output mode
    1<<DDB1: sets bit DDB1 (data-direction, port B, pin 1), which puts PB1 (port B, pin 1) in output mode
    1<<DDB0: sets bit DDB0 (data-direction, port B, pin 0), which puts PB0 (port B, pin 0) in output mode
    */
    DDRB = 1<<DDB4 | 1<<DDB1 | 1<<DDB0;

    /*
    Control Register A for Timer/Counter-0 (Timer/Counter-0 is configured using two registers: A and B)
    TCCR0A is 8 bits: [COM0A1:COM0A0:COM0B1:COM0B0:unused:unused:WGM01:WGM00]
    2<<COM0A0: sets bits COM0A0 and COM0A1, which (in Fast PWM mode) clears OC0A on compare-match, and sets OC0A at BOTTOM
    2<<COM0B0: sets bits COM0B0 and COM0B1, which (in Fast PWM mode) clears OC0B on compare-match, and sets OC0B at BOTTOM
    3<<WGM00: sets bits WGM00 and WGM01, which (when combined with WGM02 from TCCR0B below) enables Fast PWM mode
    */
    TCCR0A = 2<<COM0A0 | 2<<COM0B0 | 3<<WGM00;
   
    /*
    Control Register B for Timer/Counter-0 (Timer/Counter-0 is configured using two registers: A and B)
    TCCR0B is 8 bits: [FOC0A:FOC0B:unused:unused:WGM02:CS02:CS01:CS00]
    0<<WGM02: bit WGM02 remains clear, which (when combined with WGM00 and WGM01 from TCCR0A above) enables Fast PWM mode
    1<<CS00: sets bits CS01 (leaving CS01 and CS02 clear), which tells Timer/Counter-0 to not use a prescalar
    */
    TCCR0B = 0<<WGM02 | 1<<CS00;
   
    /*
    Control Register for Timer/Counter-1 (Timer/Counter-1 is configured with just one register: this one)
    TCCR1 is 8 bits: [CTC1:PWM1A:COM1A1:COM1A0:CS13:CS12:CS11:CS10]
    0<<PWM1A: bit PWM1A remains clear, which prevents Timer/Counter-1 from using pin OC1A (which is shared with OC0B)
    0<<COM1A0: bits COM1A0 and COM1A1 remain clear, which also prevents Timer/Counter-1 from using pin OC1A (see PWM1A above)
    1<<CS10: sets bit CS11 which tells Timer/Counter-1  to not use a prescalar
    */
    TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS10;
   
    /*
    General Control Register for Timer/Counter-1 (this is for Timer/Counter-1 and is a poorly named register)
    GTCCR is 8 bits: [TSM:PWM1B:COM1B1:COM1B0:FOC1B:FOC1A:PSR1:PSR0]
    1<<PWM1B: sets bit PWM1B which enables the use of OC1B (since we disabled using OC1A in TCCR1)
    2<<COM1B0: sets bit COM1B1 and leaves COM1B0 clear, which (when in PWM mode) clears OC1B on compare-match, and sets at BOTTOM
    */
    GTCCR = 1<<PWM1B | 2<<COM1B0;
   
    /*
    loop forever
    */
    for (;;)
    {
        /*
        increment and boundary-check each color
        */
        if (++r>255) r=0;
        if (++g>255) g=0;
        if (++b>255) b=0;
       
        /*
        update compare registers with red, green and blue values
        */
        OCR0A = r;
        OCR0B = g;
        OCR1B = b;
       
        /*
        brief pause so we can perceive what is happening
        */
        _delay_ms(10);
    }
}

Monday, September 12, 2011

Welcome to the Internet

I've decided that a blog could be a handy tool for many reasons. Ideally, this will serve as a place for me to post snippets of useful information that I (or anyone else) may reference.

For my first order of business, lets set the mood for this blog with a piece of software I just finished. Last night (err.. 3am this morning) I finished an implementation of the Skein 512-512 hash algorithm (version 1.3). I'm a fan of Skein and hope it wins the SHA-3 competition next year. One of the nice things about Skein is how quickly it's been adopted by many platforms and implemented in many languages. To that end, I present Skein 512-512 implemented in Bash. I know, and I'm sorry, but someone had to do it. It is extremely slow, and left a very bad taste in my brain. Isn't that punishment enough?