AdSense

Tuesday, 10 February 2015

Serial communication with Matlab or C#

(Deutsche Version) In the last post, I showed how to read out a heartbeat sensor (Read out heartbeat sensor). In this post, I want to explain how to read this data with Matlab or C#. I want to start with Matlab. At first, you have to open a serial port:

s = serial('COM3');
fopen(s);


You simply have to plug in the number of your COM port. Afterwards you can read all existing characters:

str = fscanf(s);

Keep in mind that it can also occur that the Arduino has only sent half of its message when the computer is reading all existing characters, and in the next read instruction from the computer, the rest of the message (and possibly further messages) is read in. In the end you should close the port:

fclose(s);

Now, I want to explain how to do this in C#. Again, you have to open a port:

port = new SerialPort("COM3", 9600);
port.Open();

Afterwards, you can read in all existing characters (analog to the example with Matlab):

string indata = sp.ReadExisting();

In C#, you don't have to close the port because this happens automatically when closing the program.

Saturday, 24 January 2015

Read out heartbeat sensor

(Deutsche Version) If you look for "heartbeat sensor" on ebay, you find a small circuit board which contains an LED and a photo transistor. This board claims to be able to measure the heart beat. I bought one sensor and tried it. Unfortunately, there is very few (ok, basically absolutely no) documentation about the sensor and not even something like a product key, only xinda and Lcup can be found on the sensor.
The heartbeat sensor
The sensor has 3 pins which are labelled very good. One of them has a -, here you have to connect GND. The next pin has an S, this is the pin for the sensor output. The last pin (in the middle) which has no label is connected to the LED. This pin has to be connected to +5V and the sensor output has to be connected to an analog input of the arduino.

The program reads the sensor value and sends it to the computer via the serial port where you can further process the data (e.g. with Matlab, maybe I will write a post about that). Here is a picture of the plotted heartbeat data on the computer and below the code for the Arduino.
//Define pins for LED and sensor.
int ledPin = 13;
int sensorPin = 0;
//alpha is used in the original proposed code by the company (see below).
double alpha = 0.75;
//lasttime is used to have a very precise measurement of the time so the calculated pulse is correct.
unsigned long lasttime;

void setup ()
{
  //Switch on the LED.
  pinMode (ledPin, OUTPUT);
  digitalWrite(ledPin,HIGH);
  Serial.begin (9600);
  lasttime = micros();
}

void loop ()
{
  //Also used for smoothening the signal.
  static double oldValue = 0;
  
  //Wait 10 ms between each measurement.
  while(micros() - lasttime < 10000)
  {
    delayMicroseconds(100);
  }
  
  //Read the signal.
  int rawValue = analogRead (sensorPin);
  lasttime += 10000;
  
  //In the "original" code example, "value" was sent to the computer. This calculation basically smoothens "rawValue".
  //double value = alpha * oldValue + (1 - alpha) * rawValue;
  
  //Send back the measured value.
  Serial.println (rawValue);
  oldValue = value;
}

Sunday, 18 January 2015

A gaming table for tabletops

(Deutsche Version) For tabletop games you need some kind of base to play on. For the beginning, a small table or simply the floor is sufficient but if you start to have large battles, something bigger is needed. The usual size of tables for 28 mm tabletops is about 6 x 4 feet, this is about 183 x 122 cm. Such a table is quite large and needs a lot of space, it can take up to a whole room. Therefore I created a table which can be set up and dismounted within 2 minutes.

The basic idea is simple. A large plate of wood is layed onto an existing coffee table. My coffee table is about 110 x 70 cm, so a plate of 183 x 122 cm would hang down. Therefore, the gaming table required to have feet. The result was a gaming table consisting of two plates of the size 183 x 61 cm which you can plug together easily. One side of the table is layed down on the coffee table whereas two feet are placed below the other side. I will now explain the single parts of the table.
The complete table.
The plates
For the plates I used 8 mm thick chipboard. A thicker plate is more stable but also heavier and more expensive. 8 mm works pretty fine for me but you shouldn't sit on top of the table.

The feet
At the end of each plate there is a foot mounted via a hinge. If the table is dismounted, you can easily fold up the foot and it does not take up much room.
The feet of the table.
Plugging together
At Obi, a local hardware store, there are special locks for closets which you can easily plug together. I attached them to both plates so you can plug the plates together.
The connection between the plates.
Positioning on the coffee table
Finallz, I glued some small pieces of wood below the table so the plate fits perfectlz onto the coffee table and cannot move anz more.
On the left the coffee table with the piece of wood below the plate.
On the table, you can now distribute the terrain or a grass mat. Alternatively, you can also put grass directly onto the plates, attach a piece of cloth or paint the plates which can be useful for large areas of water.

Tuesday, 13 January 2015

Arduino - read keypad

(Deutsche Version) Today I want to explain how to read out a simple keypad with an Arduino, as seen in the following image. You could use this keypad from ebay: Keypad.
The keypad has 8 pins. 4 in each case are for the rows respectively the columns. A pressed key connects two of these pins. 4 pins are used as an output on the Arduino, the other 4 pins as an input. I used pin 22, 24, 26 and 28 as output and 30, 32, 34, 36 as input so you can easily attach the keypad to the Arduino using a pin header.
Now a voltage is applied to one output after the other and the input pins are measured whether they receive this voltage. This shows directly which key was pressed. My code reads the pressed keys and sends them via the serial bus to the computer as soon as a key state has changed.

//For different sizes of Keypads, you can adjust the numbers here. Important: Also change the keyValues array!
const int numOuts = 4;
const int numIns = 4;
//These are the 4 output pins, adjust it if you use a different pin mapping
int outs[numOuts] = {22, 24, 26, 28};
//These are the 4 input pins, adjust it if you use a different pin mapping
int ins[numIns] = {30, 32, 34, 36};
//This array contains the values printed to the different keys
char keyValues[numOuts][numIns] = {{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'*','0','#','D'}};
//This array contains whether a pin is pressed or not
boolean pressed[numOuts][numIns];

void setup() {  
  Serial.begin(9600);
  //Define all outputs and set them to high
  for (int i = 0; i < numOuts; i++)
  {
    pinMode(outs[i], OUTPUT);
    digitalWrite(outs[i], HIGH);
  }
  //Define all inputs and activate the internal pullup resistor
  for (int i = 0; i < numIns; i++)
  {
    pinMode(ins[i], INPUT);
    digitalWrite(ins[i], HIGH);
  }
}

//Read whether a key is pressed
void KeyPressed()
{
  for (int i = 0; i < numOuts; i++)
  {
    //Activate (set to LOW) one output after another
    digitalWrite(outs[i], LOW);
    //Wait a short time
    delay(10);
    for (int j = 0; j < numIns; j++)
    {
      //Now read every input and invert it (HIGH = key not pressed (internal pullup), LOW = key pressed (because the output was set to LOW)
      boolean val = !digitalRead(ins[j]);
      //If the value changed, send via serial to the computer and save the value in the "pressed" array
      if (pressed[i][j] != val)
      {
        char str[255];
        sprintf(str, "%c pressed: %d", keyValues[i][j], val);
        Serial.println(str);
        pressed[i][j] = val;
      }
      
    }
    //Deactivate (set back to HIGH) the output
    digitalWrite(outs[i], HIGH);
  }
}

//Yeah, do this forever...
void loop()
{
  KeyPressed();
}

Sunday, 14 December 2014

Arduino - Read out height sensor GY-65

(Deutsche Version) A common way to measure relative heights is the usage of a barometric height sensor. Such a sensor measures the pressure and by using the barometric formula (Wikipedia), one can calculate the height. The ambient pressure varies during the days therefore the sensor is calibrated at a well-known height and the other heights are calculated by using this reference pressure and height. The measured heights have a precision of up to 1 meter.

If  you look for the GY-65 at ebay, you can find the sensor for about 5 euro. The sensor has a usual I2C interface so only two wires are needed. Additionally, the I2Cdev library is needed which can be downloaded here. The source code is as simple as possible, at first the sensor is initialised, then measuring the pressure is set and afterwards the pressure is read out and calculated into the height. A basic program looks like this:


#include <I2Cdev.h>
#include "BMP085.h"
#include <Wire.h>

BMP085 barometer;

double pressure;
double altitude;


void setup() {
  Wire.begin();
  
  Serial.begin(9600);
  Serial.println("starting...");
    
  //initialize the barometer
  barometer.initialize();
}

void loop()
{
  // request pressure (3x oversampling mode, high detail, 23.5ms delay).
  // Let's just wait a bit more to be sure...
  barometer.setControl(BMP085_MODE_PRESSURE_3);
  delay(30);
  // read calibrated pressure value in Pascals (Pa)
  pressure = barometer.getPressure();
  // calculate absolute altitude in meters based on known pressure
  // (may pass a second "sea level pressure" parameter here,
  // otherwise uses the standard value of 101325 Pa)
  altitude = barometer.getAltitude(pressure); 
  
  // print back the calculated altitude
  Serial.println(altitude);
  // do this every second
  delay(1000);
}

I2C OLED display

(Deutsche Version) If you look for "Arduino OLED Display" on Ebay, you will find a display with a size of 1 inch and a resolution of 128x84 pixels which is controlled via I2C. It costs less than 4 Euros. Of course, 1 inch isn't much, but I was curious and so I ordered it. To show you how small it really is, I placed a coin next to it:


Connecting the display is very easy (thanks to I2C): you only need the voltage supply and two wire for I2C. But how can you control the display? After some searching on Google I found out that the display is a clonde of the Adafruit OLED display called SSD1306. Adafruit offers an Arduino library for this display which can be downloaded HERE. Additionally you need the Adafruit-GFX-Library. After installing the two libraries you will find the example "ssd1306_128x64_i2c" under "Adafruit_SSD1306" in the Arduino IDE. But if you transmit this example to the Arduino nothing will happen. The china-clone-display has a different I2C adress than the original Adafruit display. You will have to change something in the setup() function. Change
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);  // initialize with the I2C addr 0x3D (for the 128x64)
to
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64).

After that you can transmit the example to your Arduino and you should see a small demonstration of the different functions of the GFX library on the display. Since there are a lot of functions and the example has a lot of code I will not explain it in detail. I think all of the functions in the example are self-explanatory. I you have problems understanding the code, just have a look in the header file of the GFX library. There you find further explanations like parameters for the functions. You can print text, draw squares, triangles, etc. Even inverting or scrolling the screen is possible.

You also have the possibility to print a user-defined bitmap. I'm going to explain this:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define XPOS 50
#define YPOS 25
#define BITMAP_HEIGHT 16 
#define BITMAP_WIDTH  16 
static const unsigned char PROGMEM bitmap[] =
{ B00000001, B10000000,
  B00000010, B01000000,
  B00000100, B00100000,
  B00001000, B00010000,
  B00010000, B00001000,
  B00111111, B11111100,
  B00101000, B00010100,
  B00100100, B00100100,
  B00100010, B01000100,
  B00100001, B10000100,
  B00100010, B01000100,
  B00100100, B00100100,
  B00101000, B00010100,
  B00110000, B00001100,
  B00111111, B11111100,
  B00000000, B00000000 };

void setup()   {                

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64)
  
  //clear display buffer
  display.clearDisplay();
  //draw a bitmap stored in variable bitmap with given size at XPOS, YPOS in color white
  display.drawBitmap(XPOS, YPOS, bitmap, BITMAP_WIDTH, BITMAP_HEIGHT, WHITE);
  display.display();
 
}


void loop() { 
}


In this example we are going to draw a bitmap with the size of 16x16 pixels. Of course you can choose another size. The bitmap has to be stored in a character array. It is very important to use the keyword "PROGMEM" when declaring the variable. This will make the Arduino store the variable in the flash memory. The library only accepts bitmaps stored in flash. In the example, two characters store the 16 bit data of a line of the bitmap. If a bit is set, a pixel is set when the bitmap is drawn. To increase readability, line breaks were inserted. On line in the code is on line of the bitmap. To draw the bitmap, you have to call the function drawBitmap(). Parameters are: x- and y-position of the bitmap, the variable in which the bitmap is stored, height und width of the bitmap and its color (BLACK or WHITE) of a set pixel.

The result:

Friday, 5 December 2014

Sharpen a brush

(Deutsche Version) A newly bought brush is usually sharp and also a bit hard so you can draw very fine lines. After a while, the hair of the brush starts to point into every direction so you cannot use the brush any more. To get the brush back into the state which it has been after buying, you can use a simple trick.
A used brush which you cannot use for fine details any more.
First you have to create a mixture of sugar and water. Simply mix the two ingredients and stir. Now you may put the brush in the liquid. The surface tension keeps the hair together.
Brush tip with the sugar water mixture applied. The hair is kept together (Surface tension).
To get the brush back into the perfect shape, you have to wipe off the brush off carefully, this gets it even sharper. If the brush dries, the tip gets even better, as good as for a newly bought brush. I use brushes of the size 00, you can get them in every toy's shop. If you take good care of the brush, you should be able to use it forever.
The sharpened brush.