Color Picker for Android

Color Picker with HSV sliders and mini-palette for Lightbox on Android.

Color Picker on a Tablet with HSV sliders and mini-palette for Lightbox on Android.

The Lightbox app allows users to alter the colour displayed on the lightbox screen. Previous colour-pickers used in Lightbox were sufficient for general use but lacked the fine control needed for some applications. The new colour picker provides three large controls for tweaking the hue, saturation and value aspects of a given colour. This means that for colours close to white it is now possible to finely tune the hue and saturation independently. There are also a few standard colours in the mini-palette to quickly jump to full white, red, yellow, green, blue or magenta. The original colour and the new colour swatches are also displayed allowing the user to reset to the original colour as a starting point. On larger displays, the controls will expand to make full use of the screen space (in portrait or landscape) for even finer control for the user.

The mini-palette uses the AspectGrid from StackOverflow to provide a nice grid layout. The Hue, Saturation and Value sliders are derived from the SurfaceView with the canvas painted using the LinearGradient for background and a simple stroke line for the slider marker.

This provides a simple, but effective solution. There are also many alternatives if you are looking for solutions, with some particularly flexible and stylish implementations such as HoloColorPicker.

Daylight Lamp

Earlier this summer I stumbled on an article explaining how windowless work-spaces can cause sleep deprivation. This is based on the research and journal paper by Boubekri et al.

I spend my days working in an underground laboratory (albeit not in a hollowed out volcano) with fluorescent lighting and zero natural light. I had also noticed that my sleep was no longer as replenishing as it was when I worked at a desk in front of a south facing window.

So, as an experimental solution I purchased a lamp and daylight bulb and now illuminate my desk with this all day. I have found that gradually I am sleeping better and feeling much more rested when I wake. Correlation, though not necessarily causation – it’s certainly better having the daylight hues lighting the desk.

The lamp and daylight bulb are both available from John Lewis. Although the matching bulb is actually found in the craft department rather than the lighting department?!

John Lewis Elliot Task Lamp

John Lewis Elliot Task Lamp

Purelite Natural Daylight Bulb ES 15 Watt

Purelite Natural Daylight Bulb ES 15 Watt

This should also help during those long, dark, northern winters!

Electric Dawn – Alarm Clock Sunrise

The Electric Dawn sunrise also works in landscape if the device is in that orientation already. Here it is running on a Samsung Galaxy Tab S 8.4. A soothing way to gently nudge you from slumber; far superior to the average alarm clock. 🙂

Android app on Google Play

 

 

George / CompuRobot CGL - Front View

George CompuRobot CGL

Whilst tidying up my desk area I stumbled on an old George-bot (CGL CompuRobot) that I’d bought cheap on ebay some years ago. The electronics all work perfectly well, but a broken gear/cog means one of the wheels is undrivable. Eventually I may find a replacement gear, but in the meantime here are some photos showing some robust 1980s electronics.

George / CompuRobot CGL - Front View

George / CompuRobot CGL – Front View

George / CompuRobot CGL - Front View

George / CompuRobot CGL – Front View

George / CompuRobot CGL - Inside Front View

George / CompuRobot CGL – Inside Front View

George / CompuRobot CGL - Motors View

George / CompuRobot CGL – Motors View

George / CompuRobot CGL - Cogs, Gears and Differential Drive View

George / CompuRobot CGL – Cogs, Gears and Differential Drive View

George / CompuRobot CGL - PCB Circuit View

George / CompuRobot CGL – PCB Circuit View

George / CompuRobot CGL - Membrane Keypad PCB View

George / CompuRobot CGL – Membrane Keypad PCB View

 

New Year, New Project

A slightly belated Happy New Year to you! (It is still January. Just).

Having finally shaken the never-ending stream of colds since before Christmas, I now have energy once again to make a focussed and sustained advance at the new project.

Onwards to new (to me) technological territories: NodeJS, LocomotiveJS, PassportJS, Mongoose, Bootstrap, and friends.

To be continued…

Programming Books

A selection of go-to books on my reference bookshelf. I’m always interested to hear of your recommendations too! I will keep appending to this page as I go.

Game Coding Books

Game Coding Complete by McShaffry

General C++ Books

Exceptional C++, Exceptional C++ Style, More Exceptional C++ – All by Herb Sutter

Effective C++, More Effective C++ – All by Meyers

General Programming Books

Design Patterns by Gamma et al

Small Memory Software by Weir and Noble, available online.

Refactoring by Fowler

The Pragmatic Programmer by Hunt and Thomas

Algorithms and Mathematics

The Algorithm Design Manual by Skiena

Mathematics for 3D Game Programming & Computer Graphics by Lengyel

Numerical Recipes in C++ by Press et al

Seasons Greetings

Whimsical Otter's Christmas TreeThe Christmas Tree is up. The artificial antique one (a Woolworths classic) this year as the live one shed all of its needles in the garden last winter and has only grown back about half of them. The heating is on and cosy. The Christmas Robot is merrily beep beep booping in the background. So it seems the festivities have begun in earnest. Here’s hoping you all have an enjoyable festive season catching up with loved ones and look forward to an exciting year in 2014! 😀

Unit Testing with AVR Studio and AVR-GCC

Overview

When developing embedded C applications for 8-bit AVR microcontrollers, I found the lack of a unit test framework troublesome. Especially as unit testing now forms a standard part of our C-sharp and Java development processes.

There are a number of C and C++ unit testing frameworks available but nothing geared up for running in the target environment of an 8-bit AVR.

The “framework” produced here is a lightweight starting point that can be enhanced to provide output in any form useful to the user. It is currently used in the AVR Simulator as part of the AVR Studio 5 environment, but there’s no reason why it couldn’t be run on the target device with test result output streamed over a USART connection.

Init levels

Adding the tests in JUnit etc allows you to scan the classes and run them all automatically. We can’t quite do the same in C. However, what we can do is to make use of the .init levels and have a function for each test automatically called on system start-up. These functions will then automatically add each test to the test suite.

AVR Memory Sections

Simulator

By running the tests in the AVR simulator, we can use the Watch tools to view the test results by putting breakpoints after each test is run, or after all tests have run. Monitor the m_Test_activeTest for the current test data, and m_Test_result for the final results.

The Code

test.h

#ifndef TEST_H
#define TEST_H

#include <inttypes.h>

// typedefs
typedef enum TestResult
{
	NOT_RUN = 0,
	SUCCESS,
	FAILURE
} TestResult;

typedef struct Test_TestHolder
{
	char * name;
	void (*testFunction)(void);
	char * file;

	int line;
	TestResult testResult;

	struct Test_TestHolder* next;
} Test_TestHolder;

// Initialise the test framework

void Test_add(Test_TestHolder* test);

void Test_assertTrueLog(uint8_t condition, uint16_t lineNumber);

void Test_assertEqualLog(uint16_t expected, uint16_t actual, 
    uint16_t lineNumber);

void Test_runall(void);

#if __TEST__

void Test_init(void) __attribute__ ((naked)) 
    __attribute__ ((section (".init7")));

#define Test_run() {Test_runall(); for(;;); }

#define Test_test(MODULE, NAME)
	void MODULE##_test_##NAME(void);
	void MODULE##_appendtest_##NAME(void) 
            __attribute__ ((naked))   
            __attribute__ ((section (".init8")));
	Test_TestHolder m_##MODULE_test_##NAME = { #NAME,
            MODULE##_test_##NAME, __FILE__, 0, NOT_RUN };
	void MODULE##_appendtest_##NAME(void) { 
            Test_add( &m_##MODULE_test_##NAME ); }; 
	void MODULE##_test_##NAME(void)

#else

void Test_init(void);

#define Test_run()

#define Test_test(MODULE, NAME)
	void MODULE##_test_##NAME(void);
	void MODULE##_test_##NAME(void)

#endif

#define Test_assertTrue(condition)
    Test_assertTrueLog((condition), __LINE__);
    if (!(condition)) {
        return;
	}		

#define Test_assertEquals(expected, actual)
    Test_assertEqualLog((expected), (actual), __LINE__);
    if ((expected) != (actual)) {
        return;
    }

#endif /* TEST_H */

test.c

#include "test.h"

#include <stdlib.h>
#include <string.h>

Test_TestHolder* m_Test_head;

Test_TestHolder* m_Test_activeTest;

typedef struct Test_ResultType
{
	uint16_t totalTests;
	uint16_t successCount;
	uint16_t failureCount;
} Test_ResultType;

Test_ResultType m_Test_result;

// Initialise the test framework
void Test_init(void)
{
	m_Test_head = NULL;
	m_Test_activeTest = NULL;

	m_Test_result.totalTests = 0;
	m_Test_result.successCount = 0;
	m_Test_result.failureCount = 0;
}

void Test_add(Test_TestHolder* test)
{
	// Put to front of chain
	test->next = m_Test_head;
	m_Test_head = test;
}

void Test_assertTrueLog(uint8_t condition, uint16_t lineNumber)
{
	// We have the active test
	if( !(condition) )
	{
		m_Test_activeTest->testResult = FAILURE;
		m_Test_activeTest->line = lineNumber;	
	}
}

void Test_assertEqualLog(uint16_t expected, uint16_t actual, 
    uint16_t lineNumber)
{
	if( expected != actual )
	{
		m_Test_activeTest->testResult = FAILURE;
		m_Test_activeTest->line = lineNumber;	
	}
}

// Run through all the tests
void Test_runall(void)
{
	// Reset counts
	m_Test_result.totalTests = 0;
	m_Test_result.successCount = 0;
	m_Test_result.failureCount = 0;

	// Reset status of all
	m_Test_activeTest = m_Test_head;
	while( m_Test_activeTest != NULL )
	{
		m_Test_result.totalTests++;

		m_Test_activeTest->testResult = NOT_RUN;
		m_Test_activeTest->line = 0;

		// next in the chain
		m_Test_activeTest = m_Test_activeTest->next;
	}

	// Now execute the tests
	m_Test_activeTest = m_Test_head;
	while( m_Test_activeTest != NULL )
	{
		m_Test_activeTest->testFunction();

		if( m_Test_activeTest->testResult == NOT_RUN )
		{
			m_Test_activeTest->testResult = SUCCESS;
			m_Test_result.successCount++;
		}
		else
		{
			m_Test_result.failureCount++;
		}

		asm("nop");

		// next in the chain
		m_Test_activeTest = m_Test_activeTest->next;
	}

	// Get the results
	asm("nop");
}

// Examples
/*
Test_test(Test, testWillFail)
{
	Test_assertEquals(1, 0);
}

Test_test(Test, testWillPass)
{
	Test_assertTrue(1);
}
*/

main.c

#include "test.h"

int main(void)
{	
	Test_run();        // System code
}