Add University of Reading Geiger-Mueller counter.

This commit is contained in:
Martin Mueller
2011-07-22 17:31:19 +02:00
parent df54ababd7
commit 813eee7a8e
5 changed files with 279 additions and 1 deletions
+6 -1
View File
@@ -1165,7 +1165,12 @@
</message>
<!--152 is free -->
<!--153 is free -->
<message name="GEIGER_COUNTER" id="153">
<field name="tube1" type="uint32" unit="events"/>
<field name="tube2" type="uint32" unit="events"/>
<field name="vsupply" type="uint16" unit="volts"/>
</message>
<message name="INS_REF" id="154">
<field name="ecef_x0" type="int32" alt_unit="m" alt_unit_coef="0.01"/>
+14
View File
@@ -0,0 +1,14 @@
<!DOCTYPE module SYSTEM "module.dtd">
<module name="geiger_counter" dir="meteo">
<header>
<file name="geiger_counter.h"/>
</header>
<init fun="geiger_counter_init()"/>
<periodic fun="geiger_counter_periodic()" freq="1"/>
<event fun="geiger_counter_event()"/>
<makefile target="ap">
<file name="geiger_counter.c"/>
</makefile>
</module>
@@ -0,0 +1,171 @@
/*
* $Id$
*
* Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
*
* 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 <Wire.h>
#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;
}
}
}
@@ -0,0 +1,77 @@
/*
* $Id$
*
* Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
*
* 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);
}
}
}
@@ -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