25 Sept 2012
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
12 Aug 2012
Universal r/c camera shutter control
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); } }
28 Jul 2012
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:
- VCC to VCC (3.3-6V)
- GND to GND
- TX-O to RX-I
- RX-I to TX-O
$ 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
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"
18 Jun 2012
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