20170226

Mastermind Game #3: Getting started with the code

ARDUINO: Allright, now that all is well planned out, it's time to flesh it out a bit by means of actual wiring up stuff, and write the code to run it. It'll all be done in steps adding one feature after the other in separate writeups so as to not get ahead of myself.

Today, the basic structure of the code and getting the buttons to work as intended. First off I believe the source code of this project to get rather big - in Arduino terms - so I've split it up into three files so as to be easier to navigate.

- mastermind.ino
The main file. Contains all the various definitions, setup and loop. Note here that I've structured it in such a way that loop() will never actually do just that. Inside it I got some initializations, and then an endless loop using a while(true){} loop to take care of business resetting values on new game and then get the game going. The game-loop itself is separated out into a separate function

- chores.ino
Contains various helper-functions to make it all work as intended. This is where most the logic work is done. Keeping up with and setting state, feed data to and from structs and arrays. You know, all the fun stuff.

- inOut.ino
The nuts and bolts level of the operation. Reading buttons, control the shift-register to change LED output and such. If there is something to be done with the actual hardware, this is where it'll be at.

Github repo for this stage.

Mind you, when using several files like this - it do not work quite as in other more 'professional' development environments. The extra files are not packages unto themselves that are fully enclosed bar the functionality and structures you make public for export. No, in the Arduino IDE it just means that at compile time, the IDE will collate all the files in the project, and treat them combined as one big file rather than several smaller.

So whilst you do not have to worry about transporting data around or import supporting files - you pay for it in lack of encapsulation and separate name-spaces.

In its' current state, it'll read the buttons, and allow navigation to change colours of the players guess and proceed to the next stage.

Breadboard wiring for this stage:



Using button left and right you traverse the LEDs. Hitting button select, you change color 0..5 by hitting button left and right. When happy with the choice, hitting button select will take you back to traversing the LEDs again. When traversing, one can also get to the 'next stage' option by being off the right 'edge' of LEDs.

Mind you, no LEDs are actually hooked up yet, so everything is 'emulated' by dumping the values of internal state to the Serial-monitor.

The next update will flesh out some more functionality. Probably the random assignment of colours to the game solution - and the routine to check the players guess up towards the generated solution, and display the result.

20170225

Mastermind Game #2: Failing to plan is planning to fail!

ARDUINO: Been having a bit of a rethink of the Mastermind game project. The rather prolonged inactivity on it have been unfortunate. Been busy in other areas, though I have mulled over this project to refine it before I get started proper.

First and foremost, I've ditched the idea of using a rotary encoder. I'll use three buttons instead. One for select, and then two for browsing. Not so much for coding considerations, but UX and saving some precious space in what I think will be a very cramped enclosure.

Secondly, my previous though of using three shift-registers to drive the LEDs was somewhat wasteful. I can get by with one as it happens. And four NPN transistors plus eight resistors.



As for the general layout of the project, I've landed on a 4x3 LED grid plus a single LED. Since two rows are made of RGB LEDs, electrically it is an 7x4 grid - and the lone LED making sure I use all 8 outputs from the shift-register. Finally the three button go on the bottom. Inside, it'll be a two-layer proto-board design. Lower layer for the ICs and glue hardware, upper layer for the LEDs. The buttons will be attached directly to the lid.

Basic 'display' as it were will be from top to bottom:

- A 4x row of Blue LEDs to count the tries. Binary FTW!
- A 4x row of RGB LEDs to signal result. Blue for a correct colour, Green for a correct color and placement, Red for neither.
- A 4x row of RGB LEDs for user selection of colour.
- A single Green LED to signal browse row or commit row mode.

How the UI will work:

- On the left there will be one button (1) to select and commit.
- On the right there will be two buttons (2 and 3) to browse.

Basic procedure:

00 - Power switch is turned on.
---
01 - Game starts, a little lights-show and then all LEDs turn off.
02 - User in edit mode, browse colours on a column - when happy commit colour with button 1. Current column will blink.
03 - User in edit mode, browse left-righ to select another column with button 1.
04 - Repeat from 2 until four colours are committed at which point user may:
05 - Browse off left or right column to get to mode select.
06 - If green LED is blinking, browse previous history by hitting button 2 (back) and 3 (forward) if available.
07 - If green LED is blinking and at current go to commit mode by hitting button 3.
08 - If green LED is blinking and at current go to edit mode by hitting button 1.
09 - If green LED is solid, commit turn by hitting button 3.
10 - If green LED is solid, go back to browse history mode by hitting button 1.
11 - Result is computed and displayed, if not solved, back to 2
12 - Result is computed and correct. A little lights-show, reset to 1 on hitting button 1
---
13 - Power switch is turned off.

To start off, it'll all have to be breadboarded up of course. And even-though the final product will run off a bare Atmega328, during the prototyping, programming and testing - I'll use an UNO. It's such a nice device for that purpose. Though it'll be quite the rats-nest of wires :)

Since I got no serious plans for the weekend, some actual hands on progress and write up of it all may even surface soon(tm)

20170220

Raspberry Pi 3 CPU Fan Control

PI / GOLANG: Finally got my Raspberry Pi 3 working the way I wanted. It's been on my list of todo-projects for a while. I got it about half a year ago or so - and it was my first foray into Linux. It did not go too well, so that install got to be a real mess.

Since then I've been using Ubuntu more or less daily on my laptops, so I got the urge the other week to try out Ubuntu MATE on the Pi. Got it up and running well enough - but it did not take to updates all that well. It froze dead twice during that process actually. So waited a bit until Ubuntu MATE 16.04.02 got released last week and tried that. This worked fine but for one major niggle - no matter what I did, my Norwegian keyboard layout would not stick between reboots.

So, back to Raspbian. And since last, it's been rebranded PIXEL. Fine. Gave it a go. Worked very well straight out of the box. Though, it would not recognize my WiFi card in the GUI. Some bash-magic fixed that, so got connected to my home network.

Plenty of updates, tweaks and twiddling about later, it is now working like a charm. It's a pretty decent little setup as it happens. Very pleased with it.



Even better, with a bit of investigation I found someone that had been so kind as to compile Visual Studio Code for the Pi. Tried doing this myself, but ran into all kinds of problems with out of date this, missing that and misconfigured other thing. So having it already compiled and available was quite the boon to my efforts.



Most other IDEs (on the Pi anyway) require all kinds of esoteric configurations and fiddling with settings to work flawlessly with my language of choice - Go. Not so with VS Code. Everything is in place after mere minutes, and by and large automagically. It's just wonderful.

With all things performing well and to my taste, I thought it a good idea to give it a proper spin. Do a little project to enhance my Pi. I got this enclosure for my Pi that included heatsinks and a CPU fan. Though I never used the fan after first testing it, as it makes for a rather noisy rattling annoyance when going full tilt. Which is all it would do, as it is a simple two-wire job with no speed control.

Though to protect from overheat having a fan available is always a good idea. The Pi will throttle down the CPU at I think 80'C. However running such temperatures may significantly reduce the lifespan of the CPU. I've even read about people measuring upwards of 100'C on a Pi 3. Obviously, that won't do.

A little fan-control circuitry and code was in order. The circuitry itself is simple enough. A S8050 NPN transistor, a 10 ohm resistor, a tiny bit of proto-typing board and some wires, headers and plugs.



Soldered it up and tested with +5V and +3.3V from a lab PSU - worked as intended.



Next I taped it up with some electrical-tape and crammed it into the Pi enclosure. It fit snuggly between the case and fan.



Hardware done, on with the software. I know plenty of others have done similar - if not identical - projects to this. Though from what I've seen, the software have been done in Python or even as a Bash-script.

That just rubs me the wrong way. Just the interpreter for JIT languages like Python gobbles up a ton of resources before you've even executed a single line of code. Then there is the compatibility issues, the distribution issues, the slowness of the execution. And so on and so forth.

Native binaries for the win! If resources are at a premium, nothing beats C/C++. Well, assembler do, but who got time for that?! Luckily, a Pi3 got reasonable amounts of resources, so Go is a very viable option for writing native apps in. It will be a bit bigger and hungrier than C/C++ due to the inner workings of the concurrency model and garbage collector. But it'll be nearly as fast and lean in execution - and also got all the other advantages of a static native binary.

Anyhow, the full code and binary can be found on my github;

rDybing/PiFanControl

Just download, and move the binary to a location of your choosing. Then to have it start automatically at boot, edit your /etc/rc.local file to include the pifc binary. Remember to put an ampersand at the end to make it run on a thread of its own. My edit look like this:

/etc/fancontrol/pifc &

Pin connections are easy enough;

+5VCC   (red wire)
GND     (black wire)
GPIO-18 (green wire)

Another little note - my application relies on the command '$ vcgencmd measure_temp' not needing sudo. This won't be a problem if running the default user - but if logged in as another user, it may. The solution is to add your user account to root Video-group for some reason. Yeah, don't ask why - you just have to. Here is the command to do that:

>$ sudo usermod -a -G video yourUserNameHere

Nothing too complicated in the code. Fairly straight forward. Anyone who's been fiddling around with Arduino for instance, should be comfortable with both structure and syntax of how to operate the GPIO pins on the Pi using Go.

The one thing worth noting in the code is how the temperature limits are implemented. In most others code I've seen (yes, those dreaded Python and Bash scripts), it's a simple threshold. Above it, turn on, below it turn off.

Which sounds nice and dandy in theory. In practice though, you can get some heavy trashing between the two states as the temperature may fluctuate right on the threshold. So I got a 'deadzone' implemented.


---

func setFan(s *state_t) {
  if s.fanOn {
    if s.tempC < s.limitOff {
      // turn off fan
      s.fanOn = false
      embd.DigitalWrite(fanPin, embd.Low)
    }
  } else {
    if s.tempC > s.limitOn {
      // turn on fan
      s.fanOn = true
      embd.DigitalWrite(fanPin, embd.High)
    }
  }
}


---

As you can see, I use a flag to check if fan is on or off, and then check the limits. The limit for turning on is set to above 65'C and turning off is set to below 63'C.

I check the temperature every other second. In between the app sleeps. At first I tried using a timer rather than sleep - but all that resulted in was one core running at 100%. So even-though I am not a fan of sleep commands in code, here was one of those few times where it was warranted.

It works very well. During testing, running sysbench pushing all four cores to 100%, it will intermittently hit 70'C - but usually hovers around 68-69'C. During normal use, the fan is off naturally as it won't even be close to the threshold to trigger it. But now I got the added safety of having a fan kick in should it be needed.

Now I just need think up another project for my Pi. Probably something server/backend related for an Arduino project I am contemplating :)

20170213

Collating a list in Go

GOLANG: So I am working on an admin tool for a database-backend. One of the reports wanted is to extract from a table number of messages in a given network. Which sounds easier than it is. The database entry for a message got quite the few fields, but the only one I am interested in, is the network ID which is stamped into each message entry. So there is a lot of network IDs that repeat. I got to count them and collate them for the report.

In this case, it is finding what networks is near or at the limit for free use, which is to say between 40 and 50 messages in the network. And to do this without hitting the backend database any more than strictly speaking necessary. With well over 100k individual messages in the database spread out over some 5k networks, the obvious solution is to just fetch and cache the entire table column of network IDs. Each ID being 64 bits, that is a transfer of roughly 800kb which is not too bad.

Then sort through it all. It took a bit of head-scratching thinking through the problem. And a pot of coffee.

Eventually I came up with this:

---

type collate_t struct {
  id       int64
  count    int
  // whatever else you need
}

func collateList(entry []collate_t) []collate_t {
   
  var collected collate_t
  var collated []collate_t

  for i := range entry {
    collected.id = entry[i].id
    if i > 0 && getExist(collated, collected.id) {
      collected.count = 0
    } else {
      if i < len(entry) {
        for j := i + 1; j < len(entry); j++ {
          if collected.id == entry[j].id {
            collected.count++
          }
        }

        collated = append(collated, collected) 
      }
    }
  }
  return collated
}

func getExist(c []collate_t, id int64) bool {
  for i := range c {
    if id == c[i].id
    return true
  }
  return false
}


---

That is *NOT* the first version - it is however the *WORKING* version 😁

Oh, and I did not include the cutoff function to trim the fat to only network IDs with between 40 and 50 messages in them - as that is rather simple.

The code is presented here a bit more general than what I've used in the actual application - as that is mired in a function with some postgres SQL queries and a few other bits and bobs. Anyhow, I think the solution is quite efficient - eventhough it do not use any of Gos' concurrency-goodieness.

The short of it is to iterate over the incoming entry slice - transfer the ID to a temp struct. Check if the incoming slice is iterated over at least once and if that ID have been counted already and is registered in the collated list. If not, run through the entire range of the incoming slice and count the number of hits on that ID. Finally then append to the collated list the new collected ID and count.

Pretty pleased with it, and just had to reward myself a Guiness for the effort -  and to calm my little tummy after all the coffee it took to reach that solution!

20170212

Mastermind Game #1: Considerations and Limitations

ARDUINO: Pondering doing a fun little project for a while now, but not quite found the correct one until it hit me: A version of the classic Mastermind board game.


Though it won't be a 1:1 copy. That would require an unholy amount of LEDs and just the though of soldering all those RGB leds and accompanying resistors make me dizzy. So no, got to simplify things a bit.

I guess I could cheat, and just use a color display - but then I might as well do it on the Pi in Go or AGK. Nope, I want this to be 'hands-on' as it were. So LEDs, buttons and I'm also thinking a rotary encoder...

But first - the rules. In the original you get six colors, ten tries and the 'coder' can tell if a color is correct or if a color and position is correct. But not what position and/or color. But since the 'cracker' got the entire history available, the process of elimination is simple enough.

In the version I'm making, The history will not be directly visible as such. I'm thinking of using a rotary encoder to browse back and forth in the history. The same encoder will be used to select what LED to change and to what color.

Speaking of colors. Your typical RGB LED got plenty to choose from - but for simplicity I'll keep it to what can be achieved using binary on/off. So no gradients. If not counting fully off (black) or fully on (white) that leaves six colors. Which is just perfect.

Color - R - - G - - B -
red 1 0 0
green 0 1 0
blue 0 0 1
yellow 1 1 0
magenta 1 0 1
cyan 0 1 1

As for the 'coder' LEDs, I'll just use four yellow ones to signal correct color, and four green ones to signal correct color and position.

In addition I'll also need something to signal how many tries have been attempted. If counting LEDs needed to be controlled now, I get 5 x 4 = 20. I can control that using three Shift Registers and have four channels left over. So unless I want to throw in another Shift Register, a 7seg LED display is not going to happen. But with the four bits left over from the three Shift Registers, I can count to 16 - which is plenty. So I'll add four blue LEDs and use that as a digital counter. Counting in digital is cool anyways, and blue LEDs are the coolest, so double win!

In the next installment I'll go through some of the initial hardware design. Ultimately, I'm going to want this in a nice little box with a 9V battery for power. So it's all going to run off a bare Atmega328P in the end with all the necessary discrete components to have it all humming along nicely. Which will be fun to bodge up on perf-boards with a ton of wires hither and dither to connect it all 😄

20170209

About this blog

Here I'll gather my little personal projects, various tutorials and help I give others in their projects. Most content will probably cover various topics related to programming in Go (aka Golang), fun and games with Arduino and also App Game Kit.

Other topics may crop up - but in general I'll contain myself to the more technical side of technology. Whilst I do have many opinions on many a topic, this is not a political or philosophical blog :)

I may be Norwegian, but will write in English. I live in Bergen, which means it is probably wet outside so I got nothing better to do than be inside and tinker with toys anyway.