Bienvenue sur le blog de GreenRbot
mon robot tondeuse de 2ème génération.
Ma précédente réalisation, SyLaM, était un robot tondeuse entièrement réalisé à partir de matériel de récupération. Malheureusement, les moteurs, issus des essuie-glaces d'une Toyota Corolla, n'étaient pas assez puissant pour ma pelouse, ou devrais-je dire mon pré.
De plus, le processeur, un PIC 16F84 n'offrait pas la puissance de calcul suffisante à l'algorithme de tonte parallèle que je voulais intégrer.
Vous pourrez voir la description de SyLaM à l'adresse suivante : http://sylam.blogspirit.com/
GreenRbot, offre une motorisation plus puissante, et le processeur central est un classique PIC 16F877.
Pour GreenRbot, j'ai renoncé à fabriquer tous mes capteurs à partir de composant récupérés. Mon premier achat a été 2 capteurs Sharp IR.
Vous trouverez ci-dessous le petit bout de logiciel qui m'a servi à valider le principe. Le logiciel est écrit pour le compilateur CCS.
J'ai fait le test en intérieur, reste à valider à l'extérieur si des variations d'ensoleillement n'influent pas trop sur les mesures.
* Pour affichage GP2YOA02 en cm
****************************************************************************/
#include <16f877.h>
#fuses HS,NOPROTECT,NOWDT,BROWNOUT,PUT,NOLVP
#ORG 0x1F00,0x1FFF {} /* Reserve memory for bootloader for the 8k 16F876/7 */
#device PIC16F877 *=16 /* Allow RAM to expand beyond 256 bytes */
#device adc=10 /* Make sure that we are sampling on 10 bits. This directive
is required for compiler version 2.7. */
/* Set the clock speed */
#use delay(clock=20000000)
/* Directive for RS-232 interface */
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
/* Definitions */
/* Analog channel definitions */
#define ADC_DELAY 20 /* Delay in microseconds */
#define DISTANCE_ANCH 4 /* Port A5/AN4 */
/* IR calibration data */
#define IR_DISTANCE_BASE 10
#define IR_DISTANCE_STEP 2
#define NUM_IR_CALIB_DATA 31
/* Type definitions */
typedef int uint8_t;
typedef long uint16_t;
/* Public interface */
void main(void);
void init_pins(void);
void init(void);
void display_ir_distance(void);
/* IR sensor interface */
uint8_t get_ir_distance(uint8_t ir_reading);
void monitor_ir_distance_sensor(void);
/* Variable definitions */
static const uint8_t ir_calib_data[NUM_IR_CALIB_DATA] = {
124, 107, 93, 83, 75, 67, 62, 57, 53, 49, 47, 44, 42, 39, 38, 36,
34, 33, 32, 30, 29, 28, 27, 26, 25, 25, 24, 23, 23, 22, 21
};
uint8_t distance = 0xff;
/*****************************************************************************
* Init hardware pins: Set up the TRIS, set up analog ports, set the
* pins to their default values.
****************************************************************************/
void
init_pins(void) {
/* Set up the various pins in/out */
set_tris_a(0b00100000); /* Pin A5 is input. Rest is not used. */
set_tris_b(0b00000000); /* Port B is not used. */
set_tris_c(0b10000000); /* C6 is output. C7 is input. Rest is not used. */
set_tris_d(0b00000000); /* Port D is not used. */
set_tris_e(0b00000000); /* Port E is not used. */
} /* init_pins */
/*****************************************************************************
* Board initialization. Initialize pins.
****************************************************************************/
void
init(void) {
init_pins();
} /* init */
/*****************************************************************************
* This is the main control loop.
****************************************************************************/
void
main(void) {
char c;
init();
printf("ADC Demornrn");
for ( ; ; ) {
printf("press key to get ADC value: ");
for ( ; ; ) {
if (kbhit())
break;
c = getc();
printf("rn");
monitor_ir_distance_sensor();
display_ir_distance();
}
}
} /* main */
void
display_ir_distance(void) {
printf("distance = %3u cm n", distance);
} /* display_status */
/* IR sensor implementation */
/*
* get_ir_distance
*
* Determine distance in cm based in the A/D value and the calibration table.
*
* Parameters:
* ir_reading (IN) - A/D value for the IR sensor
*/
uint8_t
get_ir_distance(uint8_t ir_reading) {
int i;
for (i = 0; i < NUM_IR_CALIB_DATA; i++) {
if (ir_calib_data[i] < ir_reading) {
return IR_DISTANCE_BASE + i * IR_DISTANCE_STEP;
}
}
return IR_DISTANCE_BASE + (i - 1) * IR_DISTANCE_STEP;
} /* get_ir_distance */
/*****************************************************************************
* This function monitors the IR distance sensor.
* This function updates the distance global variable.
****************************************************************************/
void
monitor_ir_distance_sensor(void) {
uint16_t value;
/* Read ADC for left sensor */
setup_adc_ports(A_ANALOG);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(DISTANCE_ANCH); /* Read Port A5/AN4 */
delay_us(ADC_DELAY);
value = Read_ADC();
setup_adc(ADC_OFF);
value >>= 2;
distance = get_ir_distance(value);
} /* monitor_ir_distance_sensor */
Aucun commentaire pour cet article
Commentaires