Sunday, April 30, 2017

Using the PI Cobbler on an Arduino

Introduction


The PI Cobbler (made by Adafruit) is a great tool that is used to connect a Raspberry PI to a bread board.
PI Cobbler

The Arduino Uno board on the other hand is not so straight forward to connect to a breadboard. You often end up with a mess of many wires
Arduino Uno requires individual wires towards the breadboard
An alternative is to use an Arduino Nano that fits directly on the breadboard
Arduino Nano fits directly on Breadboard


It would be great to be able to connect a flat cable directly to the Arduino UNO. So let's build an adapter UNO -> Flat cable

Assembly instructions

Needed stuff

You will need
  1. A PI Cobbler
  2. A 2x40 Positions Header, Breakaway Connector 0.100" (2.54mm) Through Hole
  3. An Arduino Uno
  4. An Arduino Protoshield (I use the one from Adafruit) 
  5. Some cabling wire
  6. Some solder
Update on May 2 2017:
STOP DON'T USE THE ADAFRUIT PI COBBLER!! it is only intended for the Raspberry PI. It contains internal wiring that connect all the Raspberry PI GND together this may damage your Arduino and / or prevent your project from working 

Monday, January 2, 2017

Creating a WASD joystick with an Arduino Esplora

Introduction

The classic WASD game keys are very popular. But if this key layout is nice on QWERTY keyboard, it is not so logical on an AZERTY keyboard.


With such layout you cannot make great score at any game.
The classic solution is to configure the keyboard as a US QWERTY keyboard for the duration of the game. But that's not a very satisfactory solution. What we need is a joystick that behaves like the WASD keys.

The Arduino Esplora board

The Arduino Esplora board is an Arduino Leonardo board that implement a joystick.
This is exactly what we need.

 The Leonardo (and the Esplora) board can behave like an HID device. This means that they can be programmed to behave as an USB mouse or as an USB  keyboard by the computer.

Now all we need is to program it so that the board joystick generates the WSAD key press.

The program

Enrico Gueli has written a program called "EsploraKart" (www.arduino.cc/en/Tutorial/EsploraKart) that does exactly what we want except that he has used the arrow keys instead of the WSAD keys.
Now lets modify his program to get the WSAD keys mapping:

/*
 esploraWASD
 This is a sketch is a modification of "EsploraKart" written by Enrico Gueli
 The joystick will send the WASD keys and
 the switches will send "space"
*/
#include <Esplora.h>
#include <Keyboard.h>
boolean buttonStates[8];
const byte buttons[] = {
  JOYSTICK_DOWN,
  JOYSTICK_LEFT,
  JOYSTICK_UP,
  JOYSTICK_RIGHT,
 
  SWITCH_RIGHT,
  SWITCH_LEFT,
  SWITCH_UP,
  SWITCH_DOWN
};
const char keystrokes[] = {
  's',
  'a',
  'w',
  'd',
  ' ',
  ' ',
  ' ',
  ' '

};
void setup() {
  Keyboard.begin();
}
void loop() {
  for (byte thisButton = 0; thisButton < 8; thisButton++) {
    boolean lastState = buttonStates[thisButton];
    boolean newState = Esplora.readButton(buttons[thisButton]);
    if (lastState != newState) { // Something changed!
      if (newState == PRESSED) {
        Keyboard.press(keystrokes[thisButton]);
      }
      else if (newState == RELEASED) {
        Keyboard.release(keystrokes[thisButton]);
      }
    }
    buttonStates[thisButton] = newState;
  }
  delay(50);
}

I have removed the comments and marked in red the modified lines

 Return of the AZERTY problem

The above program will work great if you have a QWERTY (or a German QWERTZ) keyboard, but strangely, it does not work with a computer configured with an AZERTY keyboard.

On a AZERTY computer the Esplora board outputs are  ZQSD instead of WASD.
If you look at the position of the ZQSD keys on an AZERTY keyboard you will notice that they are at the same location as the WASD keys on a QWERTY keyboard.

This is a limitation of the Arduino Keyboard library: this library allows to simulate a keyboard with a Leonardo or an Esplora board but the simulated keyboard is expecting that the computer uses a US QWERTY keyboard layout.

This origin of this restriction comes from the HID protocol: It specifies a key location on the keyboard and it is the computer responsibility to map this key location to a key symbol (or a special key).

I should have tried to adapt the Arduino Keyboard library to support multiple keyboard layouts. But I was too lazy ( this guy did something like that www.zem.fr). I simply have mapped the AZERTY keys in my program. This makes the program only usable on an AZERTY PC.

const char keystrokes[] = {
  's',//s
  'q',//a
  'z',//w
  'd',//d
  ' ',
  ' ',
  ' ',
  ' '
};

With this mapping the Esplora board is behaving like a WASD joystick. This is what I needed.

Sunday, December 18, 2016

Using mouse events on an HTML 5 Canvas in typescript

In this tutorial, I will show how to add a mouse event handler to an HTML 5 canvas using typescript.

Acknowledgements: Writing this would not have been possible without the excellent documentation I have found in http://www.typescriptgames.com/ 

The sample document:

To demonstrate the use of the mouse on a canvas, I have created a very simple page:


This page is a primitive drawing program that just draws a line on the canvas till the point where the mouse was clicked.

The html is below:


<!doctype html>
<html>
<head>
<title>Demonstration of Canvas and Typescript</title>
<link rel="stylesheet" href="canvas.css">
</head>
<body>
<header>
<h1>Mouse events on a canvas using typescript</h1>
</header>
<aside>
<h2>
Instructions
</h2>
<p>
Click on the canvas to draw a line from the last point to the point where you have clicked The first point is at the canvas center.
</p>
<p>
note: the canvas is cleared on resize.
</p>
</aside>
<canvas id="canvas">This is the canvas</canvas>
<script src=canvas.js></script>
</body>
</html>
And this is the CSS


h1{
    margin: 10px;
}
h2{
    margin: 0px;
}
aside {
    float: left;
    border: 1px solid black;
    padding: 10px;
    margin: 20px;
    width: 20%;
}
aside p{
    font-family: Arial, Helvetica, sans-serif;
}
#canvas {
    float: left;
    background: lightgray;
    border: 1px solid black;
    margin: 20px;
    width: 65%;
}

Handling the mouse event

Since we are using typescript, It is a good opportunity to make use of OOP. So let's create a class named canvasDraw that will handle all the operations related to drawing.

This class shall include an event handler that will receive the "mousedown" events
class CanvasDraw {
    canvas: HTMLCanvasElement;
    context: CanvasRenderingContext2D;
    private x: number;
    private y: number;
    public constructor() {
        this.canvas = <HTMLCanvasElement>document.getElementById("canvas");
        this.context = this.canvas.getContext("2d");
        this.canvas.addEventListener("mousedown", this.click, false);
    }
    public click = (event: MouseEvent): void => {
        this.context.beginPath();
        this.context.moveTo(this.x, this.y);
        let rect = this.canvas.getBoundingClientRect();
        this.x = (event.clientX - rect.left)/rect.width*this.canvas.width;
        this.y = (event.clientY - rect.top)/rect.height*this.canvas.height;
        this.context.lineTo(this.x, this.y);
        this.context.stroke();
        event.preventDefault();
    }
}
let canvasDraw: CanvasDraw = new CanvasDraw();

Syntax to declare the event handler:

We assign a lambda function to an attribute of the class:

 public click = (event: MouseEvent): void => { ... }

and we use this attribute to as a mousedown event listenr

this.canvas.addEventListener("mousedown", this.click, false);

This allows us to define the full code inside the class

Finding the clicked x/y position inside the canvas

The mouse event attributes clientX and ClientY cannot be used directly.

They need to be offset by the client top/left position and must be adapted by the canvas  scaling.

        let rect = this.canvas.getBoundingClientRect();
        x = (event.clientX - rect.left)/rect.width*this.canvas.width;
        y = (event.clientY - rect.top)/rect.height*this.canvas.height;

The canvas scaling problem

 If you try the above program (don't forget to compile the typescript into JavaScript) You will see that the result is not as good as expected. This is because the HTML 5 canvas maintain a distinction between the canvas size (i.e. the image drawn) and the displayed size.

By default the canvas size is 300px x 150 px but the displayed size is determined by the css. This means that most probably the displayed size will be much larger than the canvas drawing size leading to a "zoomed" image where all the pixels are visible and blurry.




To avoid this we should align the canvas size on the display size. But doing this is not straight forward.

Aligning canvas size on display size

To do this we use the following code

        this.canvas.height = this.canvas.offsetHeight;
        this.canvas.width = this.canvas.offsetWidth;

This works great but we need to find a way to call it at program startup  and each time the canvas is resized.

The resize event

There is no resize event on canvas in HTML 5 so we will have to use the event associated with the window object instead of the canvas object

class CanvasDraw {
    canvas: HTMLCanvasElement;
    context: CanvasRenderingContext2D;
    private x: number;
    private y: number;
    public constructor() {
        this.canvas = <HTMLCanvasElement>document.getElementById("canvas");
        this.context = this.canvas.getContext("2d");
        this.canvas.addEventListener("mousedown", this.click, false);
        //note resize event cannot be attached to the canvas
        window.addEventListener("resize", this.resize, false);
        this.resize(null);
    }
    public click = (event: MouseEvent): void => {
...
    }
    public resize = (event: UIEvent): void => {
        this.canvas.height = this.canvas.offsetHeight;
        this.canvas.width = this.canvas.offsetWidth;
    }
}

Note the call to resize at the end of the constructor that ensure that the initial canvas drawing area size is correct at the application startup

Important note: on most browser the canvas is cleared after resize but this behavior is not guaranteed. To avoid compatibility problems  we always clear the canvas with
 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);

The Complete program

Just for completeness and if you want to try it, this is the full listing of canvas.ts

class CanvasDraw {
    canvas: HTMLCanvasElement;
    context: CanvasRenderingContext2D;
    private x: number;
    private y: number;
    public constructor() {
        this.canvas = <HTMLCanvasElement>document.getElementById("canvas");
        this.context = this.canvas.getContext("2d");
        this.canvas.addEventListener("mousedown", this.click, false);
        //note resize event cannot be attached to the canvas
        window.addEventListener("resize", this.resize, false);
        this.resize(null);
    }
    public click = (event: MouseEvent): void => {
        this.context.beginPath();
        this.context.moveTo(this.x, this.y);
        let rect = this.canvas.getBoundingClientRect();
        this.x = (event.clientX - rect.left);///rect.width*this.canvas.width;
        this.y = (event.clientY - rect.top);///rect.height*this.canvas.height;
        this.context.lineTo(this.x, this.y);
        this.context.stroke();
        event.preventDefault();
    }
    public resize = (event: UIEvent): void => {
        //the problem is that we must align canvas resolution on CSS set display size
        // otherwise there will be a zoom at display that will blur the lines
        this.canvas.height = this.canvas.offsetHeight;
        this.canvas.width = this.canvas.offsetWidth;
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.x = this.canvas.width / 2;
        this.y = this.canvas.height / 2;
    }
}
let canvasDraw: CanvasDraw = new CanvasDraw();

Sunday, June 26, 2016

Redirecting stdout and stderr under Windows

Introduction

A console program (i.e. a program that is executed from the command line) can write its output on two separate streams: stdout and stderr. Theoretically stdout is used to display the program results and stderr is used to write error messages.

In a normal execution text written on both the stdout and the stderr isdisplayed on the console.

Lets try with an example. The following simplistic C# code writes a message on stdout and another message in stderr.



using System;
namespace TestStdout
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Error.WriteLine("STDERR message");
            Console.Out.WriteLine("STDOUT message");
        }
    }
}


If we execute this program on the windows command line we get



D:\test>TestStdout.exe
STDERR message
STDOUT message

D:\test>

Redirection

The redirection of stdout and stderr is well known by Linux users but strangely not so much popular for Windows users. However, it works (nearly) the same way with both operating systems

Redirect stdout to a file

To redirect the program output (stdout) to a file, use the operator >



D:\test>TestStdout.exe >out.txt
STDERR message

D:\test>type out.txt
STDOUT message

D:\test>

To get rid of stdout you may redirect it to a special file called NUL that throws away anything sent to it. (note that in Linux it is called /dev/null).



D:\test>TestStdout.exe >NUL
STDERR message

D:\test>


Redirect stderr to a file

To redirect the stderr you use the operator 2>



D:\test>TestStdout.exe 2>err.txt
STDOUT message

D:\test>type err.txt
STDERR message

D:\test>


You may also redirect stderr to NUL if you want to get rid of it



D:\test>TestStdout.exe  2>NUL
STDOUT message


D:\test>

Redirect both stdout and stderr to a file

You may combine > and 2> to redirect both stdout and stderr



D:\test>TestStdout.exe >out.txt 2>err.txt


D:\test>

It is also possible to redirect both stdout and stderr to the same file by using 2>&1 to first redirect stderr to stdout (&1 is in fact stdout) and redirect stdout to a file.



D:\test>TestStdout.exe >OutAndErr.txt 2>&1


D:\test>type OutAndErr.txt
STDERR message
STDOUT message


D:\test>

Redirecting to the clipboard

On Windows sytsems, it is possible to redirect directly to the clipboard instead of redirecting to a file (thank yo to Scott Hanselman for this trick ) by using | clip

You can redirect stdout to the clipboard



D:\test>TestStdout.exe |clip
STDERR message


D:\test>

You can redirect both stdout and stderr to the clipboard by first redirecting stderr to stdout



D:\test>TestStdout.exe 2>&1 |clip


D:\test>

You can redirect only stderr to the clipboard

But this is tricky: you have to redirect stderr to stdout and stdout  to null and pipe to clip. Warning swapping the operations does not get the correct result.


D:\test>TestStdout.exe 2>&1 >NUL |clip


D:\test>

Sunday, February 28, 2016

Connecting multiple LCD displays to an Arduino

The LCD Display

The LCD Display based on Hitachi HD (or equivalent) have been around for many years. They are a very popular way to display information on any microcontroller circuit.



They are available from many manufacturer and are in various display size. The usual size is 16x2 characters but you can find variants in 40x2 characters or 16x4 characters.

The display includes the full circuitry to drive the display and interface with the microcontroller.

Interfacing with the Arduino

 Interfacing with the Arduino is very straight forward and very well documented in www.arduino.cc/en/Tutorial/HelloWorld

The schematic is quite simple:


We can limit the number of wires used on the Arduino by using a 4 bits interface instead of 8 bits and hardwiring the R/W pin to VSS since we don't need to read back information for the display.

This means that the interface is reduced to 4 data bits (DB4...DB7) and the 2 control wires: RS and E.
RS is used to select the register where the data shall be written (one register is used to display text and the other one is used to control the display behaviour) . The E wire is used to perform the actual data write operation.

To access the LCD display from the Arduino sketch we use an object of the LiquidCrystal class (for the standard Arduino library LiquidCrystal.h) by creating it with the correct pin assignation:

  lcd(12, 10, 5, 4, 3, 2);

Warning: When wiring the display, check carefully the manufacturer datasheet to find the correct pinout. Every manufacturer agrees that there are 14 pins to control the LCD + 2 pins to control the backlight but the exact pin assignation varies slightly from a manufacturer to another.

Multiple Displays


Now we want to connect one (or more) additional displays to the Arduino

As explained above the LCD display takes the data into account only when the E pin is activated. This means that you can connect all the displays signals in parallel on the Arduino digital outputs as long as you keep the E signals separated.

In the schematics below I have used digital output D10 to control E signal of LCD1  and output D11 to control E signal of LCD2

The Software

The Arduino sketch to control multiple displays is very similar to the one used to control one display.

You simply have to create one object of the LiquidCrystal class for each display. I have found that the easiest way to do it is to store them in array by using the following code:
 
LiquidCrystal lcd[2]={LiquidCrystal(12, 11, 5, 4, 3, 2), LiquidCrystal(12, 10, 5, 4, 3, 2)};


This allows to easily select on which display to print (or to send any command) as shown in the very simple "Hello World" example below.

warning, since arrays begin at index zero, the 2 LCD displays shall be numbered zero and on1 (instead of one and two).

/*
This sketch prints "Hello World!" on 2 LCD displays
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11 for LCD1 pin 10 for LCD 0
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* LCD VSS pin to ground
* LCD VCC pin to 5V
* 10K pot
* ends to +5V and ground
* wiper to LCD VO pin
*/

// Directly based on the Arduino example LiquidCrystal HelloWorld
#include <LiquidCrystal.h>

LiquidCrystal lcd[2] = { LiquidCrystal(12, 11, 5, 4, 3, 2),LiquidCrystal(12, 10, 5, 4, 3, 2) };

void setup() {
// set up the LCD's number of columns and rows:
lcd[0].begin(16, 2);
lcd[1].begin(16, 2);
lcd[0].setCursor(0, 0);

lcd[0].print("Hello");
lcd[1].setCursor(0, 0);
lcd[1].print("World!");
}

void loop() {
}

Monday, November 30, 2015

GPIO pins allocation under windows 10 IOT build on Raspberry PI

The Windows 10 IOT documentation https://ms-iot.github.io/
indicates that only the following pins are available 4,5,6,12,13,16,17,18,19,20,21,22,23,24,25,26,27 for GPIO.

If you wonder why so many pins are not usable as GPIO. This is because
  • GPIO 2, and 3 are reserved for I2C interface
  • GPIO 7,8,9,10,11 are reserved for SPIO interface
  • GPIO 14,15 are reserved for UART interface.


Note that 35 and 47 are also available but they drive LEDs soldered on the board and not pins on the GPIO connector.

If you are still using Windows10 IOT build 10.0.10240 you must know that for some unknown reasons the Raspberry PI GPIO pins 17, 19, 20, 21 are not usable. I think this is a very good reason to update to build 10.0.10556.

 

Program To list all the available GPIOs

 
I have developed a small program that list all the available GPIOs.
 
The XAML is the following
 

<Page
x:Class="CountGPIO.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CountGPIO"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Name="TextblockOutput" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Page>

 
 
And the C# code associated
 

using System;
using Windows.Devices.Gpio;
using Windows.UI.Xaml.Controls;
namespace CountGPIO
{
  public sealed partial class MainPage : Page

  {
    private GpioController gpio;

    public MainPage()
    {
    this.InitializeComponent();

    gpio = GpioController.GetDefault();
    this.TextblockOutput.Text = "List of Supported GPIO pins:" +  Environment.NewLine;
    for (int port = 0; port < 64; port++)
     {
     try

      {
      gpio.OpenPin(port);
      this.TextblockOutput.Text += "GPIO Pin: " + port.ToString() + " is OK" + Environment.NewLine;

      }
     catch (Exception)

      { }
     }
    }
  }
}
 


Sunday, November 15, 2015

How to use a PC To Connect a Raspberry PI to a WIFI network


Introduction

 
The problem is the following : I am using have a standard Raspberry PI (i.e. without any WIFI interface) at a location where the only way to access the Internet is the WIFI. Is it possible to use my portable PC running Windows as a router to connect the Raspberry PI to the Internet ?
 
 
 
The answer is YES and it is very easy
 
 

Step1: Activate ICS

Activate the ICS on the WIFI connection of the Windows computer. The ICS (Internet Connection Sharing) allows other computers to use the WIFI connection of the Windows computer.
This is done in the network control panel (you may reach it by using the command)
control ncpa.cpl
Then select properties on the WIFI network
 
 



And then activate the sharing of the the WIFI connection

Once this is done any computer connected to the PC ethernet port shall receive via DHCP an IP address in the 192.168.137.X network (note the PC is located at 192.168.137.1)
 
 
 
 

Step2 Connect the Raspberry PI to the PC


Connect the Raspberry PI with a standard Ethernet cable equipped with standard RJ45 connectors). You don't even need a crossed cable because the Raspberry PI support auto MDI-X (which means that the Raspberry PI will detect that a crossed cable is needed and automatically preform the « cross » internally) .
 
Now everything is done and your raspberry PI can access the Internet. But If You don't have keyboard and display connected to it you need to know which IP address the Windows PC DHCP has given to it.
 

Step 3 retrieve the Raspberry PI IP address

The simplest way to obtain this address is to query the ARP table. Start a Windows command prompt (if you don't know how to do it just press WINDOWS+R and type cmp ENTER)
and type the following command
arp -a -N 192.168.137.1
This will give you a reply that looks like that
 
In this list you see that the Rasberry PI has been granted the addres 192.168.137.55
 
Note : the 192,168,137,255, all the 224.x.x.x and the 239.255.255.250 addresses are all multicast addresses (we don't care about them)
You can now connect to you Rasberry PI via SSH and from the Raspberry PI communicate with the Internet.