Logiciel

Vendredi 23 février 2007

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 */

Par Alain CROSET
Ecrire un commentaire - Voir les 0 commentaires - Recommander
Lundi 5 mars 2007

Pour le logiciel, j'ai choisi l'environement Matlab de Microchip, la version 6.42 convient pour le 16F877.

Le compilateur que j'ai utilisé est une version de démo de CCS de la société CCS Info que vous pouvez downloader depuis le lien http://www.ccsinfo.com/content.php?page=compdemo

 

Par Alain CROSET
Ecrire un commentaire - Voir les 1 commentaires - Recommander
Dimanche 16 décembre 2007

Pour l'autonomie de GreenRbot lors d'une tonte, je vais installer les capteurs IR Sharp sur le côté gauche pour le contournement des obstacles. Pour la détection frontale, je me suis procuré 2 capteus ultrason miniature (que j'essaie de faire fonctionner depuis plusieurs semaines maintenant), voilà qui est fait.

Je vous livre ici le petit programme qui m'a permis de tester le fonctionnement des 2 capteurs. Les capteurs sont des MSU10 de chez Lextronic, à lecture par bus I2C. Tous les 2 capteurs étant livrés avec la même adresse E0, il faut modifier l'adresse du 2ème capteur.  Pour le test, aussi bien que pour la modification d'adresse, j'ai utilisé la carte CPU de GreenRbot. Je vous livre les 2 programmess :

 Changement de l'adresse de base E0 en F0 :


#include <16f877.h>
#fuses HS,NOPROTECT,NOWDT,BROWNOUT,PUT,NOLVP
#ORG 0x1F00,0x1FFF {} /* Reserve memory for bootloader for the 8k 16F876/7 */
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c (master, sda=PIN_C4, scl=PIN_C3)
 
main()
{
  i2c_start();                    //initate start condition
  i2c_write(0xE0);                //device address
  i2c_write(0x00);                //register address
  i2c_write(0xA0);                //1rst seq to change adress
  i2c_start();                    //initate start condition
  i2c_write(0xE0);                //device address
  i2c_write(0x00);                //register address
  i2c_write(0xAA);                //2nd seq to change adress
  i2c_start();                    //initate start condition
  i2c_write(0xE0);                //device address
  i2c_write(0x00);                //register address
  i2c_write(0xA5);                //3rd seq to change adress
  i2c_start();                    //initate start condition
  i2c_write(0xE0);                //device address
  i2c_write(0x00);                //register address
  i2c_write(0xF0);                //write new adress
  i2c_stop();
}

Affichage des 2 distances en cm sur le PC :

#include <16f877.h>
#fuses HS,NOPROTECT,NOWDT,BROWNOUT,PUT,NOLVP
#ORG 0x1F00,0x1FFF {} /* Reserve memory for bootloader for the 8k 16F876/7 */
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c (master, sda=PIN_C4, scl=PIN_C3)
 
main()
{
// int i;
int rangeE;
int rangeF;
while(1)
 {
  i2c_start();                    //initate start condition
  i2c_write(0xF0);                //device address
  i2c_write(0x00);                //register address
  i2c_write(0x51);                //set units to centimeters
  i2c_stop();
  delay_ms(105);                   //wait for returning ping
 
  i2c_start();                    //initiate a new start condition
  i2c_write(0xF0);                //device address
  i2c_write(0x02);                //address of high byte register
  i2c_start();
  i2c_write(0xF1);                //device address but read
 
  rangeF = i2c_read(1);         //read first byte and shift left
  rangeF = rangeF << 8;
  rangeF += i2c_read(1);           //read second byte and add to 1st
  rangeF += i2c_read(0);
  i2c_stop();
 
//  printf("range F0 in centimeters = %3unr", rangeF);
  delay_ms(1000);

  i2c_start();                    //initate start condition
  i2c_write(0xE0);                //device address
  i2c_write(0x00);                //register address
  i2c_write(0x51);                //set units to centimeters
  i2c_stop();
  delay_ms(105);                   //wait for returning ping
 
  i2c_start();                    //initiate a new start condition
  i2c_write(0xE0);                //device address
  i2c_write(0x02);                //address of high byte register
  i2c_start();
  i2c_write(0xE1);                //device address but read

  rangeE = i2c_read(1);         //read first byte and shift left
  rangeE = rangeE << 8;
  rangeE += i2c_read(1);           //read second byte and add to 1st
  rangeE += i2c_read(0);
  i2c_stop();
 
  printf("range E0 in centimeters = %3unr", rangeE); 
  printf("range F0 in centimeters = %3unr", rangeF); 
  printf(" nr");
  delay_ms(1000);
 }
}

Reste à incorporer la lecture des capteurs droite et gauhe au module de détetion d'obstacle. Comment gérer la lecture suffisament rapidement pour l'utiliser en tant qu'interruption de trajectoire ... suspens, c'est une autre histoire, mais j'attendrai pour cela que la température de mon garage remonte au dessus des qques degrés à peine positifs du moment.

Par Alain CROSET
Ecrire un commentaire - Voir les 0 commentaires - Recommander
Lundi 24 mars 2008

Ca y est, c'est fait !
Après de nombreux déboire avec la programmation en C et mon niveau inssuffisant pour coder sur un Pic 16F877, je m'étais décidé à passer à un langage de plus haut niveau facilitant la programmation.
J'ai fini par opter pour FlowCode, dont j'ai fait l'acquisiton.
Après qques semaines de tutoriaux (merci le forum Flowcode et la réactivité du support), j'en suis à coder la lecture de tous les capteurs et la gestion des moteurs.
Si ce week-end n'avait pas été si pluvieux, GreenBot aurait fait une petite sortie dans la pelouse ... ce n'est que partie remise.

Voici un exemple de FlowCode : ImageFlowCode.jpg

Par Alain CROSET
Ecrire un commentaire - Voir les 2 commentaires - Recommander
Samedi 13 septembre 2008

Principes de quart de tour sans collision :

*      A la suite d’une détection d’obstacle frontale, 2 quarts de tour sont possibles :

*      les quarts de tour de type 1 permettent de pivoter au plus près de l’obstacle, mais nécessitent toutefois de s’assurer d’avoir une marge en face de l’obstacle. Avec ce principe, une fois le quart de tour effectué, le robot se trouve plus porche de la zone de détection, la zone non tondue est la plus étroite.

*      les quarts de tour de type 2 permettent de pivoter en étant sûr de ne pas empiéter sur la zone de détection frontale, cependant, à la suite du quart de tour, le robot se trouve éloigné de la zone détectée. En utilisant ce principe, pour une tonte en bord de détection, il reste une zone non tondue.

*      Méthode pour réaliser les quarts de tour :

*      Le type 1 est obtenu en générant une marche avant de la roue gauche égale à la marche arrière de la roue droite de p/2 x l.

*      Le type 2 est obtenu en générant un ordre d’arrêt sur la roue gauche et une marche arrière sur la roue droite de  p/2 x l.

*      Lors du quart de tour, il est nécessaire d’enclencher la détection de collision latérale du coté où l’on effectue le quart de tour, de manière à éviter les obstacles qui n’étaient pas visibles avant la détection frontale et le quart de tour.

*      Dans le cas de GreenBot, le couple moteur étant important, il vaut mieux effectuer le quart de tour à vitesse lente (Vmax / 4) pour que GreenBot ne pas être emporté par son élan et ne s’arrête pas à temps si détection latérale.

Dimensions de GreenBot :

Soit la longueur L = 105 mm

Soit la largeur l = 465 mm

 

Principes de demi tour sans collision :

*      Par analogie 2 type de demi tour sont possibles :

*      demi tour de type 1, marche avant roue gauche = marche arrière roue droite de p x l. Il s’agit alors d’un demi tour exact, GreenBot repart dans ses traces.

*      demi tour de type 2, arrêt roue droite et marche avant roue gauche =  de p x l. Il s’agit alors d’un demi tour parallèle, GreenBot repart dans une trace parallèle à sa trace aller.

*      De la même manière que pour les quarts de tour, il est nécessaire d’enclencher la détection de collision latérale et de diminuer la vitesse de rotation à Vmax / 4

 

Par Alain CROSET
Ecrire un commentaire - Voir les 2 commentaires - Recommander

Présentation

Recommander

Images aléatoires

  • PontsHetCPU.jpg
  • dscn0491.jpg
  • PontsH.jpg
  • p8120698.jpg
  • avec-capot1.jpg

Recherche

W3C

  • Flux RSS des articles

Widget Viadeo

Créer un blog sur over-blog.com - Contact - C.G.U. - Rémunération en droits d'auteur - Signaler un abus