diff --git a/conf/messages.xml b/conf/messages.xml
index d09933be9f4..0542da3bebc 100644
--- a/conf/messages.xml
+++ b/conf/messages.xml
@@ -1165,7 +1165,12 @@
-
+
+
+
+
+
+
diff --git a/conf/modules/geiger_counter.xml b/conf/modules/geiger_counter.xml
new file mode 100644
index 00000000000..a09ec1c90ae
--- /dev/null
+++ b/conf/modules/geiger_counter.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sw/airborne/firmwares/non_ap/geiger_counter/geiger_counter.c b/sw/airborne/firmwares/non_ap/geiger_counter/geiger_counter.c
new file mode 100644
index 00000000000..76c22094b44
--- /dev/null
+++ b/sw/airborne/firmwares/non_ap/geiger_counter/geiger_counter.c
@@ -0,0 +1,171 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2011 Martin Mueller
+ *
+ * This file is part of Paparazzi.
+ *
+ * Paparazzi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * Paparazzi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with paparazzi; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* I2C interface for University of Reading Geiger-Mueller counter */
+
+#include
+
+#define END_MSG 0x13
+
+/* green LED pin PB5 (on arduino pro mini) */
+#define LED_GR_PIN 13
+
+#define GEIGER_CNT_I2C_ADDR 0x76
+
+enum stats {
+ INIT,
+ FOUND_SYNC,
+ FOUND_1,
+ FOUND_2,
+ FOUND_3,
+ FOUND_4,
+ FOUND_5 };
+
+int received data = 0;
+int stat = 0, received data = 0;
+unsigned long count_geiger_1 = 0;
+unsigned long count_geiger_2 = 0;
+unsigned short volt_geiger = 0;
+
+void read_i2c() {
+ unsigned char dat[10];
+ digitalWrite(LED_GR_PIN, LOW);
+ received_data = 0;
+ memcpy(dat, count_geiger_1, 4);
+ memcpy(dat+4, count_geiger_2, 4);
+ memcpy(dat+8, volt_geiger, 2);
+ Wire.send(dat, 2);
+}
+
+void setup() {
+ /* serial port */
+ Serial.begin(2400);
+ pinMode(2,OUTPUT);
+ digitalWrite(2,HIGH);
+#ifdef DEBUG
+ Serial.println("geiger counter init");
+#endif
+
+ /* I2C init */
+ Wire.begin(GEIGER_CNT_I2C_ADDR >> 1);
+ Wire.onRequest(read_i2c);
+
+ /* green LED init */
+ digitalWrite(LED_GR_PIN, LOW);
+ pinMode(LED_GR_PIN, OUTPUT);
+
+ stat = INIT;
+}
+
+void loop() {
+ unsigned char ser;
+ int i;
+
+ /* wait for data */
+ if (Serial.available() > 0) {
+ ser = Serial.read();
+ switch (stat) {
+ case INIT:
+ /* sync on the last byte of the prev message */
+ if (b == END_MSG) {
+ count_geiger_1 = 0;
+ count_geiger_2 = 0;
+ volt_geiger = 0;
+ i = 0;
+ stat = FOUND_SYNC;
+ }
+ break;
+ case FOUND_SYNC:
+ if ((b <= '9') && (b >= '0')) {
+ count_geiger_1 = count_geiger_1 * 10 + (b-'0');
+ if (++i > 7) state = IDLE;
+ } else if (b == ',')) {
+ i = 0;
+ stat = FOUND_1;
+ } else stat = INIT;
+ break;
+ case FOUND_1:
+ /* read counter 1 */
+ if ((b <= '9') && (b >= '0')) {
+ count_geiger_2 = count_geiger_2 * 10 + (b-'0');
+ if (++i > 7) state = IDLE;
+ } else if (b == ',')) {
+#ifdef DEBUG
+ Serial.println(count_geiger_1, DEC);
+#endif
+ i = 0;
+ stat = FOUND_2;
+ } else stat = INIT;
+ break;
+ case FOUND_2:
+ /* read counter 2 */
+ if ((b <= '9') && (b >= '0')) {
+ count_geiger_2 = count_geiger_2 * 10 + (b-'0');
+ if (++i > 7) state = IDLE;
+ } else if (b == ',')) {
+#ifdef DEBUG
+ Serial.println(count_geiger_2, DEC);
+#endif
+ i = 0;
+ stat = FOUND_3;
+ } else stat = INIT;
+ break;
+ case FOUND_3:
+ /* ignore 3 */
+ if ((b <= '9') && (b >= '0')) {
+ if (++i > 7) state = IDLE;
+ } else if (b == ',')) {
+ i = 0;
+ stat = FOUND_4;
+ } else stat = INIT;
+ break;
+ case FOUND_4:
+ /* ignore 4 */
+ if ((b <= '9') && (b >= '0')) {
+ if (++i > 7) state = IDLE;
+ } else if (b == ',')) {
+ i = 0;
+ stat = FOUND_5;
+ } else stat = INIT;
+ break;
+ case FOUND_5:
+ /* read voltage */
+ if ((b <= '9') && (b >= '0')) {
+ volt_geiger = volt_geiger * 10 + (b-'0');
+ if (++i > 7) state = IDLE;
+ } else if (b == 'V')) {
+ digitalWrite(LED_GR_PIN, HIGH);
+#ifdef DEBUG
+ Serial.println(volt_geiger, DEC);
+#endif
+ received_data = 0;
+ stat = INIT;
+ } else stat = INIT;
+ break;
+ default:
+ stat = INIT;
+ }
+ }
+}
+
diff --git a/sw/airborne/modules/meteo/geiger_counter.c b/sw/airborne/modules/meteo/geiger_counter.c
new file mode 100644
index 00000000000..3c98c238a74
--- /dev/null
+++ b/sw/airborne/modules/meteo/geiger_counter.c
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2011 Martin Mueller
+ *
+ * This file is part of paparazzi.
+ *
+ * paparazzi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * paparazzi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with paparazzi; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/** \file geiger_counter.c
+ * \brief I2C interface for University of Reading Geiger counter
+ *
+ */
+
+#include "modules/meteo/geiger_counter.h"
+#include "mcu_periph/i2c.h"
+#include "mcu_periph/uart.h"
+#include "messages.h"
+#include "downlink.h"
+
+#ifndef DOWNLINK_DEVICE
+#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE
+#endif
+
+#ifndef GEIGER_CNT_DEV
+#define GEIGER_CNT_DEV i2c0
+#endif
+
+#define GEIGER_CNT_I2C_ADDR 0x76
+
+struct i2c_transaction geiger_trans;
+uint32_t count_geiger_1, count_geiger_2;
+uint16_t volt_geiger;
+
+void geiger_counter_init( void ) {
+}
+
+void geiger_counter_periodic( void ) {
+ I2CReceive(GEIGER_CNT_DEV, geiger_trans, GEIGER_CNT_I2C_ADDR, 10);
+}
+
+void geiger_counter_event( void ) {
+ if (geiger_trans.status == I2CTransSuccess) {
+ count_geiger_1 = (geiger_trans.buf[3] << 24) |
+ (geiger_trans.buf[2] << 16) |
+ (geiger_trans.buf[1] << 8) |
+ (geiger_trans.buf[0]);
+ count_geiger_2 = (geiger_trans.buf[7] << 24) |
+ (geiger_trans.buf[6] << 16) |
+ (geiger_trans.buf[5] << 8) |
+ (geiger_trans.buf[4]);
+ volt_geiger = (geiger_trans.buf[9] << 8) |
+ (geiger_trans.buf[8]);
+ geiger_trans.status = I2CTransDone;
+
+ if (volt_geiger & 0x8000) {
+ volt_geiger &= 0x7FFF;
+ DOWNLINK_SEND_GEIGER_COUNTER(DefaultChannel,
+ &count_geiger_1, &count_geiger_2, &volt_geiger);
+ }
+ }
+}
diff --git a/sw/airborne/modules/meteo/geiger_counter.h b/sw/airborne/modules/meteo/geiger_counter.h
new file mode 100644
index 00000000000..cbc900708d6
--- /dev/null
+++ b/sw/airborne/modules/meteo/geiger_counter.h
@@ -0,0 +1,11 @@
+#ifndef GEIGER_COUNTER_H
+#define GEIGER_COUNTER_H
+
+#include "std.h"
+
+void geiger_counter_init(void);
+void geiger_counter_periodic(void);
+void geiger_counter_event(void);
+
+#endif
+