33#define SIDE_WALL_DETECTION (CELL_DIMENSION * 0.90)
44#define FRONT_WALL_DETECTION (CELL_DIMENSION * 1.5)
55#define SIDE_CALIBRATION_READINGS 20
6- #define SENSORS_SM_TICKS 4
76
87static volatile uint16_t sensors_off [NUM_SENSOR ], sensors_on [NUM_SENSOR ];
98static volatile float distance [NUM_SENSOR ];
@@ -15,7 +14,6 @@ const float sensors_calibration_b[NUM_SENSOR] = {
1514 SENSOR_SIDE_LEFT_B , SENSOR_SIDE_RIGHT_B , SENSOR_FRONT_LEFT_B ,
1615 SENSOR_FRONT_RIGHT_B };
1716
18- static void sm_emitter_adc (void );
1917static void set_emitter_on (uint8_t emitter );
2018static void set_emitter_off (uint8_t emitter );
2119
@@ -70,75 +68,66 @@ static void set_emitter_off(uint8_t emitter)
7068}
7169
7270/**
73- * @brief State machine to manage the sensors activation and deactivation
74- * states and readings.
75- *
76- * In order to get accurate distance values, the phototransistor's output
77- * will be read with the infrared emitter sensors powered on and powered
78- * off. Besides, to avoid undesired interactions between different emitters and
79- * phototranistors, the reads will be done one by one.
80- *
81- * The battery voltage is also read on the state 1.
82- *
83- * - State 1 (first because the emitter is OFF on start):
84- * -# Save phototranistors sensors (ADC1) from emitter OFF and
85- * power ON the emitter.
86- * - State 2:
87- * -# Start the phototranistors sensors (ADC1) read.
88- * - State 3:
89- * -# Save phototranistors sensors (ADC1) from emitter ON and
90- * power OFF the emitter.
91- * - State 4:
92- * -# Start the phototranistors sensors (ADC1) read.
71+ * @brief Get sensors values with emitter on and off.
9372 */
94- static void sm_emitter_adc ( void )
73+ void get_sensors_raw ( uint16_t * off , uint16_t * on )
9574{
96- static uint8_t emitter_status = 1 ;
97- static uint8_t sensor_index = SENSOR_SIDE_LEFT_ID ;
75+ uint8_t i = 0 ;
9876
99- switch (emitter_status ) {
100- case 1 :
101- sensors_off [sensor_index ] =
102- adc_read_injected (ADC1 , (sensor_index + 1 ));
103- set_emitter_on (sensor_index );
104- emitter_status = 2 ;
105- break ;
106- case 2 :
107- adc_start_conversion_injected (ADC1 );
108- emitter_status = 3 ;
109- break ;
110- case 3 :
111- sensors_on [sensor_index ] =
112- adc_read_injected (ADC1 , (sensor_index + 1 ));
113- set_emitter_off (sensor_index );
114- emitter_status = 4 ;
115- break ;
116- case 4 :
117- adc_start_conversion_injected (ADC1 );
118- emitter_status = 1 ;
119- if (sensor_index == (NUM_SENSOR - 1 ))
120- sensor_index = 0 ;
121- else
122- sensor_index ++ ;
123- break ;
124- default :
125- break ;
77+ for (i = 0 ; i < NUM_SENSOR ; i ++ ) {
78+ off [i ] = sensors_off [i ];
79+ on [i ] = sensors_on [i ];
12680 }
12781}
12882
12983/**
130- * @brief Get sensors values with emitter on and off .
84+ * @brief Update the sensors raw readings .
13185 */
132- void get_sensors_raw (uint16_t * off , uint16_t * on )
86+ static void inject_readings (void )
87+ {
88+ adc_start_conversion_injected (ADC1 );
89+ while (!(adc_eoc_injected (ADC1 )))
90+ ;
91+ // Clear injected end of conversion
92+ ADC_SR (ADC1 ) &= ~ADC_SR_JEOC ;
93+ }
94+
95+ /**
96+ * @brief Update the sensors raw readings.
97+ */
98+ static void update_raw_readings (void )
13399{
134100 uint8_t i = 0 ;
135101
102+ inject_readings ();
103+ for (i = 0 ; i < NUM_SENSOR ; i ++ )
104+ sensors_off [i ] = adc_read_injected (ADC1 , (i + 1 ));
105+
136106 for (i = 0 ; i < NUM_SENSOR ; i ++ ) {
137- off [i ] = sensors_off [i ];
138- on [i ] = sensors_on [i ];
107+ set_emitter_on (i );
108+ sleep_us (10 );
109+ inject_readings ();
110+ sensors_on [i ] = adc_read_injected (ADC1 , (i + 1 ));
111+ set_emitter_off (i );
139112 }
140113}
141114
115+ /**
116+ * @brief Apply `log()` to a raw sensor difference reading.
117+ *
118+ * - Deals with invalid (non-positive) values.
119+ * - For very low values of `diff` it returns `1`.
120+ * - Never returns `0` to avoid division by zero in `update_distance_readings`.
121+ *
122+ * @param[in] diff Raw sensor reading: "on" raw value minus "off" raw value.
123+ */
124+ static float raw_log (uint16_t diff )
125+ {
126+ if (diff <= 10 )
127+ return 1. ;
128+ return log ((float )diff );
129+ }
130+
142131/**
143132 * @brief Calculate and update the distance from each sensor.
144133 *
@@ -148,11 +137,11 @@ void update_distance_readings(void)
148137{
149138 uint8_t i = 0 ;
150139
140+ update_raw_readings ();
151141 for (i = 0 ; i < NUM_SENSOR ; i ++ ) {
152- distance [i ] =
153- (sensors_calibration_a [i ] /
154- log ((float )(sensors_on [i ] - sensors_off [i ])) -
155- sensors_calibration_b [i ]);
142+ distance [i ] = (sensors_calibration_a [i ] /
143+ raw_log (sensors_on [i ] - sensors_off [i ]) -
144+ sensors_calibration_b [i ]);
156145 if ((i == SENSOR_SIDE_LEFT_ID ) || (i == SENSOR_SIDE_RIGHT_ID ))
157146 distance [i ] -= calibration_factor [i ];
158147 }
@@ -290,7 +279,7 @@ void side_sensors_calibration(void)
290279 for (i = 0 ; i < SIDE_CALIBRATION_READINGS ; i ++ ) {
291280 left_temp += distance [SENSOR_SIDE_LEFT_ID ];
292281 right_temp += distance [SENSOR_SIDE_RIGHT_ID ];
293- sleep_ticks (SENSORS_SM_TICKS );
282+ sleep_ticks (2 );
294283 }
295284 calibration_factor [SENSOR_SIDE_LEFT_ID ] +=
296285 (left_temp / SIDE_CALIBRATION_READINGS ) - MIDDLE_MAZE_DISTANCE ;
0 commit comments