And they look pretty spanky.
Not much more to say really. They'll be going along to the open evening at BuildBrighton tonight and hopefully we'll get a few made up into completed board sections for testing. We've ten in total - enough to make three full board games (of three sections each) and still have one left over for development and testing. Exciting stuff!
Thursday, 31 October 2013
Transmitting Manchester encoded data over a single wire using PIC 16F1825 - VirtualWire for PIC
As we started to put together a receiver for our Manchester encoded transmitter, something started to really niggle. It wasn't a bit niggle, but a niggle all the same. See, we'd started to write our receiver using interrupts - to make sure that it was receiving and processing the data in a timely manner. But we also knew that because the transmitter was using a software-based delay, it had the possibility of a slight drift, especially when sending long streams of data.
It was probably nothing. It probably wouldn't make any difference at all. But since this was also an exercise in understanding how the single wire interface worked, not just a task to get a job done (after all, we'd already successfully implemented the VirtualWire over RF for our toy guns project, using an Arduino and a library of existing code) we thought that perhaps it was time to do it properly.
So here's a single wire transmitter, using Manchester encoding, and Timer1 interrupts.
It's calling a single function every time the interrupt fires, which toggles the data pin high or low as soon as possible after the interrupt has fired. So even if there is a tiny delay between the interrupt firing and the pin changing, there's no chance of drift - the timer1 interrupt ensures that however long the delay is, the next pin change will happen in a timely manner; effectively we've removed any possible cumulative error when sending multiple bytes.
We changed over to the 16F1825 chip for this, just to aid debugging.
We've used these before and one handy register they have is the APFCON0 register, which allows you to map the UART TX and RX lines onto the same pins as used for programming the chip. This means that when running code, you can add in some serial debugging and have the PICKit2 programmer report back any data received, without having to move jumpers or wires all over the place.
Although we've no serial debugging in this example, our receiver will need lots of debugging, so we're sticking with these 16F1825 chips for now. Also, we can run them at 32Mhz, meaning we get a few extra clock cycles between the timer1 interrupts firing (on an 8Mhz chip, we get a quarter of available clock cycles between interrupts firing to do any processing).
You can use pretty much any chip you like, just change the include and pragma statements at the head of the code to run on your own favourite chip (and maybe the TRIS registers to map the i/o to different pins if necessary).
Anyway, with the code in place, it was time to do some testing. We only recently discovered a really useful tool in the PICKit2 software. And it really is useful - it's a logic analyser. We've used one of these before, and it was invaluable for debugging our sd card initialisation routines about 12 months ago. But it's only recently we discovered that the PICKit2 has a logic analyser built right in! To use the analyser, we simply made our dataOut pin on the transmitter the same as one of the programming pins on the PICKit2.
Now we can simply start our transmitter running, put a test condition in to tell the PICKit2 when to start taking samples, and hit the button to actually send the data.
Here we're using the PICKit2 programmer to provide power to our two PICs (one is the transmitter, one will be the receiver).
One thing to remember is to turn on the voltage supply to the PIC before starting the analyser tool. Our clone programmer doesn't have a cancel button on it. Forget to actually turn the voltage on and the PIC never sends a signal to start the analyser running. This can cause the application to hang and require Task Manager to sort the mess out!
The other highlighted section of this screenshot is the trigger condition. We made our dataPin RA.1 which is also one of the programming pins. So we set up our logic tool to monitor "channel 2" (which we have connected to RA.1 on the transmitter) and we're going to start recording data on a falling edge.
With everything hooked up, it's time to set the logic probe running and hit the transmit button. Below is a composite screenshot of the results
The top part of the image is the data as displayed on the software logic probe. We changed our tranmitter to send the most significant bit (MSB) first, so that the data would be more easily "seen" on our logic probe. At first it just looks like a load of peaks and troughs - we can see we're getting some data through!
The lower part of the image is the same graph, only this time, we've highlighted the high-to-low transition than indicates a bit value of one (the remaining un-highlighted parts show the low-to-high transitions that indicate a bit value of zero).
Now we can actually see the data in binary form. If we decode this binary data back into it's decimal equivalents, we can read back the data, exactly as it was sent from the transmitter.
Now we've got a working single-wire transmitter that can send data using the Manchester encoding, using timer1 interrupts so there's no cumulative drift error. At least now, when it comes to debugging the receiver, we won't have any niggling doubts about whether any problems are with the code in the receiver, or actually an inherent problem with the transmitter. As far as we can see, the transmitter is as "tight" as it can be, and the data should be transmitted consistently with no drift error. It's not going to make debugging the receiver any easier but at least it's one less thing to eliminate if/when it all starts to go horribly wrong!
It was probably nothing. It probably wouldn't make any difference at all. But since this was also an exercise in understanding how the single wire interface worked, not just a task to get a job done (after all, we'd already successfully implemented the VirtualWire over RF for our toy guns project, using an Arduino and a library of existing code) we thought that perhaps it was time to do it properly.
So here's a single wire transmitter, using Manchester encoding, and Timer1 interrupts.
It's calling a single function every time the interrupt fires, which toggles the data pin high or low as soon as possible after the interrupt has fired. So even if there is a tiny delay between the interrupt firing and the pin changing, there's no chance of drift - the timer1 interrupt ensures that however long the delay is, the next pin change will happen in a timely manner; effectively we've removed any possible cumulative error when sending multiple bytes.
#include <system.h>
// ##################################
// using a 32 Mhz internal oscillator
// on a PIC16F1825
#pragma DATA _CONFIG1, 0x0804
#pragma DATA _CONFIG2, 0x1DFF
#pragma CLOCK_FREQ 32000000
// ##################################
#define button portc.2
#define testing porta.5
#define dataPin porta.1
#define ledRed portc.5
#define ledGreen portc.4
#define ledBlue portc.3
char c;
char xorsum;
char dataBuffer[6];
char bitsSent=0;
bit bitFlag=0;
char byteToSend=0;
char bytesSent=0;
char byteIndex=0;
bit sendNextByte=0;
bit pinState;
bit sending=0;
// program initialise
void initialise(){
osccon=0b11110000; // oscillator=32mhz
delay_ms(50); // wait for internal voltages to settle
intcon=0b11000000; // global peripheral interrupts enabled
apfcon0=0b01000000; // alternative tx/rx for pickit2/uart
wpua=0xFF; // any inputs on portA have weak pull-ups
wpuc=0xFF; // any inputs on portC have weak pull-ups
trisa=0x00; // portA is all outputs
trisc=0b00000100; // RC.2 is an input (push button)
ansela=0x00; // turn off analogue pins on portA
anselc=0x00; // turn off analogue pins on portC
porta=0x00; // set all output pins on portA off
portc=0x00; // turn off all output pins on portC
option_reg=0x00;
option_reg.7=0; // weak pull-ups enabled on any input pins
// set up timer1
t1con=0b00001000; // set bit zero of t1con to start the timer
pie1.TMR1IE=1; // enable the timer1 interrupt
// enable the global and peripheral interrupts
intcon.GIE=1;
intcon.PEIE=1;
}
// set timer1 value so it fires every X-uS
void preloadTimer1(){
// at 32Mhz, fosc/4=8million
// our radio modules are rated *up to* 4khz
// so let's stick to about half that for now
// 8m/2000 = 4000
// so we want our timer1 to only count up to 4000
// timer1 is a 16-bit timer (0-65535) so we need to
// preload it with 65535-4000 = 61535 (0xF05F)
tmr1h=0xF0;
tmr1l=0x5F;
}
void startTimer(){
// clear any left over interrupt flag
pir1.TMR1IF=0;
// set bit zero to start the timer
t1con.0=1;
}
void stopTimer(){
// clear bit zero to stop the timer
t1con.0=0;
}
void endTransmission(){
// first, kill the timer
stopTimer();
// now wait a timer-width before pulling the
// data line low (in case we've only just pulled
// it high)
delay_100us(5);
// pull the data pin low (end of transmission)
dataPin=0;
// turn off any transmission leds
ledBlue=0;
// kill the sending flag
delay_ms(5);
sending=0;
}
void sendBit(){
if(bitFlag==0){
// work out which way the bit should be sent
// (start low for bit value 1, start high for bit value zero)
// for MSB first, use this
if(byteToSend & 0b10000000){pinState=1;}else{pinState=0;}
// for LSB first, use this
// (MSB first makes it easier to "see" the data on a logic analyser)
//pinState=byteToSend & 1;
// set the pin according to the bit value
dataPin=pinState;
bitFlag=1;
}else{
// it doesn't matter which way the pin is, just toggle it
// the other way
pinState=!pinState;
dataPin=pinState;
// keep track of the number of bits sent
bitsSent++;
if(bitsSent>=8){
sendNextByte=1;
}else{
// nudge up the value in the byteToSend buffer
// for MSB first, shift left
byteToSend=byteToSend<<1;
// for LSB first, shift right
// byteToSend=byteToSend>>1;
sendNextByte=0;
}
bitFlag=0;
}
if(sendNextByte==1){
byteIndex++;
if(byteIndex>=6){
// we've sent three bytes (6 inc preamble + crc)
// so end transmission
endTransmission();
}else{
// prepare the next byte for transmission
byteToSend=dataBuffer[byteIndex];
bitsSent=0;
bitFlag=0;
}
sendNextByte=0;
}
}
// send some data
void sendData(unsigned char i1, unsigned char i2, unsigned char i3){
sending=1;
// send a manchester standard preamble
// alternate 10101010 a few times
// then end the preamble with 10101011
// (two ones indicate end of preamble)
dataBuffer[0]=0b10101010;
dataBuffer[1]=0b10101011;
// fill the data buffer with new data to be sent
dataBuffer[2]=i1;
dataBuffer[3]=i2;
dataBuffer[4]=i3;
// create an XOR sum and put this in the last byte
c=0;
c^=i1;
c^=i2;
c^=i3;
dataBuffer[5]=c;
// now start the pin wiggling
dataPin=0;
byteIndex=0;
byteToSend=dataBuffer[0];
bitsSent=0;
bitFlag=0;
sendNextByte=0;
// start timer1 and the interrupt will send the data
preloadTimer1();
startTimer();
// this is a blocking function
while(sending==1){}
}
// main program executes from here
void main(){
initialise();
// at rest, the data line is low
dataPin=0;
// this is the main code loop
while(1){
if(button==0){
// debounce
delay_ms(10);
if(button==0){
// light the led to show we've aknowledged user action
ledBlue=1;
// wait for release
while(button==0){}
// send some data
// (values chosen to be a mix of 1 and 0 in binary)
sendData(179,227,24);
ledBlue=0;
}
}
}
}
void interrupt(){
// every time timer1 fires, we send another part of a bit
// (in Manchester encoding). Bit zero of pir1 is tmr1 overflow interrupt
if(pir1.TMR1IF==1){
// clear the timer1 interrupt flag
pir1.TMR1IF=0;
// preload timer1 to get the next interrupt to occur in a timely manner
preloadTimer1();
// send the appropriate bit-part
sendBit();
}
}
// ##################################
// using a 32 Mhz internal oscillator
// on a PIC16F1825
#pragma DATA _CONFIG1, 0x0804
#pragma DATA _CONFIG2, 0x1DFF
#pragma CLOCK_FREQ 32000000
// ##################################
#define button portc.2
#define testing porta.5
#define dataPin porta.1
#define ledRed portc.5
#define ledGreen portc.4
#define ledBlue portc.3
char c;
char xorsum;
char dataBuffer[6];
char bitsSent=0;
bit bitFlag=0;
char byteToSend=0;
char bytesSent=0;
char byteIndex=0;
bit sendNextByte=0;
bit pinState;
bit sending=0;
// program initialise
void initialise(){
osccon=0b11110000; // oscillator=32mhz
delay_ms(50); // wait for internal voltages to settle
intcon=0b11000000; // global peripheral interrupts enabled
apfcon0=0b01000000; // alternative tx/rx for pickit2/uart
wpua=0xFF; // any inputs on portA have weak pull-ups
wpuc=0xFF; // any inputs on portC have weak pull-ups
trisa=0x00; // portA is all outputs
trisc=0b00000100; // RC.2 is an input (push button)
ansela=0x00; // turn off analogue pins on portA
anselc=0x00; // turn off analogue pins on portC
porta=0x00; // set all output pins on portA off
portc=0x00; // turn off all output pins on portC
option_reg=0x00;
option_reg.7=0; // weak pull-ups enabled on any input pins
// set up timer1
t1con=0b00001000; // set bit zero of t1con to start the timer
pie1.TMR1IE=1; // enable the timer1 interrupt
// enable the global and peripheral interrupts
intcon.GIE=1;
intcon.PEIE=1;
}
// set timer1 value so it fires every X-uS
void preloadTimer1(){
// at 32Mhz, fosc/4=8million
// our radio modules are rated *up to* 4khz
// so let's stick to about half that for now
// 8m/2000 = 4000
// so we want our timer1 to only count up to 4000
// timer1 is a 16-bit timer (0-65535) so we need to
// preload it with 65535-4000 = 61535 (0xF05F)
tmr1h=0xF0;
tmr1l=0x5F;
}
void startTimer(){
// clear any left over interrupt flag
pir1.TMR1IF=0;
// set bit zero to start the timer
t1con.0=1;
}
void stopTimer(){
// clear bit zero to stop the timer
t1con.0=0;
}
void endTransmission(){
// first, kill the timer
stopTimer();
// now wait a timer-width before pulling the
// data line low (in case we've only just pulled
// it high)
delay_100us(5);
// pull the data pin low (end of transmission)
dataPin=0;
// turn off any transmission leds
ledBlue=0;
// kill the sending flag
delay_ms(5);
sending=0;
}
void sendBit(){
if(bitFlag==0){
// work out which way the bit should be sent
// (start low for bit value 1, start high for bit value zero)
// for MSB first, use this
if(byteToSend & 0b10000000){pinState=1;}else{pinState=0;}
// for LSB first, use this
// (MSB first makes it easier to "see" the data on a logic analyser)
//pinState=byteToSend & 1;
// set the pin according to the bit value
dataPin=pinState;
bitFlag=1;
}else{
// it doesn't matter which way the pin is, just toggle it
// the other way
pinState=!pinState;
dataPin=pinState;
// keep track of the number of bits sent
bitsSent++;
if(bitsSent>=8){
sendNextByte=1;
}else{
// nudge up the value in the byteToSend buffer
// for MSB first, shift left
byteToSend=byteToSend<<1;
// for LSB first, shift right
// byteToSend=byteToSend>>1;
sendNextByte=0;
}
bitFlag=0;
}
if(sendNextByte==1){
byteIndex++;
if(byteIndex>=6){
// we've sent three bytes (6 inc preamble + crc)
// so end transmission
endTransmission();
}else{
// prepare the next byte for transmission
byteToSend=dataBuffer[byteIndex];
bitsSent=0;
bitFlag=0;
}
sendNextByte=0;
}
}
// send some data
void sendData(unsigned char i1, unsigned char i2, unsigned char i3){
sending=1;
// send a manchester standard preamble
// alternate 10101010 a few times
// then end the preamble with 10101011
// (two ones indicate end of preamble)
dataBuffer[0]=0b10101010;
dataBuffer[1]=0b10101011;
// fill the data buffer with new data to be sent
dataBuffer[2]=i1;
dataBuffer[3]=i2;
dataBuffer[4]=i3;
// create an XOR sum and put this in the last byte
c=0;
c^=i1;
c^=i2;
c^=i3;
dataBuffer[5]=c;
// now start the pin wiggling
dataPin=0;
byteIndex=0;
byteToSend=dataBuffer[0];
bitsSent=0;
bitFlag=0;
sendNextByte=0;
// start timer1 and the interrupt will send the data
preloadTimer1();
startTimer();
// this is a blocking function
while(sending==1){}
}
// main program executes from here
void main(){
initialise();
// at rest, the data line is low
dataPin=0;
// this is the main code loop
while(1){
if(button==0){
// debounce
delay_ms(10);
if(button==0){
// light the led to show we've aknowledged user action
ledBlue=1;
// wait for release
while(button==0){}
// send some data
// (values chosen to be a mix of 1 and 0 in binary)
sendData(179,227,24);
ledBlue=0;
}
}
}
}
void interrupt(){
// every time timer1 fires, we send another part of a bit
// (in Manchester encoding). Bit zero of pir1 is tmr1 overflow interrupt
if(pir1.TMR1IF==1){
// clear the timer1 interrupt flag
pir1.TMR1IF=0;
// preload timer1 to get the next interrupt to occur in a timely manner
preloadTimer1();
// send the appropriate bit-part
sendBit();
}
}
We changed over to the 16F1825 chip for this, just to aid debugging.
We've used these before and one handy register they have is the APFCON0 register, which allows you to map the UART TX and RX lines onto the same pins as used for programming the chip. This means that when running code, you can add in some serial debugging and have the PICKit2 programmer report back any data received, without having to move jumpers or wires all over the place.
Although we've no serial debugging in this example, our receiver will need lots of debugging, so we're sticking with these 16F1825 chips for now. Also, we can run them at 32Mhz, meaning we get a few extra clock cycles between the timer1 interrupts firing (on an 8Mhz chip, we get a quarter of available clock cycles between interrupts firing to do any processing).
You can use pretty much any chip you like, just change the include and pragma statements at the head of the code to run on your own favourite chip (and maybe the TRIS registers to map the i/o to different pins if necessary).
Anyway, with the code in place, it was time to do some testing. We only recently discovered a really useful tool in the PICKit2 software. And it really is useful - it's a logic analyser. We've used one of these before, and it was invaluable for debugging our sd card initialisation routines about 12 months ago. But it's only recently we discovered that the PICKit2 has a logic analyser built right in! To use the analyser, we simply made our dataOut pin on the transmitter the same as one of the programming pins on the PICKit2.
Now we can simply start our transmitter running, put a test condition in to tell the PICKit2 when to start taking samples, and hit the button to actually send the data.
Here we're using the PICKit2 programmer to provide power to our two PICs (one is the transmitter, one will be the receiver).
One thing to remember is to turn on the voltage supply to the PIC before starting the analyser tool. Our clone programmer doesn't have a cancel button on it. Forget to actually turn the voltage on and the PIC never sends a signal to start the analyser running. This can cause the application to hang and require Task Manager to sort the mess out!
The other highlighted section of this screenshot is the trigger condition. We made our dataPin RA.1 which is also one of the programming pins. So we set up our logic tool to monitor "channel 2" (which we have connected to RA.1 on the transmitter) and we're going to start recording data on a falling edge.
With everything hooked up, it's time to set the logic probe running and hit the transmit button. Below is a composite screenshot of the results
The top part of the image is the data as displayed on the software logic probe. We changed our tranmitter to send the most significant bit (MSB) first, so that the data would be more easily "seen" on our logic probe. At first it just looks like a load of peaks and troughs - we can see we're getting some data through!
The lower part of the image is the same graph, only this time, we've highlighted the high-to-low transition than indicates a bit value of one (the remaining un-highlighted parts show the low-to-high transitions that indicate a bit value of zero).
Now we can actually see the data in binary form. If we decode this binary data back into it's decimal equivalents, we can read back the data, exactly as it was sent from the transmitter.
Now we've got a working single-wire transmitter that can send data using the Manchester encoding, using timer1 interrupts so there's no cumulative drift error. At least now, when it comes to debugging the receiver, we won't have any niggling doubts about whether any problems are with the code in the receiver, or actually an inherent problem with the transmitter. As far as we can see, the transmitter is as "tight" as it can be, and the data should be transmitted consistently with no drift error. It's not going to make debugging the receiver any easier but at least it's one less thing to eliminate if/when it all starts to go horribly wrong!
Sunday, 27 October 2013
Single wire communication between two PIC micros, using 433mhz radio and Manchester encoding - sending
There are plenty of cheap RF transmitter/receiver pairs on sites like eBay and they're a great alternative to implementing full wi-fi for our electronic board game. Instead of wi-fi, we're considering using an ethernet to spi converter to physically plug something into a home router, and using cheap RF comms to get this module to talk to our board game controller.
So our set up will be:
This removes the need for setting up the controller module by flipping between AP mode and infrastructure mode and simplifies things at the user end. Admittedly, this makes things a little more complex to implement, but the cost savings and ease-of-use for the end user should make this extra effort worthwhile. If we can get reliable data flowing between the RF transmitter and receiver, we can re-use this technology to make our quick-draw toy guns communicate wireless-ly too.
So the first thing we need to do is look at implementing single wire communications. Simply put, the state of the data line on the transmitter is reflected instantaneously on the data line of the RF receiver. We're going to re-visit Manchester encoding to transmit data over this single wire interface.
Using Manchester encoding, data is transmitted as a series of rising and falling edges on the data line.
The simplest form of single-wire encoding is to hold the line high to represent a one, and pull it low to represent a zero. This is ok, but can lead to long periods of the data line being held high/low, which can be difficult to decipher as valid data. Manchester encoding uses a low-to-high transition on the line to represent a value one, and a high-to-low transition to represent a zero.
Because we're going to write the firmware for both sender and receiver, we're just going to stick to a known timing rate. Our cheap RF modules are good (according to the datasheet) for up to 4khz - so to send one byte of data by flickering the line at up to 4,000 times per second, we can send 4000/8 = 500 bytes per second. This is more than fast enough for the tiny packets of data we're going to want to send.
To allow plenty of wiggle-room, let's work at 2khz. This means each "frame" in our data is going to be 1/2000 = 0.0005 seconds (0.5ms) "wide". So to transmit the value one, we would hold the data line high for 0.25ms, then pull is low for 0.25ms. To transmit the value zero, we hold the data line low for 0.25ms, then pull high for 0.25ms.
On the receiving end, we can parse the incoming data, store it in a buffer, and assume an end in data transmission when the data line does not change for more than 1ms (this represents 4 "frames" of the data line not changing) For every packet of data we can keep an XOR sum of all the bytes and send this checksum value along as the last byte in the message. As we decode the data on the receiver, we can recreate this XOR sum for each byte is received (obviously excluding the very last byte in the stream) and compare to the calculated value from the transmitter (the last byte in the stream). If the two match, we can say we've successfully decoded the data.
From this rather simplified description, we can already see that transmitting the data is a relatively simple task - we need to split each byte of data into it's constituent bits and flicker the data line, using a simple delay between changing the state of the data line.
Decoding the data on the receiving end is going to take a bit more effort (and probably a bit more debugging) so to begin with, let's create our transmitter, and make sure that this is working correctly.
Here's some Sourceboost C for a Manchester encoding transmitter for a PIC 16F882 (running off it's own internal oscillator) which can be modified by changing the microcontroller set-up bits in the first few lines, for other devices.
The idea is to wait for a button press. When the user presses the button, we transmit some data (the values chosen were just values which had a "nice mix" of ones and zeros in their binary representation). These values will never change, so when we come to write and debug our receiver code, we at least know what values we should be looking for!
Next up, how to receive and decode data on a single wire data interface....
So our set up will be:
- All board sections connected via UART/serial
- Each board section is connected in parallel to the board game controller (connected to one edge of the board)
- The board controller transmits data via cheap RF to a base unit
- The base unit is connected to the home router via ethernet cable
This removes the need for setting up the controller module by flipping between AP mode and infrastructure mode and simplifies things at the user end. Admittedly, this makes things a little more complex to implement, but the cost savings and ease-of-use for the end user should make this extra effort worthwhile. If we can get reliable data flowing between the RF transmitter and receiver, we can re-use this technology to make our quick-draw toy guns communicate wireless-ly too.
So the first thing we need to do is look at implementing single wire communications. Simply put, the state of the data line on the transmitter is reflected instantaneously on the data line of the RF receiver. We're going to re-visit Manchester encoding to transmit data over this single wire interface.
Using Manchester encoding, data is transmitted as a series of rising and falling edges on the data line.
The simplest form of single-wire encoding is to hold the line high to represent a one, and pull it low to represent a zero. This is ok, but can lead to long periods of the data line being held high/low, which can be difficult to decipher as valid data. Manchester encoding uses a low-to-high transition on the line to represent a value one, and a high-to-low transition to represent a zero.
The images on the left show the simplest way of encoding data - high is a one, low is a zero. Images on the right show the same data encoded as a transition in the data line.
Because we're going to write the firmware for both sender and receiver, we're just going to stick to a known timing rate. Our cheap RF modules are good (according to the datasheet) for up to 4khz - so to send one byte of data by flickering the line at up to 4,000 times per second, we can send 4000/8 = 500 bytes per second. This is more than fast enough for the tiny packets of data we're going to want to send.
To allow plenty of wiggle-room, let's work at 2khz. This means each "frame" in our data is going to be 1/2000 = 0.0005 seconds (0.5ms) "wide". So to transmit the value one, we would hold the data line high for 0.25ms, then pull is low for 0.25ms. To transmit the value zero, we hold the data line low for 0.25ms, then pull high for 0.25ms.
On the receiving end, we can parse the incoming data, store it in a buffer, and assume an end in data transmission when the data line does not change for more than 1ms (this represents 4 "frames" of the data line not changing) For every packet of data we can keep an XOR sum of all the bytes and send this checksum value along as the last byte in the message. As we decode the data on the receiver, we can recreate this XOR sum for each byte is received (obviously excluding the very last byte in the stream) and compare to the calculated value from the transmitter (the last byte in the stream). If the two match, we can say we've successfully decoded the data.
From this rather simplified description, we can already see that transmitting the data is a relatively simple task - we need to split each byte of data into it's constituent bits and flicker the data line, using a simple delay between changing the state of the data line.
Decoding the data on the receiving end is going to take a bit more effort (and probably a bit more debugging) so to begin with, let's create our transmitter, and make sure that this is working correctly.
Here's some Sourceboost C for a Manchester encoding transmitter for a PIC 16F882 (running off it's own internal oscillator) which can be modified by changing the microcontroller set-up bits in the first few lines, for other devices.
#include <system.h="">
// this sets up the device to run of it's own internal oscillator, at 8Mhz
#pragma DATA _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTOSCIO
#pragma DATA _CONFIG2, _WRT_OFF
#pragma CLOCK_FREQ 8000000
#define dataPin portc.0
// program initialise
void initialise(){
// set up the internal oscillator
osccon.6=1;
osccon.5=1; // 111=8Mhz
osccon.4=1;
// set up the i/o ports
trisa=0x00; // portA are output pins
trisb=0xFF; // all of portB is an input
trisc=0x00; // portC are output pins
ansel = 0x00; // only digital inputs (no analogue)
anselh = 0x00;
// turn on portb pull up resistors
option_reg.7=0; // _RBPU=0 means enable pull-ups
wpub=0xFF; // this is the individual pull-ups on portb (all enabled)
// initialise the output pins
porta=0x00;
portc=0x00;
}
void ManchesterSend(char iValue){
if(iValue==1){
// zero to rising edge = value 1
dataPin=0;
delay_10us(25);
dataPin=1;
delay_10us(25);
}else{
// one to falling edge zero = value zero
dataPin=1;
delay_10us(25);
dataPin=0;
delay_10us(25);
}
}
void sendByte(char i){
char k=0;
char j=i;
char h=0;
for(k=0; k<8; k++){
h=j & 1;
if(h==0){
ManchesterSend(0);
}else{
ManchesterSend(1);
}
h=h>>1;
}
}
void sendData(char i1, char i2, char i3, char i4){
// this sends some data over a single wire, using Manchester encoding
// first thing send a preamble of 11111101b
sendByte(11111101b);
// create an ongoing XOR sum of all bytes sent
char iXOR=0;
// send each byte and update the XOR sum
sendByte(i1);
iXOR^=i1;
sendByte(i2);
iXOR^=i2;
sendByte(i3);
iXOR^=i3;
sendByte(i4);
iXOR^=i4;
// send the XOR sum as a checksum at the end
sendByte(iXOR);
// pull the data pin low to indicate the end of a transmission
dataPin=0;
}
// main program executes from here
void main(){
initialise();
// this is the main code loop
while(1){
if(portb.0==0){
// debounce
delay_ms(10);
if(portb.0==0){
while(portb.0==0){
// wait for release
}
// send some data
// (values chosen to be a mix of 1 and 0 in binary)
sendData(179,227,24,81);
}
}
}
}
void interrupt(){
// no interrupts used in this transmitter
}
// this sets up the device to run of it's own internal oscillator, at 8Mhz
#pragma DATA _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTOSCIO
#pragma DATA _CONFIG2, _WRT_OFF
#pragma CLOCK_FREQ 8000000
#define dataPin portc.0
// program initialise
void initialise(){
// set up the internal oscillator
osccon.6=1;
osccon.5=1; // 111=8Mhz
osccon.4=1;
// set up the i/o ports
trisa=0x00; // portA are output pins
trisb=0xFF; // all of portB is an input
trisc=0x00; // portC are output pins
ansel = 0x00; // only digital inputs (no analogue)
anselh = 0x00;
// turn on portb pull up resistors
option_reg.7=0; // _RBPU=0 means enable pull-ups
wpub=0xFF; // this is the individual pull-ups on portb (all enabled)
// initialise the output pins
porta=0x00;
portc=0x00;
}
void ManchesterSend(char iValue){
if(iValue==1){
// zero to rising edge = value 1
dataPin=0;
delay_10us(25);
dataPin=1;
delay_10us(25);
}else{
// one to falling edge zero = value zero
dataPin=1;
delay_10us(25);
dataPin=0;
delay_10us(25);
}
}
void sendByte(char i){
char k=0;
char j=i;
char h=0;
for(k=0; k<8; k++){
h=j & 1;
if(h==0){
ManchesterSend(0);
}else{
ManchesterSend(1);
}
h=h>>1;
}
}
void sendData(char i1, char i2, char i3, char i4){
// this sends some data over a single wire, using Manchester encoding
// first thing send a preamble of 11111101b
sendByte(11111101b);
// create an ongoing XOR sum of all bytes sent
char iXOR=0;
// send each byte and update the XOR sum
sendByte(i1);
iXOR^=i1;
sendByte(i2);
iXOR^=i2;
sendByte(i3);
iXOR^=i3;
sendByte(i4);
iXOR^=i4;
// send the XOR sum as a checksum at the end
sendByte(iXOR);
// pull the data pin low to indicate the end of a transmission
dataPin=0;
}
// main program executes from here
void main(){
initialise();
// this is the main code loop
while(1){
if(portb.0==0){
// debounce
delay_ms(10);
if(portb.0==0){
while(portb.0==0){
// wait for release
}
// send some data
// (values chosen to be a mix of 1 and 0 in binary)
sendData(179,227,24,81);
}
}
}
}
void interrupt(){
// no interrupts used in this transmitter
}
The idea is to wait for a button press. When the user presses the button, we transmit some data (the values chosen were just values which had a "nice mix" of ones and zeros in their binary representation). These values will never change, so when we come to write and debug our receiver code, we at least know what values we should be looking for!
Next up, how to receive and decode data on a single wire data interface....
20 ton workshop press for die cutting
A while back, we had some dies made by a company called Joseph Dixon. They are an excellent die-manufacturers: taking our simple vector art and creating a number of box-shaped dies which are far and away better than the hopeless versions we supplied!
Having had dies made, we looking to getting a clicker press to use them. Clicker presses are not only very expensive, but they also require quite a bit of room. Having neither the space (nor the money) to afford a die clicker, we got the next-best thing - a 20-ton bottle press of course!
Now Paul is quite getting into his custom embossing (laser cutting shapes and embedding them into an mdf base before using them to emboss leather and leather-coated objects - notebooks, iPad/tablet cases and the like) so with a few of us showing an interest in using it, Paul took the initiative and set it up.
For our die cutting, we used a couple of 3/4 inch thick steel plates (they are very very heavy!) making a cutting make/die sandwich
It took a few attempts to find out how much pressure to use (it was lots, btw) and the surface to cut onto (a cutting mat placed straight onto the lower metal plate) before we got a good clean cut. But eventually, a few box-shapes came off the press:
The die we designed not only cut the outline shape, but also a window in the centre of one face, and also creates the crease lines for folding along each edge.
Cutting two or three sheets of card at a time on a manual bench press is much slower using a pneumatic clicker press. But it's also about 50 times cheaper to implement, and still much quicker than manually cutting each box using a knife and scissors. So we're calling it another win!
Having had dies made, we looking to getting a clicker press to use them. Clicker presses are not only very expensive, but they also require quite a bit of room. Having neither the space (nor the money) to afford a die clicker, we got the next-best thing - a 20-ton bottle press of course!
Now Paul is quite getting into his custom embossing (laser cutting shapes and embedding them into an mdf base before using them to emboss leather and leather-coated objects - notebooks, iPad/tablet cases and the like) so with a few of us showing an interest in using it, Paul took the initiative and set it up.
For our die cutting, we used a couple of 3/4 inch thick steel plates (they are very very heavy!) making a cutting make/die sandwich
Here we have a metal plate, a cutting mat, the card being cut, the die doing the cutting, and a second metal plate, all being squashed together by the 20-ton hydraulic bottle press.
It took a few attempts to find out how much pressure to use (it was lots, btw) and the surface to cut onto (a cutting mat placed straight onto the lower metal plate) before we got a good clean cut. But eventually, a few box-shapes came off the press:
The die we designed not only cut the outline shape, but also a window in the centre of one face, and also creates the crease lines for folding along each edge.
Cutting two or three sheets of card at a time on a manual bench press is much slower using a pneumatic clicker press. But it's also about 50 times cheaper to implement, and still much quicker than manually cutting each box using a knife and scissors. So we're calling it another win!
More miniatures painting - Wild West characters
During a few hours this weekend (the storms are brewing and it's cold and windy outside, so it's better to be indoors, wrapped up and warm!) I painted up a couple of Wild West characters. I started with two well known "cowboys" - Billy the Kid and Pat Garrett.
Using the Army Painter Quickshade method of painting, the first thing to do is block out all the basic colours. For these models, I'm trying something I've never done before and that's to paint the black for the eye outlines before applying QuickShade. The reason for this is, if I paint the black after and slip with the paintbrush, it can be quite difficult to match the surrounding colour to paint over any mistakes. Any mistakes made at this stage can be easily covered up, using just the pure flesh base colour.
The rest of the colours are deliberately garish and bright before applying the Quickshade. My reasoning is this: I love the bright, heavily saturated colour palette used in late 80s, early 90s Games Workshop 'Eavy Metal showcases.
But using Quickshade tones down any colour scheme quite considerably. That said, a darkened model, with brilliant, bright highlights invokes this same high-contrast colour scheme as with early GW paint-jobs (without the need to be such a brilliant model painter!). So this is my current painting method:
- block out the basic colours, using bright, vibrant shades
- slather on some Strong Tone QuickShade
- apply some Testor's DullCote matt varnish
- edge highlight (and tidy up) the miniature using the original selection of colours
- paint tiny details (faces, eyes, buttons etc)
Done!
Here's Billy The Kid and the cowardly snake-in-the-grass Pat Garrett, pretty much finished - only the bases and some tiny bits of touching up are needed to finish them off:
While it's very tempting to stick to a palette of grey and brown (the Wild West was a dirty, grubby place and not many outlaws wore flamboyant, brightly coloured garments) it's also important to keep the miniatures looking interesting - so I chose a pastel green and a splash of bright red for Billy's neckerchief.
While Pat Garrett was known to Billy the Kid (some historians go as far to say the two were friends) I wanted to emphasise that Pat was no longer "one of the guys" so painted him up with richer colours - a velvet waistcoat and red-lined overcoat along with a pale-coloured suade jacket make him stand apart from the other gang members, physically as well as spiritually (the stripey trousers were a bit of a failure! They need re-doing). The idea is to convey that he's got a bit more money (after being made a sheriff) so is more interested in having nicer clothes than any gang of outlaws.
The free-hand on these legs are not very good - I might just repaint them and stick with a complete solid colour, although patterned trousers do add a bit more interest to this model.
The photos don't really do the miniatures justice: I need to sort out a proper lighting rig and learn how to take photos - the minis do look much better in real life! These photos were taken at night, under flourescent lighting and with a harsh LED flash on the camera; with a proper photo-rig, I might be able to show the colours properly.
But that's it for tonight: two models painted up over the course of an evening which isn't really bad going for me! A few more and we'll have enough to try out a simple gunfight skirmish when the PCBs arrive for our electronic board game....
Friday, 25 October 2013
Electronic quick draw toy gun
While we're waiting for the pcbs to arrive to assemble our first "proper" boardgame prototypes, we've been trying out different ideas for re-using the technology in different board games. One idea that has generated some interest is a Wild West skirmish game.
Of course, no Wild West game would be complete without the fast-draw shootout at High Noon.
Originally we thought that, in a two player game, each player could have a button. After a specific signal, first to hit the button wins the shootout. It seemed like a quick and easy way to add an extra element to a Wild West themed board game.
But then, of course, we had to go one step further. With guns.
These were little plastic toy guns (are toy guns hard to find these days or what?!) from a local pound store. Or it may have been a 99p store. But you get the idea - cheap, plastic guns, with a hammer on an elastic band. Perfect!
The idea now is that two players face off, first to draw their gun and pull the trigger wins the shootout.
That's great - except just replacing the pushbutton idea with pulling the trigger means a player could - in theory at least - leave their gun in the holster, shoot themselves in the foot and claim to have won the shoot out.
We needed a way of checking to see if the gun was at least out of it's holster - a simple tilt switch would suffice! We did originally try using two tilt switches, to measure if the gun was roughly horizontal, but this proved problematic: if we checked the state of the tilt switches at the point where the hammer came down on the gun (the point at which it would normally fire a bullet) the vibration of this could sometimes cause a false reading: the gun may be perfectly horizontal, but because of the shock/movement, the tilt switch reported no connection.
So the design was simplified - the tilt switch can detect when the gun is vertical, and when the gun has passed through the horizontal plane. Once the gun has at least passed through horizontal, we set a flag and transmit this data when the trigger is pulled. It's not perfect, because the player could be pointing the gun at the ceiling rather than at their opponent and still register a successful shot - but it's better than them being able to shoot at the floor and claim to have fired on their opponent first.
For testing, we've got wired connections going to a breadboard. But also on the breadboard is a 433mhz transmitter (the little square thing with four legs) and on another board we've a receiver. So we're able to send data wirelessly from the gun to a host controller, meaning we can stuff all our electronics inside the gun and have a completely wire-free controller.
Of course, no Wild West game would be complete without the fast-draw shootout at High Noon.
Originally we thought that, in a two player game, each player could have a button. After a specific signal, first to hit the button wins the shootout. It seemed like a quick and easy way to add an extra element to a Wild West themed board game.
But then, of course, we had to go one step further. With guns.
These were little plastic toy guns (are toy guns hard to find these days or what?!) from a local pound store. Or it may have been a 99p store. But you get the idea - cheap, plastic guns, with a hammer on an elastic band. Perfect!
The idea now is that two players face off, first to draw their gun and pull the trigger wins the shootout.
That's great - except just replacing the pushbutton idea with pulling the trigger means a player could - in theory at least - leave their gun in the holster, shoot themselves in the foot and claim to have won the shoot out.
We needed a way of checking to see if the gun was at least out of it's holster - a simple tilt switch would suffice! We did originally try using two tilt switches, to measure if the gun was roughly horizontal, but this proved problematic: if we checked the state of the tilt switches at the point where the hammer came down on the gun (the point at which it would normally fire a bullet) the vibration of this could sometimes cause a false reading: the gun may be perfectly horizontal, but because of the shock/movement, the tilt switch reported no connection.
So the design was simplified - the tilt switch can detect when the gun is vertical, and when the gun has passed through the horizontal plane. Once the gun has at least passed through horizontal, we set a flag and transmit this data when the trigger is pulled. It's not perfect, because the player could be pointing the gun at the ceiling rather than at their opponent and still register a successful shot - but it's better than them being able to shoot at the floor and claim to have fired on their opponent first.
For testing, we've got wired connections going to a breadboard. But also on the breadboard is a 433mhz transmitter (the little square thing with four legs) and on another board we've a receiver. So we're able to send data wirelessly from the gun to a host controller, meaning we can stuff all our electronics inside the gun and have a completely wire-free controller.
Here Stephen is testing the gun-flicking action - registering when the gun has been raised to horizontal (i.e. removed from it's holster) and registering when the trigger has been pulled (and the gun has been fired).
Although there are wires everywhere and it doesn't look anywhere near finished, we concluded that this was a successful test: everything we wanted to test worked, and the gun did report - over a wireless radio connection - it's status when the trigger was pulled.
Now all we need to do is find a supplier of larger toy guns - with a gun designed for a small child's hands, you're just as likely to flip the gun out of it's holster and throw it across the room as to get your grown-up-sized fingers around the handle properly!
Tuesday, 22 October 2013
Breakout board for HLK-RM04 wifi module
A while back we got some cheap wi-fi modules from Chinaland, which are proving quite popular on various online stores: despite different appearances, they're all variations on this module, the HLK-RM04:
Some have a covering over the chips to make them difficult to distinguish, but it's basically the same board underneath:
The thing to notice is the little ceramic onboard antenna (or lack of it) next to the gold antenna connection point (it looks like an oversized 1206 SMT resistor: the first photo has one, the second - if you look at the top-left of the module - doesn't).
Our module has an onboard antenna, but it's range is pathetically limited - it couldn't even pick up the router from across the main room at BuildBrighton tonight; soldering a "genuine" antenna did enable the module to connect to the router, although it reported a signal strength of 0% most of the time!
What isn't apparent from the photos above (and we didn't notice until after they'd arrived) is that the pin spacing on these modules is not the standard 0.1" pitch - it's much smaller (probably nearer 0.0625"). So before we could try using these, we had to make a breakout board so we could poke wires onto the pins and actually see some data flying around:
It only took most of the evening (after an aborted press-n-peel attempt and some drilling disasters on another board) but eventually we managed to get our wi-fi module onto a breakout board that was suitable for testing.
With so much time lost to making the board, we didn't have very long to spend getting data in and out of the device. As usual, Steve came to the rescue with his l33t Arduino skillz and demonstrated that the device could operate in both AP (access point) and infrastructure modes. We were even able to query the device and get it to return the dynamically assigned IP address it got from the BuildBrighton router as it changed from one mode to the other.
With our pcbs on order and awaiting delivery, it's important that we can get as far as possible with the wi-fi side of things, so that when the boards arrive, we can just hook them up and have them talking to our software, quickly and easily. So far everything's looking quite promising. Talking to the modules over serial is a bit clunky and they're not very quick to respond, but they seem to be working well enough for what we need. But then again, if there are any problems, we know we can always fall back on the excellent Wi-Fly modules from Farnell.
For the next few nights, we'll probably battle on with these and see what they can do!
Some have a covering over the chips to make them difficult to distinguish, but it's basically the same board underneath:
The thing to notice is the little ceramic onboard antenna (or lack of it) next to the gold antenna connection point (it looks like an oversized 1206 SMT resistor: the first photo has one, the second - if you look at the top-left of the module - doesn't).
Our module has an onboard antenna, but it's range is pathetically limited - it couldn't even pick up the router from across the main room at BuildBrighton tonight; soldering a "genuine" antenna did enable the module to connect to the router, although it reported a signal strength of 0% most of the time!
What isn't apparent from the photos above (and we didn't notice until after they'd arrived) is that the pin spacing on these modules is not the standard 0.1" pitch - it's much smaller (probably nearer 0.0625"). So before we could try using these, we had to make a breakout board so we could poke wires onto the pins and actually see some data flying around:
It only took most of the evening (after an aborted press-n-peel attempt and some drilling disasters on another board) but eventually we managed to get our wi-fi module onto a breakout board that was suitable for testing.
With so much time lost to making the board, we didn't have very long to spend getting data in and out of the device. As usual, Steve came to the rescue with his l33t Arduino skillz and demonstrated that the device could operate in both AP (access point) and infrastructure modes. We were even able to query the device and get it to return the dynamically assigned IP address it got from the BuildBrighton router as it changed from one mode to the other.
With our pcbs on order and awaiting delivery, it's important that we can get as far as possible with the wi-fi side of things, so that when the boards arrive, we can just hook them up and have them talking to our software, quickly and easily. So far everything's looking quite promising. Talking to the modules over serial is a bit clunky and they're not very quick to respond, but they seem to be working well enough for what we need. But then again, if there are any problems, we know we can always fall back on the excellent Wi-Fly modules from Farnell.
For the next few nights, we'll probably battle on with these and see what they can do!
Sunday, 20 October 2013
Creating a sci-fi industrial base for our space-themed miniatures
Just a quick update on our sci-fi soldiers/robots miniatures - having struggled to come up with anything suitable for the bases for our miniatures (except some excellent looking modelling-putty-stamps on Kickstarter) we eventually hit on a solution: curtain netting.
Or more specifically, that weird netting they sell in Fabric Land on Western Road in Brighton - the stuff that comes in all colours and is usually used for frills on skirts and to make tu-tus from. That stuff.
A liberal dose of glue was put over the bases and the netting stretched and glued in place. Once the glue had dried, the netting was trimmed from around the edges of the base using a craft knife, and the entire base was painted black
The entire base was drybrushed with gun metal paint. The idea was to get a dark silvery colour over the whole of the base, not just the raised industrial-grid-like pattern, so drybrushing was done with the brush vertical (at 90 degrees to the plane of the base)
This allowed the bristles to get onto the actual base between the mesh, but still kept a dark shadow effect under each hole in the grill. Then the entire base was drybrushed with a brighter, shining armour silver. This time the brush was held almost horizontally, so that the drybrushing only touched the top surface of the grid pattern
The end result was an industrial looking base which fits in perfectly with our spaceship-themed playing surface:
Or more specifically, that weird netting they sell in Fabric Land on Western Road in Brighton - the stuff that comes in all colours and is usually used for frills on skirts and to make tu-tus from. That stuff.
A liberal dose of glue was put over the bases and the netting stretched and glued in place. Once the glue had dried, the netting was trimmed from around the edges of the base using a craft knife, and the entire base was painted black
The entire base was drybrushed with gun metal paint. The idea was to get a dark silvery colour over the whole of the base, not just the raised industrial-grid-like pattern, so drybrushing was done with the brush vertical (at 90 degrees to the plane of the base)
This allowed the bristles to get onto the actual base between the mesh, but still kept a dark shadow effect under each hole in the grill. Then the entire base was drybrushed with a brighter, shining armour silver. This time the brush was held almost horizontally, so that the drybrushing only touched the top surface of the grid pattern
The end result was an industrial looking base which fits in perfectly with our spaceship-themed playing surface:
Removing QuickShade shine with Testors DullCote
There are plenty of posts about "frosting" when using matt varnish all over the internet. We've had a right old time with it on a few plastic miniatures too, and were beginning to wonder if this Quickshade was going to work out for us after all.
One solution that comes up again and again is (to brush on some) Testor's Dull Cote.
This morning the postie knocked on the door and handed over our latest eBay purchase. Here's a before and after of the models:
Before DullCote - after applying QuickShade and allowing to dry for 24 hours:
Quickshade does a great job of picking out the details while keeping the colours from looking too muddy (an effect that often occurs using GW/Citadel Devlan Mud ink for shading) but makes the miniature look very glossy.
After applying DullCote:
The miniature on the left has Dullcote applied which is mostly dry - the model on the right has Dullcote applied but is still wet (which is why there's still a bit of a sheen on the paintwork)
The Testor's DullCote works just fine for us. It removes the shine off the QuickShade without affecting the colouring or intensity of the colours it's painted over. The lacquer was ready to paint over (with simple highlights and facial details) in about an hour or so and the final model not only had a nice, matt finish, it's always reassuring to know the model has had a coat of varnish which will protect all but the top-most coat(s) of paint.
Using the Army Painter method of painting multiple miniatures at once, and with the help of my new cheapo wet palette, I managed to finish three more space-soldiers this afternoon.
That makes five. Ideally I'd like each team in the Starship Raiders game to have six or more characters. But I've only five leaded soldiers, so we'll just have to go with five for now!
Here's how they could look on a modular board section:
Sadly the bases are really letting the miniatures down now - time to ask Mr Google how best to finish the bases so that they fit in with the industrial/sci-fi style board.
Why use a wet palette when painting miniatures?
Because it saves paint of course!
I made my first wet palette yesterday. It's nothing fancy - a bit of washing up sponge and some baking paper in a pencil case. The whole thing cost less than three quid (including the pencil case and enough paper to last 40 years!)
Putting paint onto a wet palette keeps it workable for hours, not minutes - and all without any extender or retarder. So you use less paint because you're not replenishing what's just dried up every 15-20 minutes or so. During painting, you can snap the lid shut and go and have a cup of tea and come back and the paint is still good to use.
But it's even better than that.
Last night I was painting 'til the early hours (the wife is away and the nerds were all back home from playing at the local hackspace). I just snapped the paint lid shut and went to bed.
Eight hours later, I checked the paint as I walked past to put the kettle on. It was still fine!
The wet palette kept may paint good for over eight hours! There's a little colour separation on the red and the blue paint, but that's nothing a quick mix around won't fix. Suddenly I'm able to use every drop of paint that comes out of the bottle. So now I'm no longer putting big blobs of paint down, in the vain attempt that it'll stay workable for 20 mins or more, in order to paint more than a couple of miniatures at a time.
For something so cheap and so simple, I was amazed at the results. The paints stay wet on the palette but - unlike using a retarding agent - they dry quickly on the model. Now I just need to improve my painting skills to get the best out of my paints!
I made my first wet palette yesterday. It's nothing fancy - a bit of washing up sponge and some baking paper in a pencil case. The whole thing cost less than three quid (including the pencil case and enough paper to last 40 years!)
Putting paint onto a wet palette keeps it workable for hours, not minutes - and all without any extender or retarder. So you use less paint because you're not replenishing what's just dried up every 15-20 minutes or so. During painting, you can snap the lid shut and go and have a cup of tea and come back and the paint is still good to use.
But it's even better than that.
Last night I was painting 'til the early hours (the wife is away and the nerds were all back home from playing at the local hackspace). I just snapped the paint lid shut and went to bed.
Eight hours later, I checked the paint as I walked past to put the kettle on. It was still fine!
Even after eight hours, the brush picked up the acrylic as if it had just come out of the bottle.
The wet palette kept may paint good for over eight hours! There's a little colour separation on the red and the blue paint, but that's nothing a quick mix around won't fix. Suddenly I'm able to use every drop of paint that comes out of the bottle. So now I'm no longer putting big blobs of paint down, in the vain attempt that it'll stay workable for 20 mins or more, in order to paint more than a couple of miniatures at a time.
For something so cheap and so simple, I was amazed at the results. The paints stay wet on the palette but - unlike using a retarding agent - they dry quickly on the model. Now I just need to improve my painting skills to get the best out of my paints!
Saturday, 19 October 2013
Painting miniatures with a wet palette and Army Painter paints
What's a wet palette?
I had no idea too, until I realised that my painting technique was changing over the course of 10 or 20 minutes. At first, the paint is really smooth and sometimes takes two coats to cover darker shades. Then, maybe 10-15 minutes later, it's thickened up and is covering really easily. That's great for block colouring, but a bit of a pain using the same paint for little details (which are more easily painted using thinner, easier-flowing paint).
I've been burning through my Army Painter paints, regularly dropping paints onto my ceramic palette (an upturned espresso cup!). Mixing paints from the dropper bottles is great, but because my paints are drying out so quickly, I'm finding I'm using a lot of paint and not actually getting much painted!
The answer? A wet palette.
I'd heard of these, but never bothered with them - it sounds too much like advanced techniques for really good painters (wet blending, gradient shading and so on). It turned out it's nothing like that. It's just a way of creating a palette which keeps the paint wet for longer.
Wet palettes can be bought at most art shops and even online. You can pay anywhere between £10 and £50 for a decent set up. I'm not bothered about decent. Cheap and cheerful will do me, until I know what it actually is/does!
Here are the ingredients for my wet palette. The maths set cost £1, the sponges 90p and the baking paper £1.20 (all from Tesco) - total cost: £3.10.
I took one sponge, cut the green scouring pad off and split it in half long-ways. Using a sharp knife (only ever use sharp knives - blunt ones are really dangerous!) I cut the moulded bits inside the maths set box and put wet sponges inside the box. The baking paper is folded to help it resisting curling as it gets wet.
As a trial, I put some "fur brown" paint onto the paper and used a bit on a model.
I chose this paint because it tends to be quite thin to begin with, but skins over - and once a skin has formed, it tends to dry out quite quickly (within another 10 minutes or so). I rinsed my brushes, closed the palette lid and went and made a brew.
Then I went to the shop and got a paper. After reading the paper I got a bit peckish, so made some cheap instant noodles. Then another brew, and after a total of an hour and a half, I tried the paint. It was still fluid and usable. Not only usable, but in the same condition as it was when it first came out of the bottle: no skinning over, no thickening, it still took two coats to cover the slightly darker colours on a model.
So in short - a successful, cheap wet palette. Hopefully this means I'll be reaching for the bottles of paint much less often and can concentrate on smudging paint over the miniatures rather than mixing and dispensing it.
I had no idea too, until I realised that my painting technique was changing over the course of 10 or 20 minutes. At first, the paint is really smooth and sometimes takes two coats to cover darker shades. Then, maybe 10-15 minutes later, it's thickened up and is covering really easily. That's great for block colouring, but a bit of a pain using the same paint for little details (which are more easily painted using thinner, easier-flowing paint).
I've been burning through my Army Painter paints, regularly dropping paints onto my ceramic palette (an upturned espresso cup!). Mixing paints from the dropper bottles is great, but because my paints are drying out so quickly, I'm finding I'm using a lot of paint and not actually getting much painted!
The answer? A wet palette.
I'd heard of these, but never bothered with them - it sounds too much like advanced techniques for really good painters (wet blending, gradient shading and so on). It turned out it's nothing like that. It's just a way of creating a palette which keeps the paint wet for longer.
Wet palettes can be bought at most art shops and even online. You can pay anywhere between £10 and £50 for a decent set up. I'm not bothered about decent. Cheap and cheerful will do me, until I know what it actually is/does!
Here are the ingredients for my wet palette. The maths set cost £1, the sponges 90p and the baking paper £1.20 (all from Tesco) - total cost: £3.10.
I took one sponge, cut the green scouring pad off and split it in half long-ways. Using a sharp knife (only ever use sharp knives - blunt ones are really dangerous!) I cut the moulded bits inside the maths set box and put wet sponges inside the box. The baking paper is folded to help it resisting curling as it gets wet.
As a trial, I put some "fur brown" paint onto the paper and used a bit on a model.
I chose this paint because it tends to be quite thin to begin with, but skins over - and once a skin has formed, it tends to dry out quite quickly (within another 10 minutes or so). I rinsed my brushes, closed the palette lid and went and made a brew.
Then I went to the shop and got a paper. After reading the paper I got a bit peckish, so made some cheap instant noodles. Then another brew, and after a total of an hour and a half, I tried the paint. It was still fluid and usable. Not only usable, but in the same condition as it was when it first came out of the bottle: no skinning over, no thickening, it still took two coats to cover the slightly darker colours on a model.
So in short - a successful, cheap wet palette. Hopefully this means I'll be reaching for the bottles of paint much less often and can concentrate on smudging paint over the miniatures rather than mixing and dispensing it.
More miniatures painting
The PCBs are designed, tested, and on order now - just need to wait about 10 days for the first batch of ten from the manufacturer so we can try out some prototype boards - very exciting!
While we're waiting for the boards back, there's still plenty to do.
So of course, everything else has gone on hold and we're back to painting miniatures. Or at least, I am!
I'm trying the Army Painter method of cranking out miniatures, but I'm not very good at it. I know the theory - get one colour and paint it onto all miniatures, get the next, paint it across all your miniatures and so on. A quick splash of QuickShade and some highlighting and you're done.
That's fine - except it means it's a lot time between taking your first primed miniature and seeing a finished model (although using the A/P method, you do end up with about 10 finished miniatures all at once).
I've been painting two or three at a time, and that's plenty for me!
Having not painted miniatures for a long time, I've forgotten the most important rule: knowing when to stop. Knowing when to say "if I carry on, I'll more than likely make this model worse, rather than improve it" is a skill, as much as keeping a steady hand to get the right blob of colour in the right place with a paintbrush.
So I've decided it's time to stop with these models.
I can't do all the fancy blending and shading and ultra-realistic looking effects. But these models are about as good as I can get them without messing them up, so it's time to say "they're done". Well, as far as painting goes anyway (finishing the bases is another minefield I've yet to negotiate).
The eagle-eyed will already have spotted a few brush-slips here and there, but in the main, they're good enough to go on to our first prototype game boards (once they're built).
The black-and-yellow stripes on the robot are a bit wonky but, having decided these are finished, they'll just have to stay like that (knowing when to stop is a skill I'm slowly learning).
Most nerds are familiar with tabletop war-gaming, 28mm miniatures and the like. When I first asked at BuildBrighton if anyone had any experience with miniature gaming, there was complete silence. Over eighty people had no idea what I was talking about. But slowly, over the last few weeks, more and more have started to take an interest in the board game project, and have started saying things like "I think I had some miniatures once.... Space somethings.... Space Marines I think" and a few have even admitted to not only playing, but also painting miniatures for various board games over the years!
For the non-gaming nerds, here's a photo to try to show the scale of these models:
While we're waiting for the boards back, there's still plenty to do.
So of course, everything else has gone on hold and we're back to painting miniatures. Or at least, I am!
I'm trying the Army Painter method of cranking out miniatures, but I'm not very good at it. I know the theory - get one colour and paint it onto all miniatures, get the next, paint it across all your miniatures and so on. A quick splash of QuickShade and some highlighting and you're done.
That's fine - except it means it's a lot time between taking your first primed miniature and seeing a finished model (although using the A/P method, you do end up with about 10 finished miniatures all at once).
I've been painting two or three at a time, and that's plenty for me!
Having not painted miniatures for a long time, I've forgotten the most important rule: knowing when to stop. Knowing when to say "if I carry on, I'll more than likely make this model worse, rather than improve it" is a skill, as much as keeping a steady hand to get the right blob of colour in the right place with a paintbrush.
So I've decided it's time to stop with these models.
I can't do all the fancy blending and shading and ultra-realistic looking effects. But these models are about as good as I can get them without messing them up, so it's time to say "they're done". Well, as far as painting goes anyway (finishing the bases is another minefield I've yet to negotiate).
The eagle-eyed will already have spotted a few brush-slips here and there, but in the main, they're good enough to go on to our first prototype game boards (once they're built).
The black-and-yellow stripes on the robot are a bit wonky but, having decided these are finished, they'll just have to stay like that (knowing when to stop is a skill I'm slowly learning).
Most nerds are familiar with tabletop war-gaming, 28mm miniatures and the like. When I first asked at BuildBrighton if anyone had any experience with miniature gaming, there was complete silence. Over eighty people had no idea what I was talking about. But slowly, over the last few weeks, more and more have started to take an interest in the board game project, and have started saying things like "I think I had some miniatures once.... Space somethings.... Space Marines I think" and a few have even admitted to not only playing, but also painting miniatures for various board games over the years!
For the non-gaming nerds, here's a photo to try to show the scale of these models:
(the minis in this photo have been QuickShaded but not yet dull-coated so they're super-shiny. The coin in the photo is a modern UK 50 pence piece)
In my younger days, I might have wanted a finish like the McVey Studio miniatures.
These days I'm just thrilled that my eyes hold out enough to get the basic colours in roughly the right areas!
Next, it's time to learn how to finish the bases for miniatures onboard a space ship (the usual textured-sand-and-drybrush finish for a grass-effect base would just look weird).
These "stampers" on Kickstarter (http://www.kickstarter.com/projects/1843680961/base-stampers-textured-base-stamps-for-miniature-w) look great but might be difficult to use, given I've superglued the miniatures in place on the bases. I think in future I need to look at the base and the model separately then just join them together at the end.
Right now, however, I'm just pleased that I've got three miniatures "finished" and another four or five almost ready to join them!
Monday, 14 October 2013
Digital board game - assembly finished
Another afternoon at BuildBrighton this weekend, and the assembly of the digital board section prototype is finally complete. To complete the project, we first took a printed and laminated top layer and cut to size.
Then we stuck some copper tape onto folded-up bits of masking tape and cut them into little circles using a hole punch (sticking the copper onto masking tape just made it easier to get the backing off each individual circle).
The little copper circles were placed in the dead-centre of the reverse of each playing square on the board.
Because the double-sided pcb was actually made in two sections, with panel pins acting as vias, the separator layer needed to be a bit thicker than in previous prototypes. In fact, with the panel pin heads being up to 1mm from the surface of the pcb, the separator layer was made from strips of 1mm plasticard from LSA Models (on Sackville Road in Hove)
With all the hardware in place, the top layer was placed over the PCB and stuck firmly to the separator layer. A quick test for continuity proved that the copper circles were (thankfully) in the correct places, on the underside of this top layer!
The last thing to so was to burn the firmware onto the PIC and solder it to the underside of the PCB:
The firmware uses multi-plexing to continually poll the input port and report back which squares (if any) are pressed. Only when a square changes state (an empty square receives a playing piece, or a previously occupied square goes empty) is a change in state registered, and a serial data stream sent back to the host controller via UART.
After a couple of false starts (and a bit of hacking to the pcb layout to allow the firmware to be updated while the PIC is in place on the circuit board) we managed to get what looks like useable data from our board game section.
So all in all, a successful test!
The PCB is a bit rough-n-ready and the top layer floats far too high above the push-button style contacts on the underlying board (we really have to press our squares down hard) but that's only because of the limitations of making a homebrew double-sided PCB. A professionally manufactured board would be completely flat, allowing us to use a much thinner separator membrane - like paper, acetate or card - and make the entire board more responsive to a playing piece being placed on each square.
The point of this test was to prove whether or not the pcb design was good, not how the board played with pieces on it - and having proved that it is, we can get some manufactured and now concentrate on the assembly process of the rest of the board!
Then we stuck some copper tape onto folded-up bits of masking tape and cut them into little circles using a hole punch (sticking the copper onto masking tape just made it easier to get the backing off each individual circle).
The little copper circles were placed in the dead-centre of the reverse of each playing square on the board.
Because the double-sided pcb was actually made in two sections, with panel pins acting as vias, the separator layer needed to be a bit thicker than in previous prototypes. In fact, with the panel pin heads being up to 1mm from the surface of the pcb, the separator layer was made from strips of 1mm plasticard from LSA Models (on Sackville Road in Hove)
With all the hardware in place, the top layer was placed over the PCB and stuck firmly to the separator layer. A quick test for continuity proved that the copper circles were (thankfully) in the correct places, on the underside of this top layer!
The last thing to so was to burn the firmware onto the PIC and solder it to the underside of the PCB:
The firmware uses multi-plexing to continually poll the input port and report back which squares (if any) are pressed. Only when a square changes state (an empty square receives a playing piece, or a previously occupied square goes empty) is a change in state registered, and a serial data stream sent back to the host controller via UART.
After a couple of false starts (and a bit of hacking to the pcb layout to allow the firmware to be updated while the PIC is in place on the circuit board) we managed to get what looks like useable data from our board game section.
(deflection in the video is deliberately exaggerated so you can see what is happening: press a square, get some serial data, release a square, get more serial data)
As well as providing instant feedback whenever a square was pressed/released, we are also able to query the state of the entire board section using serial commands:
At the bottom of the list of data, in the monitor screenshot above, you can see a square being pressed (the message FF 44 45 FE C4 FD tells us that board number 0x4445 had the square at 0xC4 pressed) then the command 0xC9 (this is a special command to say "what state are you in?") being sent to the board section with id 0x44 0x45. The response message writes out the state of every square on the board. In among all the zeros (empty squares) is a single entry: 0x40 - this is a binary value: 01000000 which corresponds to the second square in the third column being pressed down. There's only a single non-zero bit in the data, which is correct - we pressed only one square at a time on the board during testing.
The PCB is a bit rough-n-ready and the top layer floats far too high above the push-button style contacts on the underlying board (we really have to press our squares down hard) but that's only because of the limitations of making a homebrew double-sided PCB. A professionally manufactured board would be completely flat, allowing us to use a much thinner separator membrane - like paper, acetate or card - and make the entire board more responsive to a playing piece being placed on each square.
The point of this test was to prove whether or not the pcb design was good, not how the board played with pieces on it - and having proved that it is, we can get some manufactured and now concentrate on the assembly process of the rest of the board!
Friday, 11 October 2013
How to find the pin-out for an 8x8 LED matrix
Determined not to let last night's BuildBrighton meeting be a waste (I forgot half my stuff and couldn't get the other half to work!) I put some prep-work in for the word clock idea that Steve and I spoke about a little while back.
I had some 8x8 LED matrix modules. From the look of them (they had 24 not 16 pins) each was a dual-colour matrix; the problem was not being able to find out anything about them: Google drew a blank on the part numbers, and I've had them for that long, I've no idea where to begin looking for the datasheet. So I started tracing out the pins.
Working out the pins for an 8x8 LED matrix isn't as difficult as some people think.
Firstly, each dot is a diode (that's what the D in LED - light-emitting-diode - stands for) so it doesn't matter if you connect the power supply the wrong way around through them. Armed with this knowledge, I connected a 5v supply to a breadboard, routed a ground wire through a 100 ohm resistor (don't want to go blowing any of the LEDs on the matrix!) and connected power and ground to two pins at random.
Ok, it wasn't really random, it was quite methodical - but the point is it didn't really matter which two pins I chose, I just kept trying pin combinations until something lit up.
Eventually, with power on pin 3 and ground on pin 1 of the lower row, a green LED lit up.
Perfect! So I drew a grid and recorded P3,G13 in the corresponding location. Keeping the power connected to pin3 and moving the ground connection resulted in each of the top row being lit up.
Occasionally a red LED would light up, in the same location as the green, but with the ground connection on the next pin along than the green light. So once I'd mapped out the grid for one colour, I could move the ground connection along one pin and get the same result for the other colour.
Now keeping the ground in a known place, and moving the power connection, I was able to map out which LEDs lit up with which combinations of power and ground on different pins.
There was no need to try every combination of pins - once I knew which ground pins caused which columns to light, and which power pins caused each row to light, the rest of the grid could be inferred from these results.
I couldn't be bothered drawing each and every LED on the paper, but you can see the results. To get the top left LED to light, put power on pin three and ground pin 1 (the green LED lights) or ground pin 2 (the red LED lights up). The numbers down the left represent which pins need power to activate which rows, and the numbers along the top tell us which pins need grounding on which column to get a particular single LED to light.
That's really all there is to it. It seems a bit hit-and-miss (it probably is) but within about 10 minutes, you can work out the pin-out for just about any 8x8 LED matrix.
I had some 8x8 LED matrix modules. From the look of them (they had 24 not 16 pins) each was a dual-colour matrix; the problem was not being able to find out anything about them: Google drew a blank on the part numbers, and I've had them for that long, I've no idea where to begin looking for the datasheet. So I started tracing out the pins.
Working out the pins for an 8x8 LED matrix isn't as difficult as some people think.
Firstly, each dot is a diode (that's what the D in LED - light-emitting-diode - stands for) so it doesn't matter if you connect the power supply the wrong way around through them. Armed with this knowledge, I connected a 5v supply to a breadboard, routed a ground wire through a 100 ohm resistor (don't want to go blowing any of the LEDs on the matrix!) and connected power and ground to two pins at random.
Ok, it wasn't really random, it was quite methodical - but the point is it didn't really matter which two pins I chose, I just kept trying pin combinations until something lit up.
Eventually, with power on pin 3 and ground on pin 1 of the lower row, a green LED lit up.
Perfect! So I drew a grid and recorded P3,G13 in the corresponding location. Keeping the power connected to pin3 and moving the ground connection resulted in each of the top row being lit up.
Occasionally a red LED would light up, in the same location as the green, but with the ground connection on the next pin along than the green light. So once I'd mapped out the grid for one colour, I could move the ground connection along one pin and get the same result for the other colour.
Now keeping the ground in a known place, and moving the power connection, I was able to map out which LEDs lit up with which combinations of power and ground on different pins.
There was no need to try every combination of pins - once I knew which ground pins caused which columns to light, and which power pins caused each row to light, the rest of the grid could be inferred from these results.
I couldn't be bothered drawing each and every LED on the paper, but you can see the results. To get the top left LED to light, put power on pin three and ground pin 1 (the green LED lights) or ground pin 2 (the red LED lights up). The numbers down the left represent which pins need power to activate which rows, and the numbers along the top tell us which pins need grounding on which column to get a particular single LED to light.
That's really all there is to it. It seems a bit hit-and-miss (it probably is) but within about 10 minutes, you can work out the pin-out for just about any 8x8 LED matrix.