Friday, 31 May 2019

Don't shoot the nuclear weapons

This weekend I was off to our anthology LARP event and I was going to spend the whole time as 'crew' where you're the 'baddies' or 'extras' needed to make the story happen.

The Saturday was a Legends of Tomorrow-esque setup with the players travelling through time to chase down a temporal conspiracy. So we had a Victorian military demonstration, 70s CND protest and 23rd Century spaceship launch in one story line.

Games like this often need props and I volunteered to make something. As part of the 70s section I ended up putting together a 'suitcase nuke', the sort of thing beloved of 90s action movies. The game organiser built a WWI tank and replica of the HG Wells time machine out of wood, carpet roll tube, random household junk and Correx sheet. I got the easy job.

This prop is a big pile of old-school Arduino stuff: a matrix keyboard, hand-wired LEDs for the 'plutonium core' and a 32x8 LED matrix driven by MAX7219 chips to show the countdown timer on. All housed in an equipment case a friend gave to me and accessorised with some 3D printing. It was a bit last minute and I made a deliberate effort to use up a bunch of stuff that was sitting in my storage boxes. The only thing I spent money on was a sheet of MDF and some spray paint.

It does the LED countdown thing and if you unscrew the display it conforms to the "help I'm being disarmed" trope of the counter speeding up, but you can quite easily switch it off.

It was quite a simple from a technical perspective but good fun in the game and there's plenty of scope for it to be re-used.

Thursday, 9 May 2019

Resurrecting the Tilda MKe - part 2

Some time back I got interested in unravelling the set of libraries/board definitions for the 2014 EMFCamp badge so I could use it with modern versions of the Arduino IDE and associated libraries.

Well I had another fiddle over the last couple of days and now have the display working which was the last big hurdle. This was really just poking through other peoples' work from 2014 and working out where to stuff the information in a different library to make it work.

The display controller is supported by the common U8g2 library as it's an ST7565, but there's very little info about the JHD12864-G13BSW screen itself. So I initially got a visible image but with unusably low contrast and viewing angle. Wading through the old library showed up the settings needed to set the bias voltage on the display and a quick read of the U8g2 FAQ showed me how to feed this to it without having to change anything in the library. So now here's a working demo of one of the example sketches that come with the library.



I really need to build a demo sketch that does all the functions but in the meantime here's something that will drive the screen if you've got one of these and want to play with it.

/*
  HelloWorld.ino
  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
  Copyright (c) 2016, olikraus@gmail.com
  All rights reserved.
  Redistribution and use in source and binary forms, with or without modification,
  are permitted provided that the following conditions are met:
  * Redistributions of source code must retain the above copyright notice, this list
    of conditions and the following disclaimer.
 
  * Redistributions in binary form must reproduce the above copyright notice, this
    list of conditions and the following disclaimer in the documentation and/or other
    materials provided with the distribution.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

/*
  U8glib Example Overview:
    Frame Buffer Examples: clearBuffer/sendBuffer. Fast, but may not work with all Arduino boards because of RAM consumption
    Page Buffer Examples: firstPage/nextPage. Less RAM usage, should work with all Arduino boards.
    U8x8 Text Only Example: No RAM usage, direct communication with display controller. No graphics, 8x8 Text only.
 
  This is a page buffer example. 
*/
// Please UNCOMMENT one of the contructor lines below
// U8g2 Contructor List (Picture Loop Page Buffer)
// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp
// Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected
#define BOARD_SPI_SS2   (52u)
#define LCD_CS          BOARD_SPI_SS2
#define LCD_POWER       (40u)
#define LCD_BACKLIGHT   (35u)
#define LCD_BACKLIGHT_ON  HIGH
#define LCD_BACKLIGHT_OFF LOW
#define LCD_A0            (38u)
#define LCD_RESET         (34u)
#define CMD_SET_BIAS_9 0xA2
#define CMD_SET_BIAS_7 0xA3

//Screen is JHD12864-G13BSW and ST7565 controller
U8G2_ST7565_ERC12864_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ LCD_CS, /* dc=*/ LCD_A0, /* reset=*/ LCD_RESET); // - Works well!

void setup(void)
{
  //Turn on the display
  pinMode(LCD_POWER,OUTPUT);
  digitalWrite(LCD_POWER,LOW);
  //Turn on backlight
  pinMode(LCD_BACKLIGHT,OUTPUT);
  digitalWrite(LCD_BACKLIGHT,LCD_BACKLIGHT_ON);
  //Start display
  u8g2.begin();
  //Set the bias so it's legible
  u8x8_cad_StartTransfer(u8g2.getU8x8());
  u8x8_cad_SendCmd(u8g2.getU8x8(), CMD_SET_BIAS_9);
  u8x8_cad_EndTransfer(u8g2.getU8x8());
  //Set some contrast now the bias is OK
  u8g2.setContrast(32);
}
void loop(void) {
  u8g2.firstPage();
  do {
  u8g2.setContrast(32);
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(2,14,"Hello World!");
    u8g2.drawFrame(0,0,128,64);
  } while ( u8g2.nextPage() );
}