Monday, 21 December 2020

MS Orleans - .NET and the (virtual) actor model

Just a short note to share something I've been experimenting with this year - MS Orleans. I remember experimenting with Earlang some years ago and recently I started thinking about the actor model implementation for .NET. I found a number of libraries/frameworks out of which I relatively extensively tried Akka.NET and Orleans. To me, Orleans feels like a good opportunity to dive into the actor model with .NET with a relatively straightforward codebase.

I've been writing various PoC's this year but I think the special mention goes to the last one: the road to orleans (https://github.com/PiotrJustyna/road-to-orleans) which I wrote with two other engineers. Down to earth, realistic examples, .NET 5 and F# support out of the box and we're constantly expanding it.

Feel free to comment and contribute!

Friday, 15 February 2019

Pivotal Cloud Foundry - "access denied" for custom buildpacks written on Windows

Writing custom buildpacks on Windows can lead to some unnecessary frustrations. Today I would like to cover one of those frustrations: buildpack scripts not being executable on PCF. Creating buildpack scripts on windows can lead to cryptic errors during buildpack execution like "access denied" or "permission denied".

The problem is caused by the fact that any new file created on Windows is automatically set to mode 644 aka rw-r--r-- (linux standards), but at the same type is automatically executable (-rwxr-xr-x) by windows standards.

Result? Listing your buildpack scripts using git bash on windows you see:

drwxr-xr-x 1 Piotr_Justyna 1049089    0 Feb 13 20:46 ./
drwxr-xr-x 1 Piotr_Justyna 1049089    0 Feb 13 20:44 ../
-rwxr-xr-x 1 Piotr_Justyna 1049089  137 Feb 13 20:44 detect*
-rwxr-xr-x 1 Piotr_Justyna 1049089   40 Feb 13 20:46 finalize*
-rwxr-xr-x 1 Piotr_Justyna 1049089  102 Feb 13 20:44 release*
-rwxr-xr-x 1 Piotr_Justyna 1049089  135 Feb 13 20:46 supply*

While in fact all of them are by default mode 644 (rw-r--r--). Trying to execute those scripts on PCF will result in "access denied" errors. It is pretty annoying, so I prepared a little cheat sheet for those of you who work with custom buildpacks, windows and git bash:

Executable files:

  • DON'T:
    chmod +x file
    
  • DO:
    git update-index --chmod=+x file
    

List files with their access modes:

  • DON'T:
    ls -la
    
  • DO:
    git ls-files -s
    

Copying files:

  • DON'T:
    cp file file_copy (that defaults the access mode of the copy to 644 even if the file is e.g. 755)
    
  • DO:
    cp file file_copy *and then* git update-index --chmod=+x file_copy
    

chmod-calculator.com is a very handy tool, especially for those who don't work with linux too often.

Sunday, 14 October 2018

Linux: permanently update your PATH.

To permanent change your PATH:

  1. Locate your profile file. This is your user-specific initialization file for your shell and you can find it in the root of your home directory (~). It can be named slightly differently depending on your distribution and the type of shell you are using (.bash_profile, .zprofile, etc.), but it's really not easy to miss. In my case (Fedora & bash), my profile file is named .bash_profile.
  2. Make desired changes to your PATH. There's a good chance the file already has some PATH changes, so just append yours.

    # .bash_profile
    
    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then
     . ~/.bashrc
    fi
    
    # User specific environment and startup programs
    
    PATH=$PATH:$HOME/.local/bin:$HOME/bin
    PATH=$PATH:~/Documents/rebar3
    
    export PATH
    

  3. Now for the changes to take effect you can either simply log out and log back in or run:

    source ~/.bash_profile
    

    That will basically execute the command defined in ~/.bash_profile using your current shell.
And that's it.

Thank you and happy hacking!

Piotr

Friday, 13 April 2018

Haskell & Yesod - sample REST API.

Here's a sample Haskell & Yesod application demonstrating a basic REST API. It could serve as a starting point of a toy project: Haskell & Yesod - REST API.

I wrote this application as a supplement to the "RESTful Content" chapter of the "Haskell and Yesod" book. I felt the examples given in that chapter, while good, could be further developed into a working application (with IO, custom types, etc.).

Your feedback is welcome and please expect some changes to that application as time goes on.

Happy hacking,
Piotr

Saturday, 30 September 2017

Docker image to build and run your Haskell Warp server code (built on Windows).

At the time of writing this, the most helpful resources I could find covering this were simply:

  1. Stack's official dockerfile.
  2. This great gist.

I played a bit with the two and came up with my own version, suitable to produce images able to build and host simple Haskell server code. This is no production setup, but will open the door to more fine-tuned experimentation.

Let's jump right into it!

  1. First of all, here is the source code of a minimal Haskell Warp server I'm going to be hosting: haskell-warp.
  2. Secondly, the dockerfile (also contained in the github repository from the previous point):

    FROM ubuntu:16.04
    
    MAINTAINER piotr - dot - justyna - at - gmail.com
    
    # Install dependencies.
    RUN apt-get update && \
        apt-get install --assume-yes curl gcc libgmp-dev make xz-utils zlib1g-dev
    
    # Install Stack.
    RUN curl --location https://www.stackage.org/stack/linux-x86_64-static > stack.tar.gz && \
      tar xf stack.tar.gz && \
      cp stack-*-linux-x86_64-static/stack /usr/local/bin/stack && \
      rm -f -r stack.tar.gz stack-*-linux-x86_64-static/stack && \
      stack --version
    
    # Install GHC.
    WORKDIR /haskell-warp
    COPY haskell-warp/stack.yaml /haskell-warp
    RUN stack setup && stack exec -- ghc --version
    
    # Build.
    COPY /haskell-warp /haskell-warp
    RUN stack build --copy-bins --local-bin-path /usr/local/bin
    
    # Run project.
    ENV HOST 0.0.0.0
    ENV PORT 3000
    EXPOSE 3000
    CMD /usr/local/bin/haskell-warp-exe
    
  3. Now it's time to build my image (this will take a good while):

    $ docker build -t haskell-ubuntu:16.04 .
    
  4. Next, time to create a running container from the image:

    docker run --name haskell-warp -d -p 80:3000 haskell-ubuntu:16.04
    
  5. Finally, time to test the code we've just deployed:
And that's it! We've just built ourselves a working image able to host a Haskell Warp server.

Keep hacking!
Piotr

Thursday, 14 September 2017

Configure ECS to use a docker image and host static files globally.

As a continuation of Hosting static HTML files locally with Docker, today I'm focusing on running that image in ECS.

This part wasn't complicated at all and really you can just follow ECS's tutorial to see your containerized application up and running in the cloud. Minimal hassle. I don't think that there's a point in rewriting the ECS tutorial, so I'll just do two things:

The next part should be quite exciting and it is to prepare an image to run a Haskell-powered page locally. Sounds like fun.

Stay tuned and happy hacking!
Piotr

Friday, 8 September 2017

Hosting static HTML files locally with Docker

In my last post I outlined my plan for Haskell, Docker & AWS development workflow. Here's the first part of my plan:

Prepare a basic Docker image to host static HTML files locally.

I'm going to cover two methods here:
  1. Use a vanilla HTML server image and map the resources to be hosted.
    This way you can make changes to the hosted HTML files and see them reflected in the browser without the need of restarting or creating a new container.
  2. Use a vanilla HTML server image to build your own image on top of it.
    This way you can generate dockerfiles which, when built, will include the hosted resources in the docker images they produce.
Let's take a closer look at the two methods.



Prearation

If you're completely new to do Docker, I highly recommend watching this video. 40 minutes well spent and in that time you will have the contents of this post explained in detail. I will be using Docker version 17.06.1-ce and Windows.

When you're ready, there's some preparation to be done for both methods: we're going to need a web server able to host static HTML files. One of the most popular choices is nginx and at the time of writing this, the latest stable version is 1.12.1. In this post I'm going to use the 1.12.1-alpine simply because the image itself is small.

Let's pull that image:

docker pull nginx:1.12.1-alpine


Method 1

Command:

docker run --name tiny-nginx -d -v c:\temp\:/usr/share/nginx/html:ro -p 80:80 nginx:1.12.1-alpine

Explanation:
Run a docker container named (--name) "tiny-nginx" as a daemon (-d), bind mount a volume (-v) containing the resource you'd like to host in the following way: "container-host-HTML-folder-path:container-HTML-folder-path" (see how my windows container host path - "c:\temp"*, neatly mixes with the linux container path - "/usr/share/nginx/html"?**), in a read-only manner (:ro), exposing container's port 80 to my container host port 80 (so that I can actually access the HTML page from my local machine) using image "nginx" tagged as "1.12.1-alpine".

*It is important to note that we are mounting folders and not individual files. **This folder was given in the nginx image documentation.

Windows is going to ask for your permission to share the selected folder:



And now you're set. Your shared and mounted folder is now being hosted by the tiny-nginx container and every time you make changes to the HTML file locally, they should be reflected in the browser every time you refresh the hosted page. This method is pretty neat and allows for rapid write & verify iterations.

Method 2

In this method we're also going to create a docker container based on an image, but this time the image we're going to use is going to be built by ourselves on top of an existing one: nginx:1.12.1-alpine.

To do that, we first need a dockerfile. This is going to serve as a definition of our image.

Code (file: dockerfile):

FROM nginx:1.12.1-alpine
MAINTAINER piotr - dot - justyna - at - gmail.com
COPY html /usr/share/nginx/html

Explanation:
Based on image nginx, tagged 1.12.1-alpine (FROM), create a new image with a given maintainer and while creating the image, copy the contents of the container host's "html" folder* to container's "/usr/share/nginx/html"** folder (COPY).

*It is important to note that we are mounting folders and not individual files and that the folder referenced as in the example, must be available in the current, working directory.
**This folder was given in the nginx image documentation.

This basic dockerfile can now be converted (built) into an actual new image.

Command:

docker build -t static-content-nginx:1.12.1-alpine .

Explanation:
Build and optionally tag (-t) and image (name:tag -> static-content-nginx:1.12.1-alpine) using a dockerfile found in the current folder (.).

Now the image should get added to the list of docker's images. We can now run it as if it was any other image pulled from the Internet (see the Preparation section).

Command:

docker run --name tiny-nginx -d -p 80:80 static-content-nginx:1.12.1-alpine

Note the similarities between this command and the one I used in Method 1. The only difference is that we're not mounting a shared folder. Simply because it has already been added to the image itself during the build phase.



Both methods should result in the file being hosted in the locally running containers. For now, there should be only one container hosting the HTML file at any given time. Results:


That's it for now and you can find the dockerfile together with some sample HTML to be hosted here. In the next part I'm going to cover how to use the image we created in Method 2 in ECS (and not Method 1 as sharing and mounting local resources would be quite tricky!) and publish my sophisticated HTML code globally.

Stay tuned and keep hacking! Piotr

Friday, 1 September 2017

Haskell, Stack, Docker, AWS and a notepad of your choice

I've been playing with Haskell on and off for the last few years and at this stage, while I still consider myself a newbie, I feel quite confident I could write a small application (*something*) and have it do relatively simple tasks for me. It's great to have your application published and running somewhere in the cloud, but the whole process of getting your code to the cloud is much less so. At least it has been in my case. What I like to do is more programming and less configuration and manual tasks!

Check now inactive fontbot for example. The way it is written is pretty basic and its iterations are as basic as one can wish for:

* write code
* build it with Stack
* copy the compiled code manually to a prepared EC2 machine

Basic.

But, as I'm here to hack fridges, I want more. I want the cycle to be more automatic and less manual. I want to be able to publish my built code anytime I'm happy with the build. Preferably to a Docker container hosted by AWS (not necessarily a single EC2 machine). My daily work does not require any interaction with Docker (so your feedback is much appreciated!), but since it looks like a very useful thing, I plan to explore it. I'm pretty new to Docker and the idea of ECS, so it should be good fun.

Let's sketch a plan of this exercise (now partially updated with the parts I've already finished):

At the end of this exercise I should have a setup where every time I push my code to a chosen branch, it gets deployed to ECS by the pipeline.

Stay tuned and keep hacking!
Piotr

Sunday, 27 September 2015

Hackage - releasing packages

You are ready to share your first Haskell package with the whole world. How to do it? It is not difficult at all and should take you no longer than 15 minutes. I took some notes whilte releasing my package: roller to help fellow Haskellers share their work with the community. Let’s dive right into it.

To begin with, run the following command in your package directory:

cabal sdist

This will try to prepare a hackage-acceptable package of your code. Depending on your package, first time you run it, cabal will complain a lot producing the something like this result:

Warning: Cannot run preprocessors. Run 'configure' command first.
Building source dist for roller-0.1.4...
Source tarball created: dist\roller-0.1.4.tar.gz

Cabal configure needed, let’s run it:

cabal configure

This will produce following results:

Warning: The package list for 'hackage.haskell.org' is 44.3 days old.
Run 'cabal update' to get the latest list of available packages.
Resolving dependencies...
Configuring roller-0.1.4...
cabal: At least the following dependencies are missing:
optparse-applicative >=0.11.0,
random >=1.0.1,
regex-applicative >=0.3

Cabal complains about dependencies being not up to date, let’s update cabal first:

cabal update

(this will take a while)

An now, let’s update those problematic packages beginning with:

cabal sandbox init

and followed by:

cabal install optparse-applicative
cabal install random
cabal install regex-applicative

Now, cabal configure should not complain anymore, let’s find out:

cabal configure

This should produce:

Resolving dependencies...
Configuring roller-0.1.4...

Looks well! We are now ready to prepare the package:

cabal sdist

Now cabal should produce this output:

Building source dist for roller-0.1.4...
Preprocessing library roller-0.1.4...
Preprocessing executable 'roller' for roller-0.1.4...
Source tarball created: dist\roller-0.1.4.tar.gz

At this stage your package is ready and can be uploaded to hackage, so please use this link when you're ready for that final step.

Good luck with your packages and happy hacking!

Saturday, 8 August 2015

Haskell - updating GHC and leaving the Haskell platform

This was my first GHC update and since it made me spend a couple of minutes scratching my head and deciding on how to approach this, let me share my experience in the form of a Q&A for the sake of brevity.

Q: When to update my GHC?
A: Whenever you think you need a newer version. A good example would be: new hackage packages stop working (give installation errors) and require new versions of core packages like base.

Q: I am using Haskell Platform, how do I update GHC?
A: Simply download the latest GHC and make sure your PATH points at the updated version (and not at Haskell Platform). Fear not. Stepping away from, otherwise very useful, Haskel Platform will give you much more freedom and control over the packages you're using.

Q: I have the latest version of GHC installed. How do I update my PATH?
A: If you've been using the Haskell Platform until now, your PATH should point at two things located in the Haskell Platform:
  • GHC
    C:\Program Files (x86)\Haskell Platform\2013.2.0.0\bin
  • mingw
    C:\Program Files (x86)\Haskell Platform\2013.2.0.0\mingw\bin
To leave the Haskell Platform's GHC and start using the new one, simply update the PATH accordingly (depending on where you installed the latest GHC):
  • GHC
    C:\Users\Piotr\Documents\Haskell\ghc-7.10.2\bin
  • mingw
    C:\Users\Piotr\Documents\Haskell\ghc-7.10.2\mingw\bin

This should get you access to the latest Haskell packages. Please share if your experience was different or if you follow a simpler process.

Happy hacking!

Friday, 31 July 2015

Haskell - playing with Hackage

OK, so you have just finished reading your first Haskell book, you understand most of (if not all!) compilation errors GHC throws at you and you start thinking creatively about the language. If you are at this stage and wondering what's next, welcome to my team! Not so long ago I finished Learn you a Haskell and, while reading The Haskell Road to Logic, Maths and Programming, I decided I was ready to start playing with Hackage. My package of choice was Rasterific - mostly because I wanted to get something on the screen quickly.

In this update I'm going to walk you through installing a package of your choice (+ all its dependencies) in your local cabal sandbox and using it in your own Haskell program. Let's get started!

First of all, let's make sure you have the latest versions of

  • Cabal
  • cabal-install
installed. To do that, simply run the following command from your command line:
cabal install Cabal cabal-install
This will install the latest versions of both packages.

Once it's done, let's update cabal packages using the following command:

cabal update

Now, a special note for the Haskell Platform users: the cabal you are using from the command line might not (and it wasn't in my case) be the one being updated! In my case, the cabal my PATH variable was pointing at was located in the Haskell Platform folder

...\Haskell Platform\2013.2.0.0\lib\Cabal-1.16.0
but executing those commands made the cabal install its latest version in
C:\Users\Piotr\AppData\Roaming\cabal\bin (version 1.22.6.0)
I had to come up with a solution and I ended up changing my PATH variable to use the cabal installed in my AppData.

Once you have the PATH variable pointing at the updated cabal, navigate to the folder you want to place your experimental project in (still using the command line) and type:

cabal sandbox init
This will create a folder-local sandbox environment for packages that could have otherwise damaged your global cabal repository. In case anything goes wrong in the sandbox, you can always delete it and start fresh - no need to modify your global set of packages.

Once you have the local sandbox prepared, you are ready to install your package of choice and its dependencies. Just in case, make the first run dry (just list the required dependencies):

cabal install Rasterific --dry-run
You should see something like this:
Resolving dependencies...
In order, the following would be installed:
base-orphans-0.4.0 (new package)
bytestring-0.10.6.0 (new version)
Win32-2.3.0.2 (new version)
binary-0.7.5.0 (new version)
text-1.2.1.1 -integer-simple (new version)
hashable-1.2.3.3 (new version)
nats-1 (reinstall) changes: hashable-1.1.2.5 -> 1.2.3.3
time-1.5.0.1 (new version)
directory-1.2.3.0 (new version)
FontyFruity-0.5.1.1 (new package)
mwc-random-0.13.3.2 (new package)
unordered-containers-0.2.5.1 (new version)
semigroups-0.16.2.2 (reinstall) changes: bytestring-0.10.0.2 -> 0.10.6.0,
hashable-1.1.2.5 -> 1.2.3.3, text-0.11.3.1 -> 1.2.1.1,
unordered-containers-0.2.3.0 -> 0.2.5.1
bifunctors-5 (new version)
vector-algorithms-0.7 (new package)
void-0.7 (reinstall) changes: hashable-1.1.2.5 -> 1.2.3.3
contravariant-1.3.1.1 (new version)
comonad-4.2.7.2 (new version)
profunctors-5.1.1 (new version)
semigroupoids-5.0.0.2 (new version)
free-4.12.1 (new version)
zlib-0.6.1.1 (new version)
JuicyPixels-3.2.5.3 (new version)
Rasterific-0.6.1 (new package)
Warning: The following packages are likely to be broken by the reinstalls:
linear-1.18.0.1
force-layout-0.4.0.0
diagrams-contrib-1.3.0
diagrams-1.3
diagrams-lib-1.3
diagrams-svg-1.3
diagrams-core-1.3
active-0.2.0.1
lens-4.9.1
contravariant-1.3.1
semigroupoids-4.3
profunctors-4.4.1
free-4.11
kan-extensions-4.2.1
adjunctions-4.2
monoid-extras-0.4.0.0
dual-tree-0.2.0.6
bifunctors-4.2.1
comonad-4.2.5
bytes-0.15
Use --force-reinstalls if you want to install anyway.

Once you're happy with required dependencies, simply run:

cabal install Rasterific

If everything goes well, you are ready to start playing with the package! You can find Rasterific documentation here. I used it to write a small program drawing rectangles into a file:

import Codec.Picture(PixelRGBA8( .. ), writePng)
import Graphics.Rasterific
import Graphics.Rasterific.Texture

main :: IO ()
main = do
    let backgroundColour = PixelRGBA8 234 247 217 255 -- Cilantro Creme
        foregroundColour1 = PixelRGBA8 195 214 170 255 -- Mint Sherbert
        foregroundColour2 = PixelRGBA8 142 168 108 255 -- Pesto Paste
        foregroundColour3 = PixelRGBA8 77 100 45 255 -- Simple Green
        foregroundColour4 = PixelRGBA8 40 58 16 255 -- Dark Water
        image = renderDrawing 400 400 backgroundColour $ do
            withTexture (uniformTexture foregroundColour1) . fill $ rectangle (V2 50 50) 145 145
            withTexture (uniformTexture foregroundColour2) . fill $ rectangle (V2 205 50) 145 145
            withTexture (uniformTexture foregroundColour3) . fill $ rectangle (V2 50 205) 145 145
            withTexture (uniformTexture foregroundColour4) . fill $ rectangle (V2 205 205) 145 145
    writePng "test.png" image

-- palette taken from: http://www.colourlovers.com/palette/110443/Summer_Grass
You can also find the code here. To build it, execute the following command (and this is where a local sandbox comes very handy):
ghc -package-db=.cabal-sandbox\i386-windows-ghc-7.6.3-packages.conf.d main.hs
Once the program compiles, you can run it and start drawing. Here is my result:

And that's it! You have just installed your first package and used it in your own program. Please leave a comment if the installation process was different for you or if you experienced some other problems.

Let the adventure with Hackage begin!

Saturday, 25 July 2015

Haskell - the power of type declarations

Haskell - a very interesting functional language, which continuously helps me become a better programmer and a more efficient thinker. One small example (exercise 1.24) I found in the book I'm currently reading (The Haskell Road to Logic, Maths and Programming) made me think: "wow, this is just great". This "wow" moment is something I would like to share with you today. I am going to show you that it's the type declaration and not the actual body of the function that you should consider your best friend while reasoning about the function's job. Haskell, as a strongly and statically typed language lets you do that. If you think it's crazy, please read on!

Let's look at a small program:

add2 :: Integer -> Integer
add2 x = (2 + x)

main = print $ add2 1 -- prints "3"
If you're a Haskell virgin, I hope you can still follow what's happening (if not, take a look at some other examples from e.g. Wikipedia to get a feel of the language). The add2's type declaration (first line) states:

I transform Integers into Integers.

Pretty simple. However, you might come across a slightly different interpretation:

I take one parameter of type Integer and return an Integer.

Which also works in our simple example. You might now ask: "ok, so now how do we write type declarations for functions which take more than one parameter?".
add x y = x + y
I remember asking this question myself and experimenting with constructs like:
add :: Integer Integer -> Integer
add x y = x + y
or
add :: Integer, Integer -> Integer
add x y = x + y
but none of them worked. At the time I just accepted that the compiler is smart enough to determine that the last "->" denotes the returned type and every other "->" simply chains parameters together. Weeks have passed and I started reading about lambdas, currying, partial application. I never looked back at those failed experiments from the beginning of my journey. Until now.

Let's return to our first function - add2. Exercise 1.24 (or its variant, adapted to fit my add2 example) makes you remove the parameter "x" and see what happens. Haskell allows for (and eagerly supports!) partial application of functions, so in our example, the additon is just partially applied (we only have one out of two parameters: 2). Not a big thing. Let's remove the "x" and look at the code now:

add2 :: Integer -> Integer
add2 = (2 +)

main = print $ add2 1 -- prints "3"
This is when I started connecting the dots. I expected the code to work, but I never thought of this:
  1. If my function (partially applying addition) works without the parameter, it really is nothing more than just an alias for that partial application of addition. This was a very powerful thought as it was always natural to me to associate the assignment operation with some sort of an order for the computer to "run the code on the right to give value to the code on the left". I started asking more questions:
    • If we don't need the "x" now, have we ever really needed it?
    • Is this going to change the way I think about code (not only the functional code)?
    • If so, how will all my programs look from now on?
    I am in the process of looking for answers to these questions and I find it very fresh and exciting.
  2. Let's look at the type declaration again - it hasn't changed! This made me think that my perception of type declarations was not very accurate. I realised that it serves as the promise of what the function is expected to achieve. The body obviously does the heavy lifting and fleshes the type declaration out, but it's the type declaration that helps understand the big picture. In the end, it does not really matter if your function takes one parameter and returns its processesed value or takes zero parameters and returns (or acts as!) a function that does it. What matters is the transformation defined in the type declaration. Implementation is just a set of various operations that should follow the principles outlined in the type declaration.

Learning Haskell (and functional programming in general) is a great experience which I can highly recommend to every software engineer. I plan to continue reading and understanding Haskell as it's a great source of inspiration and ideas. I've been writing some sandbox Haskell code in my free time, which you can find here and contribute if you please.

I hope this makes sense to you and if not (or if so!), please feel free to leave a comment in the section below.

Monday, 13 July 2015

Teensy 3.1 programmer for ATtiny85 chips - going permanent, part 3

This is a continuation of my previous post Teensy 3.1 programmer for ATtiny85 chips - going permanent, part 2 and the last part of the tutorial. After a couple of months of a break, this time, I'm going to connect indicator LEDs and the socket. The board does not look as clean and neat as initially thought it would, but it's my first one afterall.

I took my time finishing the board as after wiring everything up and soldering it together, I introduced a hardware bug and couldn't figure out where it was. After a couple of days of scratching my head I put my unfinished board on the shelf and decided I would get back to it at some stage. I looked at it almost every day for a couple of months saying to myself: "I will fix you some day" and finally, last weekend I decided that this just has to end. I took my trusty yellow multimeter and started debugging.

Finding hardware problems is not as easy as debugging a high level program. There's no IDE, no debugger, no stack trace. There is just your board and your multimeter. And a short circuit somewhere. Debugging a physical circuit is not as easy as "stepping into" your code or whatever term you use (if you've ever debugger a program, that is!). It is a tedious set of checks, one wire after another. One after another, and again and again... Even if you find a bug (minimal or infinitely large resistance), it is not immediately obvious what causes it. It wasn't any different in my case.

I found two short circuits and I had no idea what could have caused them. I almost gave up a couple of times, but after hours and hours of probing, I finally found my mistake. And when I finally did, I was far from happy with what caused it! As it turns out, when you drill a hole in the copper strip to break the connection, you have to be very careful not to leave any residue copper touching the neighbouring strips. Zero, null. If you do (and you might not even see it!), you, my friend, are up for a treat - hours of tedious tests and misery.

Thankfully all ended well and I finally fixed the board. Let me show you the process step by step.

  1. Indicator LEDs connected and working (I decided to stir thing up a bit and assign the red LED to WRITE signal):
  2. Socket connected:
  3. RESET and GND lines connected:
  4. Remaining lines connected:
  5. And finally, the board gets cut:

This is the final part of the tutorial.

A piece of advice for keen fans of electronics: think twice before you buy a stripboard like mine. If you're a beginner, just like me, it will most definitely cost you hours of head-scratching if you make a tiniest mistake. And after it's finished, it will not look pretty.

However, finding a bug and fixing it does give some sort of feeling of accomplishment, so it wasn't all that bad :)

Thanks for reading and happy hardware hacking!

Saturday, 14 March 2015

Teensy 3.1 programmer for ATtiny85 chips - going permanent, part 2

This is a continuation of my previous post Teensy 3.1 programmer for ATtiny85 chips - going permanent, part 1. This time, I'm going to list all components needed to make a permanent Teensy 3.1 programmer for ATtiny85 chips.

I have all components ready, here's what I'm going to use:
  1. Shrouded box header (2x3):
  2. 8 Pin DIL IC Socket:
  3. 2 x 14 pin header socket:
  4. 6-Conductor Ribbon Cable with IDC Connectors 6:
  5. and obviously, a stripboard:
Now, since I have all components, let's prepare a compact prototype on a breadboard. If you remember from my previous post, I wanted to change the default Arduino ISP layout slightly to make my board look better.

Update:

After an hour or so of experimentation, I realised that changing that pin 13 to 9 would be more complicated than I initially thought, so I decided to leave the ISP code as it is now and move on to soldering. Expect an update soon!

Sunday, 1 March 2015

Teensy 3.1 programmer for ATtiny85 chips - going permanent, part 1

Breadboard prototypes are handy. You can assemble them quickly, check if your concept works and your work is done - the tool you wanted to build can be used immediately (see my Teensy 3.1 programmer design here). However, after a while, those flimsy cables and fragile design make you want to build something more permanent. I don't mean anything like a printed, fancy board, but just a simple, soldered solution on a stripboard. As I have one of those stripboards somewhere in my "electronics" drawer (thankfully, it's still only one drawer), I decided that it's the highest time to try to make my ATtiny85 programmer more robust and move from plastic to copper.

Stripboard.jpg
"Stripboard" by Alexander Jones - Own work. Licensed under Public Domain via Wikimedia Commons.

Before I start soldering, let me gather all requirements in one place so the design is as polished as possible.
  1. Ideally, only one side of Teensy's pins should be used - right now, most of the programmer's pins are located on just one side of the Teensy board. There are two pins on the other side, though:
    • 3.3V
    • PIN 13
    While I don't think I can relocate the 3.3V pin, PIN 13 should be easy to replace by one from the the other side of the Teensy board. This should keep the design compact and understandable but will require some changes to the Arduino ISP code.
  2. Microcontroller socket should be a part of the programmer board - in case the device doesn't have the programmer interface (programming is done by removing the chip), it should be possible to connect programmed chips directly on top of the programmer board.
  3. The board should have the ATtiny85 programming interface - 6 pins will be enough.
  4. The board should be as compact as possible - that goes without saying.
I think that's a complete list of my requirements. Now, let me prepare all required components. Please expect an update soon!

Friday, 26 September 2014

How to make an ATtiny85-powered programmable intervalometer for Canon DSLR?

Remember that intervalometer I mentioned some time ago? Well, I made one for myself and since it's been working great for the last couple of weeks, I decided to share how I made it. If you'd like to build one yourself and shoot photos like this one:

or videos like this one (I strongly recommend downloading it as vimeo dramatically reduced its quality and frame rate - 60FPS was cut down to 30FPS):

01092014 Full HD 60FPS from Let Zweindaut on Vimeo.


, you will need:
  1. Perf board/stripboard:
  2. 8 Pin DIL IC Socket for the ATtiny85:
  3. 3.5mm stereo audio jack:
  4. NPN Transistor:
  5. 1MΩ resistor:
  6. Power source (in my case - a double AAA battery pack):
  7. Some sort of internally isolated enlosure (completely optional):


After you have all components prepared, you can start soldering, following the schematic:




I did it in following order, but it's completely up to you:
  1. I decided to start with the DIL socket:

  2. Next up, audio jack. Before you start soldering, let's take a closer look at this part:

    I am using only the shutter pin, but you can get creative and use the focus pin as well if you plan to focus automatically. The idea behind the build will remain similar.


  3. Followed by a transistor:

    Notice how transistor's collector is connected to the shutter pin, emitter to the ground pin (through a bridge) and base is not connected to anything yet. If you're having trouble telling which pin is the collector and which is the emmiter, take a look at this website.
  4. Resistor. This part connects transistor's base to ATtiny85's operational pin (in my case 0).

  5. Power source:

  6. And a ground reference (very sloppy, I know...):
  7. And it's finished!

Now, let's program it!

The program I'm using is just a slightly modified version of Arduino's sample Blink program. I added the initial delay, which will give you those few extra seconds before the shutter closes for the first time (I usually use that time to switch the camera's display off). My code looks like this:

int operationalPin = 0; // microcontroller's pin to be used
int initialDelay = 10000; // defines when the first photo should be taken, expressed in milliseconds
int shutterCloseTime = 100; // defines for how long the shutter should be closed, expressed in milliseconds
int gapBetweenShots = 3000; // defines the gap between every photo, expressed in milliseconds

void setup()
{
pinMode(operationalPin, OUTPUT);
delay(initialDelay); // initial delay
}

void loop()
{
digitalWrite(operationalPin, HIGH); // shutter closes
delay(shutterCloseTime); // keeping the shutter closed
digitalWrite(operationalPin, LOW); // shutter opens
delay(gapBetweenShots); // keeping the sutter open
}


The process of programming the ATtiny85 (actually getting the compiled code on the chip) is not covered here, but if you have an Arduino or a Teensy 3.1, you can take a look at an article I wrote some time ago on how to do it (it's here).

This concludes my tutorial, I hope it will prove useful to somebody. If you think it can be improved or have your own ideas for modifications, plese let me know in the comments section. If you'd like to share your intervalometer photos/videos, I *strongly* encourage you to do so!

Thanks and have a nice weekend!

Thursday, 11 September 2014

How to use a trimpot (or any three-legged potentiometer)?



First time I saw a trimpot (trim-pot as trimmer potentiometer, 10KΩ in my case) I immediaty started wondering why the heck does it have 3 pins. Would 2 not be just enough? I started googling and, surprisingly, the answer was not that easy to find. I'll share what I found out, but first, let me answer the title question: how to use a trimpot?
  1. First of all, if you flip the trimpot over, you will see 3 pins, just as on the diagram I clumsily prepared:


    That is the back of your trimpot. Well, you get the idea.

  2. Let's describe what's on the diagram. The two horizontally aligned pins (let's call them A and B) are your reference points and the third pin is called wiper.
  3. Now, the idea behind the trimpot is *brutally* simple:
    • Resistance between A and B is always constant (in my case, 10KΩ)
    • Restistance A-wiper and B-wiper varies depending on the trimpot's knob (or screw, whatever you have) so that if A-wiper is 10% of trimpot's nominal value, B-wiper will be (100% - 10%) of trimpot's nominal value.
And that's it, there's nothing more when it comes to trimpots. However, if you want some examples or if you're genuinely interested in what I have to say, please read on!


To follow up, let me list a couple of interesting facts about trimpots. Great majority of them has 3 pins, but there actually are trimpots with just two pins, like this one:


Why 3 and not 2 then? From what I've read, two most popular reasons are:
  • To keep soldered trimpots in place while adjusting their values. A lot of people simply ignore either pin A or B.
  • To utilise the fact that when the resistance on one side increases (e.g. A-wiper), the other one decreases (e.g. B-wiper), and vice-versa.
Additionally, as it turns out, trimpots are not really designed for adjusting their values too frequently - they are expected to work following the adjust-seal-forget formula. If you expect the resistance to change often, potentiometers are probably a better choice.

To illustrate how trimpots exactly work, I ran a couple of simple measurements (top: wiper, left: A, right: B). Before I start, though, please keep in mind that neighter my multimeter nor the trimpot are perfect, so expect some measurement imperfections. Also, the multimeter measures resistance in .




Trimpot's knob goes all the way down the B-wiper side. Whole resistance is allocated between A and wiper.
A-wiper measurement B-wiper measurement

Trimpot's knob goes all the way down the A-wiper side. Whole resistance is allocated between B and wiper.
A-wiper measurement B-wiper measurement

Trimpot's knob is somewhere in the middle of the range. Whole resistance is shared equally between A-wiper and B-wiper.
A-wiper measurement. I expected something around 5KΩ, but 5.00KΩ exactly is pure concidence. B-wiper measurement. 5.07KΩ - that's more like it!

Trimpot's knob is somewhere on the B-wiper side which means this side's resistance will be lower compared to the A-wiper side. Additionally, 7.00KΩ + 3.06KΩ = ~10KΩ, which is the nominal value of the trimpot.
A-wiper measurement. B-wiper measurement.

And finally, even though the trimpot's knob goes all the way down the B-wiper side, A-B resistance is always constant.
A-B measurement.