From f4d29f0c30e8af182de049f06ef3ef939f255309 Mon Sep 17 00:00:00 2001 From: Jérémy Dufour Date: Thu, 27 Mar 2008 23:38:26 +0100 Subject: * digital/io/src - add sharp module with hysteresis support. --- digital/io/src/Makefile | 4 +- digital/io/src/sharp.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++ digital/io/src/sharp.h | 109 ++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 digital/io/src/sharp.c create mode 100644 digital/io/src/sharp.h diff --git a/digital/io/src/Makefile b/digital/io/src/Makefile index 428f2418..1ea16d6f 100644 --- a/digital/io/src/Makefile +++ b/digital/io/src/Makefile @@ -1,7 +1,7 @@ BASE = ../../avr AVR_PROGS = io -io_SOURCES = main.c asserv.c servo.c eeprom.c trap.c -MODULES = proto uart twi +io_SOURCES = main.c asserv.c servo.c eeprom.c trap.c sharp.c +MODULES = proto uart twi utils adc CONFIGFILE = avrconfig.h # atmega8, atmega8535, atmega128... AVR_MCU = atmega128 diff --git a/digital/io/src/sharp.c b/digital/io/src/sharp.c new file mode 100644 index 00000000..1a3084a7 --- /dev/null +++ b/digital/io/src/sharp.c @@ -0,0 +1,162 @@ +/* sharp.c */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2008 Dufour Jérémy + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program 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 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ + +#include "sharp.h" + +#include "modules/adc/adc.h" /* ADC functions */ +#include "io.h" + +/** + * Cached array of raw sharp values. + */ +uint16_t sharp_values_[SHARP_NUMBER]; + +/** + * Low (0 index) and high (1 index) thresholds for interpreted sharp values. + */ +uint16_t sharp_threshold[SHARP_NUMBER][2]; + +/** + * Hysteresis. + */ +uint8_t sharp_hysteresis_[SHARP_NUMBER]; + +/** + * Hysteresis threshold. + */ +#define SHARP_HYSTERESIS_THRESHOLD 3 + +/** + * Previous sharp interpreted values. + */ +uint8_t sharp_previous_values_[SHARP_NUMBER]; + +/* Initialize sharp module. */ +void +sharp_init (void) +{ + /* Pins are in input mode by default */ + + /* ADC initialize */ + adc_init (); +} + +/* Update read data from sharps. */ +void +sharp_update (uint8_t sharp_mask) +{ + uint8_t compt; + + /* Go through the bit mask */ + for (compt = 0; compt < SHARP_NUMBER; compt++) + { + /* Check if the bit/sharp id is set */ + if (bit_is_set (sharp_mask, compt)) + { + /* Start the capture */ + adc_start (compt + 1); + /* Wait until ADC mesure is finished */ + while (!adc_checkf ()) + ; + /* Store the value */ + sharp_values_[compt] = adc_read (); + } + } +} + +/* Get raw cached data from sharps. */ +uint16_t +sharp_get_raw (uint8_t sharp_id) +{ + /* Sanity check */ + if (sharp_id < SHARP_NUMBER) + /* Return raw cached value */ + return sharp_values_[sharp_id]; + return 0; +} + +/* Configure the thresholds of a sharp. */ +void +sharp_set_threshold (uint8_t sharp_id, uint16_t low, uint16_t high) +{ + /* Sanity check */ + if (sharp_id < SHARP_NUMBER) + { + /* Set low and high threshold */ + sharp_threshold[sharp_id][0] = low; + sharp_threshold[sharp_id][1] = high; + } +} + +/* Get interpreted value from sharps. */ +uint8_t +sharp_get_interpreted (uint8_t sharp_id) +{ + uint8_t current_state; + + /* Sanity check */ + if (sharp_id < SHARP_NUMBER) + { + /* Check if sharp state is lower than the low threshold */ + if (sharp_values_[sharp_id] < sharp_threshold[sharp_id][0]) + /* Update current state seen by the sharp */ + current_state = 0; + /* Check if sharp state is higher than the high threshold */ + else if (sharp_values_[sharp_id] > sharp_threshold[sharp_id][1]) + /* Update current state seen by the sharp */ + current_state = 1; + /* In the middle */ + else + /* Return the previous value */ + return sharp_previous_values_[sharp_id]; + + /* Manage the hysteresis */ + /* Check if previous value is the current state */ + if (sharp_previous_values_[sharp_id] == current_state) + { + /* Reset hysteresis */ + sharp_hysteresis_[sharp_id] = SHARP_HYSTERESIS_THRESHOLD; + /* Return current state */ + return current_state; + } + /* Otherwise, check if this sharp value has been the same + * SHARP_HYSTERESIS_THRESHOLD times */ + else if (sharp_hysteresis_[sharp_id]-- == 0) + { + /* Current value change (for SHARP_HYSTERESIS_THRESHOLD times)! */ + /* Update previous value */ + sharp_previous_values_[sharp_id] = current_state; + /* Reset hysteresis */ + sharp_hysteresis_[sharp_id] = SHARP_HYSTERESIS_THRESHOLD; + /* Return current state */ + return current_state; + } + else + /* Return previous state */ + return sharp_previous_values_[sharp_id]; + } + /* Error */ + return 2; +} diff --git a/digital/io/src/sharp.h b/digital/io/src/sharp.h new file mode 100644 index 00000000..ef48969a --- /dev/null +++ b/digital/io/src/sharp.h @@ -0,0 +1,109 @@ +#ifndef sharp_h +#define sharp_h +/* sharp.h */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2008 Dufour Jérémy + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program 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 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ + +/** + * @file Module to control distance measuring sensors (sharp). + * They can be used to detect obstacles, for example a bot. + * It uses the Analog to Digital Converter (ADC) of the AVR to read and + * understand data from the sharp sensors. + * This module keep a value of the last read values from the sharp and update + * it when calling the correct function. + */ + +#include "common.h" /* uint*_t */ + +/** + * Number of sharps. + */ +#define SHARP_NUMBER 6 + +/** + * Front left sharp. + */ +#define SHARP_FRONT_LEFT _BV(0) + +/** + * Front right sharp. + */ +#define SHARP_FRONT_RIGHT _BV(1) + +/** + * Back left sharp. + */ +#define SHARP_BACK_LEFT _BV(2) + +/** + * Back right sharp. + */ +#define SHARP_BACK_RIGHT _BV(3) + +/** + * Low (0 index) and high (1 index) thresholds for interpreted sharp values. + */ +extern uint16_t sharp_threshold[SHARP_NUMBER][2]; + +/** + * Initialize sharp module. + */ +void sharp_init (void); + +/** + * Update read data from sharps. + * This function is blocking. To get the value you have to use the get + * function (@a sharp_get_raw). + * @param sharp_mask list of sharps (using a mask) to update. + */ +void sharp_update (uint8_t sharp_mask); + +/** + * Get raw cached data from sharps. + * It read the cached data (updated by the @a sharp_update function). + * @param sharp_id the sharp id to get raw data from. + * @return the raw data read from the sharps (0 is a non valid value). + */ +uint16_t sharp_get_raw (uint8_t sharp_id); + +/** + * Configure the thresholds of a sharp. + * @param sharp_id the sharp id to configure the thresholds. + * @param low low threshold of the sharp. + * @param high high threshold of the sharp. + */ +void sharp_set_threshold (uint8_t sharp_id, uint16_t low, uint16_t high); + +/** + * Get interpreted value from sharps. + * It is used to know if there is something in front of the sharp. + * @param sharp_id the sharp number to get interpreted value from. + * @return + * - 0 if there is nothing in front of the sharp. + * - 1 if there is something in front of the sharp; + * - other values when error occurs. + */ +uint8_t sharp_get_interpreted (uint8_t sharp_id); + +#endif /* sharp_h */ -- cgit v1.2.3