25 Sept 2012

Magick numbers

yay, one of my posts just hit 2600 views ;)

13 Sept 2012

Flying the ResearchDrones UAV in Holland

Last weekend we have been visiting the Netherlands to train Sander, a brave young biology scientist. Sander is planning to monitor Chimpanzees in Gabon with our Drone.

This time we got everything right. The autopilot was working perfectly, performing automatic take-offs and landings. The cameras shot quiet sharp images.

The current solution is able to carry quiet some payload, approx. 1kg. The planned endurance on this airframe is 1h. It is fully autonomous and the flight can be planned with a laptop through a map and then be uploaded to the drone.


Here are some impressions from the flight training and testing in Holland:









22 Aug 2012

Maja Drone Airframe is a very stable platform

The Maja Drone platform from Bormatec is a very stable, easy to handle and rugged platform for UAV's with a small payload (~300g in our case).

Due to the superb slow speed behavior of this platform it is also operable by inexperienced pilots.

  • 0:30 takeoff
  • 1:20 landing
on a gusty day.


12 Aug 2012

Universal r/c camera shutter control

This is a first proof of concept for a universal camera shutter control. The goal is to turn a camera on/off as well as controlling its shutter. Both functions are controlled with one radio channel (3 position switch) from an r/c receiver. The green LED signals that the camera has been turned on and the red LED that the shutter is operated with a predefined interval.

Parts for this hack cost approx. U$ 5 so far.

11 Aug 2012

Reading PPM Signal with arduino

I want to trigger additional logic in an UAV when I flip a 3 position switch on my R/C transmitter. This sketch will decode a PPM signal from an R/C receiver and will turn on two LEDs depending on switch position.

The code compiles for a Sparkfun Pro Micro 16MHz and also on an ATtiny85:


/**
 * Read PPM signal
 * 
 * Decode r/c receiver PPM servo signal and turn lights on 
 * according to servo position.
 *
 * $Id$
 */

// from which pin to read.
#define PIN_PPM   9
#define PIN_POS1 10
#define PIN_POS2 16

unsigned long duration, lastgood = 0;
int position = 0;

void setup() {
  pinMode(PIN_PPM, INPUT);
  pinMode(PIN_POS1, OUTPUT);
  pinMode(PIN_POS2, OUTPUT);
  digitalWrite(PIN_POS1, LOW);
  digitalWrite(PIN_POS2, LOW);
}

void loop() {
  // the length of the pulse (in microseconds) or 0 if no pulse 
  // started before the timeout (unsigned long)
  duration = pulseIn(PIN_PPM, HIGH, 20000); 
  if (duration == 0) {
    duration = lastgood;
  } else {
    lastgood = duration;
  }
  // map ppm values to 0, 1 and 2
  position = map(lastgood, 1000, 2000, 0, 2);
  // 0 == both off, 1 == LED1 on, LED2 off, 2 = both on 
  if (position > 0) {
    digitalWrite(PIN_POS1, HIGH);
  } else {
    digitalWrite(PIN_POS1, LOW);
  }
  if (position > 1) {
    digitalWrite(PIN_POS2, HIGH);
  } else {
    digitalWrite(PIN_POS2, LOW);
  }
}

5 Jul 2012

Arduino Pro Micro as USB Adapter for BlueSMiRF

/**
 * Pro Micro 5V / BlueSMiRF Test
 *
 * Pro Micro has 2 Serial adapters. One on the USB port (Serial), another on 
 * pin 11 (RX) and 12 (TX) (known as Serial1).
 *
 * This program will transmit data received on Serial to Serial1 and Serial1 
 * to Serial. This can be useful when a bluetooth adapter must be hooked up to 
 * an usb port.
 *
 * Pins
 *    VCC to VCC (3.3-6V)
 *    GND to GND 
 *    TX-O to RX-I 
 *    RX-I to TX-O 
 * 
 * LEDs
 *    Orange: USB receive, Bluetooth transmit
 *    Green:  Bluetooth receive, USB transmit
 *
 * $Id$
 */

void setup() {
  Serial.begin(115200); //  USB
  Serial1.begin(115200); // BlueSMiRF
}

void loop() {
  if (Serial.available())
    Serial1.write(Serial.read());
  
  if (Serial1.available())
    Serial.write(Serial1.read());
} 
 

BlueSMiRF Gold setup HOWTO

a short HOWTO on BlueSMiRF Setup from linux.




The default baud rate of the BlueSMiRF Gold is 115'200 baud. Using an FTDI cable from sparkfun, 3V or 5V will do), the following pins must be connected:

FTDI connector:
BlueSMiRF Gold connector:
 
Wiring it up to the FTDI connector:
  • VCC to VCC (3.3-6V)
  • GND to GND 
  • TX-O to RX-I 
  • RX-I to TX-O 
The BlueSMiRF is now power via the FTDI's VCC. So, it's time to connect it to an USB port. Via /var/log/messages (on some linux systems it's in /var/log/syslog?) you ca check the name of the device

$ grep tty /var/log/messages | tail -n1
Jul  4 20:31:58 shell1 kernel: [4027300.342679] usb 8-1: FTDI USB Serial Device converter now attached to ttyUSB0


This means it is connected to /dev/ttyUSB0 in m case.

Now it's time to use a serial terminal such as minicom, screen or in my case PuTTY:
































Serial line: /dev/ttyUSB0
Speed: 115200
Connection type: Serial

That's it. You will be greeted with an empty prompt. At the prompt, enter '$$$' and hit the key. You should get an CMD as response. Otherwise you most probably have chosen the wrong tty port or baud rate. Also, you need to enter '$$$' in the first 60 seconds after power up or the command won't be recognized.

Entering help will bring up the ist of available commands:



*** SET COMMANDS ***
SA,<1,0>   - Authentication
SB,   - Send Break
SC,   - Service Class
SD,   - Device Class
SE,<1,0>   - Encryption
SF,1       - Factory Defaults
SI,   - Inquiry Scan Window
SJ,   - Page Scan Window
SL, - Parity
SM,<0-5>   - Mode (0=slav,1=mstr,2=trig,3=auto,4=DTR,5=Any)
SN,  - Name
SO,  - conn/discon Status
SP,  - Pin Code
SR,   - Remote Address
SS,  - Service Name
ST,   - Config Timer
SU,  - Baudrate
SW,   - Sniff Rate
SX,<1,0>   - Bonding
SY,   - TX power
SZ,   - Raw Baudrate
S7,<0-1>   - 7bit data
S~,<0-3>   - Profile (0=SPP,1=DCE,2=DTE,3=MDM,4=D&S
S?,<0-1>   - role switch
S$,  - CMD mode char
S@,   - io port dir
S&,   - io port val
S%,   - io boot dir
S^,   - io boot val
S*,   - pio(8-11) set
S|,   - low power timers
*** DISPLAY      ***
D     - Basic Settings
E     - Extended Settings
G  - Stored setting
GB    - BT Address
GK    - Connect Status
G&    - I/O Ports
V     - Firmare version
*** OTHER        ***
C,    - Connect
F,1        - Fast Mode
I,

Full documentation: RN-41 AT Command Set

All I needed to do was changing the name to something more specific to the device I was building (and wile I was at it, I changed the pin code needed for pairing):

SN,Fireworks-1
SP,5678 
R,1
D
***Settings***
BTA=000666069B51
BTName=Fireworks-1
Baudrt(SW4)=115K
Parity=None
Mode  =Slav
Authen=0
Encryp=0
PinCod=
5678Bonded=0
Rem=NONE SET




28 Jun 2012

Compile and Run a C file from wihin gedit

I use gedit to write simple C programs. The External Tools plugin is really helpful for compiling and running them. Here is a simple example to invoke gcc and run the compiled file:

#!/bin/sh

EHOME=`echo $HOME | sed "s/#/\#/"`
DIR=$GEDIT_CURRENT_DOCUMENT_DIR
BASENAME=`echo "$GEDIT_CURRENT_DOCUMENT_NAME" | sed -e 's/\.c$//'`

cd "$GEDIT_CURRENT_DOCUMENT_DIR"
date
gcc -o "$BASENAME" "$GEDIT_CURRENT_DOCUMENT_NAME"

11 May 2012

10 May 2012

First Production Batch Prototype 2 of Fireworks (V4)

Yay the joy. I have just etched the PCBs for the final production Boards.

Update: it turns out that this is still a prototype (the hardware is not yet production ready).

What is it? This board (once finished) will be able to launch fireworks trough electric fuses controlled by a Bluetooth device (I plan to write an Android app).

See the development history of this project.





Layout




9 May 2012

Programming ATtiny45/ATtiny85 with Arduino

I have found many long winded HOWTOs on doing this, I love mini howtos, here we go:

I am using an Arduino UNO with Arduino IDE 0022.

The Arduino IDE needs some hardware information to support the ATtiny45/ATTiny85. Download the following zip file, create a hardware folder in your sketches folder and unzip it into the newly created hardware folder (you should now have the following folder structure in your sketches folder: hardware/attiny45_85/). Restart the Arduino IDE.

Flash your Arduino with the ArduinoISP sketch (File » Examples » ArduinoISP, compile and upload).

Connect the ATtiny45 or ATtiny85 to your Arduino as shown below:


(use a 10 uF capacitor between reset and ground, - on the capacitor goes to GND).


Pin layout of ATtiny45/ ATtiny85

That's it. Select "Tools » Board » ATtiny45 (w/ Arduino as ISP)" as board and you are good to go. While uploading the Arduino IDE will show the error "avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny45". This doesn't have an effect, just disregard it.

To check if it works you may connect a LED from pin0 to GND and upload the following blink sketch (the LED will also flash on activity during MOSI while uploading a sketch).

// Blink for ATtiny45/ATtiny85 

#define PIN_LED 0

void setup() {                
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(PIN_LED, OUTPUT);     
}

void loop() {
  digitalWrite(PIN_LED, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(PIN_LED, LOW);    // set the LED off
  delay(1000);              // wait for a second
}

23 Apr 2012

Display HEX and Binary representation of an integer with C

a little example in C on how to display an integer in hex an binary:

/**
 * Name        : bitwise.c
 * Author      : wus
 * Version     : $Id: bitwise.c 13 2012-04-23 15:37:41Z wus $
 * Copyright   : GPL
 * Description : Print an 8-64 bit integer in hex and binary to stdout.
 *
 * NOTE: gcc needs the -lm option enabled to include the math library (must add
 *       -lm after the source file, WTF?)
 * NOTE: compile flags: $ gcc -ofilename filename.c -lm
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>

int int_size = 64;  // num bits of integer

void usage(void) {
 printf("Usage: bitwise <%d bit int>\n\n", int_size);
 printf("Exit codes:\n");
 printf("  2 argument error\n");
 printf("  3 overflow error\n");
}

char dec2hex(int digit) {
 if (digit < 10) return (digit + 48);
 switch(digit) {
  case 10: return 'A';
  case 11: return 'B';
  case 12: return 'C';
  case 13: return 'D';
  case 14: return 'E';
  case 15: return 'F';
 }
 return '*';
}

/**
 * generate binary and hex string from an integer
 *
 * loop bit for bit (MSB) over an integer, generate binary and hex string
 *
 * param num:      the number
 * param result:   max. 64 bits + 7 spaces (pairs by 4 and an ending \0
 * param hex:      hex representation, 8 digits and one \0
 * param int_size: number of bits to represent in the output
 */
void format_bin(uint64_t num, char result[78], char hex[9], int int_size) {

 int pos_bit, pos_string = 0;
 int pos_hex = int_size / 4 - 1;
 int str_size = int_size + (int_size/4 - 1);
 hex[pos_hex] = 0;

 for(pos_bit=0; pos_bit < int_size; pos_bit++, pos_string++) {
  // add spaces
  if (pos_bit % 4 == 0 && pos_bit != 0) {
   result[str_size - 1 - pos_string++] = ' ';
  }

  // check if current bit is set
  int t = ((num & (1L<<pos_bit)) ? 1 : 0);
  result[str_size - 1 - pos_string] = t + 48;
  
  // handle hex
  int pot = pos_bit % 4;

  if (t) {
   switch (pot) {
    case 0: hex[pos_hex] += 1; break;
    case 1: hex[pos_hex] += 2; break;
    case 2: hex[pos_hex] += 4; break;
    case 3: hex[pos_hex] += 8; break;
   }
  }

  // next character
  if (pot == 3) {
   // make sure the int is a character and store it in the
   // result hex string
   hex[pos_hex] = dec2hex(hex[pos_hex]);
   hex[--pos_hex] = 0;
  }
 } // end for loop

 hex[int_size/4] = '\0';
 result[str_size] = '\0';
}

/**
 * generate binary and hex representation of an integer value
 */
int main(int argc, char* argv[]) {

 if (argc != 2) {
  usage();
  exit(2);  
 }

 int arg1 = atoi(argv[1]);
 // check overflow
 if (arg1 > (pow(2, int_size) - 1)) {
  printf("Overflow detected, we can handle max. %d bit integers!\n\n",
         int_size);
  usage();
  exit(3);
 }
 uint8_t input = arg1;
 
 char str[78];
 char hex[9];
 format_bin(input, str, hex, int_size);
 printf("\n0x%s - %s\n", hex, str);

 return EXIT_SUCCESS;
}

gcc math.h WTF!?

#include <math.h> in gcc will not automatically pull in the math implementation only the header. To make a file with this include compile you need to add -lm on the command line (linker option). To make it a bit more convenient, in my case I had to add the option after the source file on the command line.

Example:

$ gcc -omyfile myfile.c -lm