Paparazzi UAS  v5.15_devel-112-g521f3cf
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
temp_adc.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Eduardo Lavratti <agressiva@hotmail.com>
3  *
4  * This file is part of paparazzi
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
26 #include "std.h"
28 #include "mcu_periph/adc.h"
29 #include "mcu_periph/uart.h"
30 #include "pprzlink/messages.h"
32 #include BOARD_CONFIG
33 
34 bool temp_adc_sync_send = false;
35 static float temp_c1, temp_c2, temp_c3;
36 
37 float get_temp(uint8_t nr) {
38  switch(nr) {
39  case 1:
40  return temp_c1;
41  case 2:
42  return temp_c2;
43  case 3:
44  return temp_c3;
45  default:
46  return 0.0f;
47  }
48 }
49 
50 
51 #if PERIODIC_TELEMETRY
53 #endif
54 
55 #define LM35 0
56 #define NTC 1
57 
58 #ifndef TEMP_ADC_CHANNEL1
59 #ifndef TEMP_ADC_CHANNEL2
60 #ifndef TEMP_ADC_CHANNEL3
61 #error "at least one TEMP_ADC_CHANNEL1/2/3 needs to be defined to use the temp_adc module"
62 #endif
63 #endif
64 #endif
65 
66 #ifdef TEMP_ADC_CHANNEL1
67 static struct adc_buf temp_buf1;
68 
69 #ifndef TEMP_ADC_CHANNEL1_TYPE
70 #define TEMP_ADC_CHANNEL1_TYPE LM35
71 #endif
72 #endif
73 
74 #ifdef TEMP_ADC_CHANNEL2
75 static struct adc_buf temp_buf2;
76 
77 #ifndef TEMP_ADC_CHANNEL2_TYPE
78 #define TEMP_ADC_CHANNEL2_TYPE LM35
79 #endif
80 #endif
81 
82 #ifdef TEMP_ADC_CHANNEL3
83 static struct adc_buf temp_buf3;
84 
85 #ifndef TEMP_ADC_CHANNEL3_TYPE
86 #define TEMP_ADC_CHANNEL3_TYPE LM35
87 #endif
88 #endif
89 
90 #ifndef TEMP_ADC_NB_SAMPLES
91 #define TEMP_ADC_NB_SAMPLES DEFAULT_AV_NB_SAMPLE
92 #endif
93 
97 #ifndef TEMP_ADC_SYNC_SEND
98 #define TEMP_ADC_SYNC_SEND FALSE
99 #endif
100 
104 static inline float calc_ntc(int16_t raw_adc, uint16_t pull_up_r, float a, float b, float c)
105 {
106  // Calculate the logaritmic resistance value based on the Pull up resistor
107  float log_r = log((pull_up_r * raw_adc) / (ADC_RESOLUTION - raw_adc));
108 
109  // Steinhart equation (https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation)
110  // 1 / T = a + b*len(R) + c*ln(R)³
111  float temp_c = 1 / (a + (b * log_r) + (c * log_r * log_r * log_r));
112  temp_c = temp_c - 273.15; // Convert do celcius
113  return temp_c;
114 }
115 
116 static inline float calc_lm35(int16_t raw_temp)
117 {
118  return ((float)raw_temp * (3300.0f / 1024.0f) / 10.0f);
119 }
120 
121 static void temp_adc_downlink(struct transport_tx *trans, struct link_device *dev)
122 {
123  pprz_msg_send_TEMP_ADC(trans, dev, AC_ID, &temp_c1, &temp_c2, &temp_c3);
124 }
125 
129 void temp_adc_init(void)
130 {
132 
133 #ifdef TEMP_ADC_CHANNEL1
135 #endif
136 
137 #ifdef TEMP_ADC_CHANNEL2
139 #endif
140 
141 #ifdef TEMP_ADC_CHANNEL3
142  adc_buf_channel(TEMP_ADC_CHANNEL3, &temp_buf3, TEMP_ADC_NB_SAMPLES);
143 #endif
144 
145 #if PERIODIC_TELEMETRY
147 #endif
148 }
149 
150 
152 {
153  uint16_t adc_raw;
154 
155 #ifdef TEMP_ADC_CHANNEL1
156  adc_raw = temp_buf1.sum / temp_buf1.av_nb_sample;
157 #if TEMP_ADC_CHANNEL1_TYPE == LM35
158  temp_c1 = calc_lm35(adc_raw);
159 #elif TEMP_ADC_CHANNEL1_TYPE == NTC
162 #endif
163 #endif
164 
165 #ifdef TEMP_ADC_CHANNEL2
166  adc_raw = temp_buf2.sum / temp_buf2.av_nb_sample;
167 #if TEMP_ADC_CHANNEL2_TYPE == LM35
168  temp_c2 = calc_lm35(adc_raw);
169 #elif TEMP_ADC_CHANNEL2_TYPE == NTC
172 #endif
173 #endif
174 
175 #ifdef TEMP_ADC_CHANNEL3
176  adc_raw = temp_buf3.sum / temp_buf3.av_nb_sample;
177 #if TEMP_ADC_CHANNEL3_TYPE == LM35
178  temp_c3 = calc_lm35(adc_raw);
179 #elif TEMP_ADC_CHANNEL3_TYPE == NTC
180  temp_c3 = calc_ntc(adc_raw, TEMP_ADC_CHANNEL3_PU_R,
181  TEMP_ADC_CHANNEL3_A, TEMP_ADC_CHANNEL3_B, TEMP_ADC_CHANNEL3_C);
182 #endif
183 #endif
184 
185  /* Send measurements as soon as they are calculated */
186  if (temp_adc_sync_send) {
187  temp_adc_downlink(&(DefaultChannel).trans_tx, &(DefaultDevice).device);
188  }
189 }
#define TEMP_ADC_NB_SAMPLES
Definition: temp_adc.c:91
unsigned short uint16_t
Definition: types.h:16
#define ADC_RESOLUTION
Definition: adc_arch.h:37
#define TEMP_ADC_CHANNEL1_PU_R
Definition: opa_ap_1.0.h:214
static float calc_ntc(int16_t raw_adc, uint16_t pull_up_r, float a, float b, float c)
Calculate the NTC tempreature in celcius based on the Steinhart equation.
Definition: temp_adc.c:104
#define TEMP_ADC_CHANNEL2_B
Definition: opa_ap_1.0.h:230
float get_temp(uint8_t nr)
Definition: temp_adc.c:37
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
static float temp_c1
Definition: temp_adc.c:35
Periodic telemetry system header (includes downlink utility and generated code).
void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
Link between ChibiOS ADC drivers and Paparazzi adc_buffers.
Definition: adc_arch.c:281
arch independent ADC (Analog to Digital Converter) API
static float calc_lm35(int16_t raw_temp)
Definition: temp_adc.c:116
Generic interface for all ADC hardware drivers, independent from microcontroller architecture.
Definition: adc.h:53
#define TEMP_ADC_CHANNEL2_PU_R
Definition: opa_ap_1.0.h:228
static void temp_adc_downlink(struct transport_tx *trans, struct link_device *dev)
Definition: temp_adc.c:121
signed short int16_t
Definition: types.h:17
void temp_adc_periodic(void)
Definition: temp_adc.c:151
static float temp_c3
Definition: temp_adc.c:35
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:73
#define TEMP_ADC_CHANNEL2
Definition: opa_ap_1.0.h:226
#define TEMP_ADC_CHANNEL2_A
Definition: opa_ap_1.0.h:229
static float temp_c2
Definition: temp_adc.c:35
unsigned char uint8_t
Definition: types.h:14
#define TEMP_ADC_CHANNEL1_C
Definition: opa_ap_1.0.h:217
bool temp_adc_sync_send
Definition: temp_adc.c:34
temperature driver for LM35 and 100k NTC analog sensores
#define TEMP_ADC_CHANNEL2_C
Definition: opa_ap_1.0.h:231
void temp_adc_init(void)
Temperature ADC initialize channels.
Definition: temp_adc.c:129
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:46
#define TEMP_ADC_CHANNEL1_A
Definition: opa_ap_1.0.h:215
#define TEMP_ADC_CHANNEL1
Definition: opa_ap_1.0.h:212
#define TEMP_ADC_CHANNEL1_B
Definition: opa_ap_1.0.h:216
#define TEMP_ADC_SYNC_SEND
Send a TEMP_ADC message with every new measurement.
Definition: temp_adc.c:98