Permalink
Browse files

Merge pull request #128 from sittner/add-adc-voltagesupport

ADC cleanup / add voltage readout support
  • Loading branch information...
2 parents 6a389f1 + a470346 commit 95dd679f96426f52e082c413904fc156e8363417 Erik Kunze committed Mar 28, 2012
View
@@ -8,14 +8,12 @@ divert(globals_divert)
#ifndef ADC_SUPPORT
#error Please define adc support
#endif
+
+#include "hardware/adc/adc.h"
+
static uint16_t
control6_get_adc(uint8_t sensorchannel){
- ADMUX = (ADMUX & 0xF0) | sensorchannel;
- /* Start der adc konvertierung */
- ADCSRA |= _BV(ADSC);
- /* Warten bis sie fertig ist */
- while (ADCSRA & _BV(ADSC)) {}
- return ADC;
+ return adc_get(sensorchannel);
}
divert(old_divert)')')
View
@@ -115,6 +115,10 @@ eeprom_init (void)
eeprom_save_P (pam_password, PSTR (PAM_SINGLE_PASSWORD), 16);
#endif
+#ifdef ADC_VOLTAGE_SUPPORT
+ eeprom_save_int (adc_vref, ADC_REF_VOLTAGE);
+#endif
+
#ifdef KTY_SUPPORT
eeprom_save_char (kty_calibration, 0);
#endif
View
@@ -53,6 +53,10 @@
#include "services/dmx-fxslot/dmx-fxslot.h"
#endif
+#ifdef ADC_VOLTAGE_SUPPORT
+#include "hardware/adc/adc.h"
+#endif
+
struct eeprom_config_t
{
#ifdef ETHERNET_SUPPORT
@@ -82,6 +86,10 @@ struct eeprom_config_t
char pam_password[16];
#endif
+#ifdef ADC_VOLTAGE_SUPPORT
+ uint16_t adc_vref;
+#endif
+
#ifdef KTY_SUPPORT
int8_t kty_calibration;
#endif
View
@@ -301,12 +301,17 @@ PS2_GERMAN_LAYOUT
ADC input
ADC_SUPPORT
- Depends on:
- * ECMD support (ECMD_PARSER_SUPPORT)
-
Enable ADC abstraction layer. This especially enables a further
ECMD 'adc get' which triggers a ADC conversion for each channel
- and returns the gained values.
+ and returns the gained values (if ECMD support is enabled).
+
+ADC voltage support
+ADC_VOLTAGE_SUPPORT
+ Depends on:
+ * ADC input (ADC_SUPPORT)
+
+ Enables the direct readout of ADC in volt. A VREF calibration value
+ can be set by ECMD and is stored in EEPROM.
FS20 RF-control
FS20_SUPPORT
View
@@ -9,6 +9,10 @@
<link rel="stylesheet" href="Sty.c" type="text/css"/>
<script src="scr.js" type="text/javascript"></script>
<script type="text/javascript">
+#ifdef ADC_VOLTAGE_SUPPORT
+var vref;
+#endif
+
function ecmd_adc_req() {
ArrAjax.ecmd('adc get', ecmd_adc_req_handler);
}
@@ -22,20 +26,40 @@ function ecmd_adc_req_handler(request, data) {
if (isNaN(value))
continue;
var graph = $('adc_graph' + i);
- graph.style.width = (value * 100 /1023.0) + "%";
+ graph.style.width = (value * 100 / 1023.0) + "%";
graph.innerHTML = (value != 0) ? "&nbsp;" : "";
var data = $('adc_data' + i);
+#ifdef ADC_VOLTAGE_SUPPORT
+ data.innerHTML = (value * 100 / 1023).toFixed(2) + "% (" + (value / 1023.0 * vref).toFixed(3) + "V)";
+#else
data.innerHTML = (value * 100 / 1023).toFixed(2) + "% (" + value + ")";
+#endif
}
}
+#ifdef ADC_VOLTAGE_SUPPORT
+function ecmd_adc_vref_req() {
+ ArrAjax.ecmd('adc vref', ecmd_adc_vref_req_handler);
+}
+
+function ecmd_adc_vref_req_handler(request, data) {
+ vref = parseFloat(request.responseText) / 1000;
+ ecmd_adc_req();
+ setInterval('ecmd_adc_req()', 5000);
+}
+#endif
+
window.onload = function() {
var adc_table = $("adc_table");
for (var i = 0; i < ADC_CHANNELS; i++) {
adc_table.insertRow(i).innerHTML = '<td>Kanal ' + i +' </td><td class="adc_graph"><div id="adc_graph'+i+'"></div></td><td class="adc_data" id="adc_data'+i+'"></td>';
}
+#ifdef ADC_VOLTAGE_SUPPORT
+ ecmd_adc_vref_req();
+#else
ecmd_adc_req();
setInterval('ecmd_adc_req()', 5000);
+#endif
}
</script>
</head><body>
View
@@ -171,14 +171,6 @@ main (void)
wdt_disable ();
#endif //USE_WATCHDOG
-#if defined(ADC_SUPPORT) || defined(ADC_LIGHT)
- /* ADC Prescaler to 64 */
- ADCSRA = _BV (ADEN) | _BV (ADPS2) | _BV (ADPS1);
- /* ADC set Voltage Reference to extern */
- /* FIXME: move config to the right place */
- ADMUX = ADC_REF; //_BV(REFS0) | _BV(REFS1);
-#endif
-
#if defined(RFM12_SUPPORT) || defined(ENC28J60_SUPPORT) \
|| defined(DATAFLASH_SUPPORT)
spi_init ();
View
@@ -1,9 +1,10 @@
TOPDIR ?= ../..
include $(TOPDIR)/.config
-ifeq ($(ECMD_PARSER_SUPPORT),y)
- $(ADC_SUPPORT)_ECMD_SRC += hardware/adc/adc.c
-endif
+$(ADC_LIGHT)_SRC += hardware/adc/adc.c
+
+$(ADC_SUPPORT)_SRC += hardware/adc/adc.c
+$(ADC_SUPPORT)_ECMD_SRC += hardware/adc/adc_ecmd.c
$(HR20_TEMP_SUPPORT)_SRC += hardware/adc/hr20-temp.c
$(HR20_TEMP_SUPPORT)_SRC += hardware/adc/hr20-batt.c
View
@@ -3,6 +3,7 @@
* Copyright (c) by Alexander Neumann <alexander@bumpern.de>
* Copyright (c) 2007 by Stefan Siegl <stesie@brokenpipe.de>
* Copyright (c) 2007 by Christian Dietrich <stettberger@dokucode.de>
+ * Copyright (c) 2012 by Sascha Ittner <sascha.ittner@modusoft.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (either version 2 or
@@ -21,55 +22,92 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include <string.h>
-#include <avr/pgmspace.h>
+#include <avr/io.h>
-#include "config.h"
-#include "core/debug.h"
+#include "adc.h"
-#include "protocols/ecmd/ecmd-base.h"
-
-
-#define NIBBLE_TO_HEX(a) ((a) < 10 ? (a) + '0' : ((a) - 10 + 'A'))
+#ifdef ADC_VOLTAGE_SUPPORT
+#include "core/eeprom.h"
+#endif /* ADC_VOLTAGE_SUPPORT */
#ifndef ADC_REF
#define ADC_REF 0
#endif
-int16_t parse_cmd_adc_get(char *cmd, char *output, uint16_t len)
+uint8_t last_ref;
+
+#ifdef ADC_VOLTAGE_SUPPORT
+uint16_t vref;
+#endif /* ADC_VOLTAGE_SUPPORT */
+
+void
+adc_init(void)
{
- uint16_t adc;
- uint8_t channel;
- uint8_t ret = 0;
- if (cmd[0] && cmd[1]) {
- if ( (cmd[1] - '0') < ADC_CHANNELS) {
- ADMUX = (ADMUX & 0xF0) | (cmd[1] - '0') | ADC_REF;
- channel = ADC_CHANNELS;
- goto adc_out;
- } else
- return ECMD_ERR_PARSE_ERROR;
- }
- for (channel = 0; channel < ADC_CHANNELS; channel ++) {
- ADMUX = (ADMUX & 0xF0) | channel | ADC_REF;
-adc_out:
- /* Start adc conversion */
+ /* ADC Prescaler to 64 */
+ ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1);
+
+ /* init reference */
+ ADMUX = ADC_REF;
+ last_ref = 0xff;
+
+#ifdef ADC_VOLTAGE_SUPPORT
+ eeprom_restore_int(adc_vref, &vref);
+#endif
+}
+
+uint16_t
+adc_get_setref(uint8_t ref, uint8_t channel)
+{
+ /* select reference and channel */
+ ADMUX = (ref & 0xc0) | (channel & 0x1f);
+ if (last_ref != ref)
+ {
ADCSRA |= _BV(ADSC);
- /* Wait for completion of adc */
- while (ADCSRA & _BV(ADSC)) {}
- adc = ADC;
- output[0] = NIBBLE_TO_HEX((adc >> 8) & 0x0F);
- output[1] = NIBBLE_TO_HEX((adc >> 4) & 0x0F);
- output[2] = NIBBLE_TO_HEX(adc & 0x0F);
- output[3] = ' ';
- output[4] = 0;
- ret += 4;
- output += 4;
+ loop_until_bit_is_clear(ADCSRA, ADSC);
+ last_ref = ref;
}
- return ECMD_FINAL(ret);
+
+ /* Start adc conversion */
+ ADCSRA |= _BV(ADSC);
+ /* Wait for completion of adc */
+ loop_until_bit_is_clear(ADCSRA, ADSC);
+
+ return ADC;
}
+#ifdef ADC_VOLTAGE_SUPPORT
+
+uint16_t
+adc_get_voltage_setref(uint8_t ref, uint8_t channel)
+{
+ return adc_raw_to_voltage(adc_get_setref(ref, channel));
+}
+
+uint16_t
+adc_raw_to_voltage(uint16_t raw)
+{
+ return ((float) vref * (float) raw * ADC_RES_RECIEP);
+}
+
+uint16_t
+adc_get_vref()
+{
+ return vref;
+}
+
+void
+adc_set_vref(uint16_t value)
+{
+ vref = value;
+ eeprom_save_int(adc_vref, vref);
+ eeprom_update_chksum();
+}
+
+#endif /* ADC_VOLTAGE_SUPPORT */
+
/*
-- Ethersex META --
block(Analog/Digital Conversion ([[ADC]]))
- ecmd_feature(adc_get, "adc get", [CHANNEL], Get the ADC value in hex of CHANNEL or if no channel set of all channels.)
+ header(hardware/adc/adc.h)
+ init(adc_init)
*/
View
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright (c) by Alexander Neumann <alexander@bumpern.de>
+ * Copyright (c) 2007 by Stefan Siegl <stesie@brokenpipe.de>
+ * Copyright (c) 2007 by Christian Dietrich <stettberger@dokucode.de>
+ * Copyright (c) 2012 by Sascha Ittner <sascha.ittner@modusoft.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (either version 2 or
+ * version 3) as published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * For more information on the GPL, please go to:
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _ADC_H
+#define _ADC_H
+
+#include <inttypes.h>
+
+#include "config.h"
+
+#ifdef ADC_VOLTAGE_SUPPORT
+
+#if ADC_REF == ADC_2_56
+#define ADC_REF_VOLTAGE 2560
+#elif ADC_REF == ADC_1_1
+#define ADC_REF_VOLTAGE 1100
+#else
+#define ADC_REF_VOLTAGE 5000
+#endif
+
+#define ADC_RES_RECIEP (1.0F / 1023.0F)
+
+#define adc_get_voltage(x) adc_get_voltage_setref(ADC_REF,x)
+
+#endif /*ADC_VOLTAGE_SUPPORT */
+
+#define adc_get(x) adc_get_setref(ADC_REF,x)
+
+void adc_init(void);
+uint16_t adc_get_setref(uint8_t ref, uint8_t channel);
+
+int16_t parse_cmd_adc_get(char *cmd, char *output, uint16_t len);
+
+#ifdef ADC_VOLTAGE_SUPPORT
+uint16_t adc_get_voltage_setref(uint8_t ref, uint8_t channel);
+uint16_t adc_raw_to_voltage(uint16_t raw);
+uint16_t adc_get_vref();
+void adc_set_vref(uint16_t value);
+
+int16_t parse_cmd_adc_vget(char *cmd, char *output, uint16_t len);
+int16_t parse_cmd_adc_vref(char *cmd, char *output, uint16_t len);
+
+#endif /*ADC_VOLTAGE_SUPPORT */
+
+#endif /* _ADC_H */
Oops, something went wrong.

0 comments on commit 95dd679

Please sign in to comment.