int bcr_scanIrregularLines(unsigned char num, unsigned int spacing)
{
	/* maxlength = 100 means that it will drive max. 100 ticks
	 * to find the first bar! Later in the code it will contain
	 * the regular space between the bars. */
	unsigned int whiteLength = 200;
	if (spacing < whiteLength) { spacing = whiteLength; } /* default buffer */
//	unsigned int blackLength = 200;
	lineCounter = 0;
	
	/* assume we stand on white (or not completely dark) */
	currentState = BCR_DIMMING_STATE;
	EncoderSet(0,0);
	MotorSpeed(READ_SPEED, READ_SPEED);
	
	while(1) {
		switch (currentState)
		{
			case BCR_DIMMING_STATE:
				EncoderSet(0,0);
				while (bcr_getGradient() >= -1*M_TOL*tolFactor) {
					if ( encoder[LEFT] > (whiteLength+spacing) ) {
						MotorDir(BREAK, BREAK);
						MotorSpeed(0,0);
						return lineCounter;
					}
				}
				
				if (lineCounter >= 1) { whiteLength = encoder[LEFT]; }
				currentState = BCR_BRIGHTEN_STATE;
				lineCounter += 1;
//				util_intToBeep(1);
//				MotorSpeed(READ_SPEED, READ_SPEED);
				break;

			case BCR_BRIGHTEN_STATE:
				EncoderSet(0,0);
				while (bcr_getGradient() <= M_TOL*tolFactor) {
//					if ( encoder[LEFT] > (2*whiteLength+spacing) ) {
//						MotorDir(BREAK, BREAK);
//						MotorSpeed(0,0);
//						return lineCounter;
//					}
				}
				currentState = BCR_DIMMING_STATE;
				break;
		}

		/* enough lines scanned? -> stop */
		if (num>0 && lineCounter >= num) {
			MotorDir(BREAK, BREAK);
//			MotorDir(RWD, RWD);
			GoTurn(-5, 0, READ_SPEED);
			break;
		}
	} // end switch

	MotorSpeed(0,0);
	return lineCounter;
}
Exemple #2
0
/*!
  \brief
  Faehrt eine bestimmte Strecke mit einer bestimmten Geschwindigkeit.
  (Autor: stochri)\n
  ODER\n
  Dreht um einen bestimmten Winkel mit einer bestimmten Geschwindigkeit.
  (Autor: stochri)\n
  Benutzt die Odometrie Sensoren im Interrupt Betrieb.\n
  Vor dem ersten Aufruf muss deshalb EncoderInit() aufgerufen werden.

  \param[in]
  distance Distanz in mm (- rueckwaerts, + = vorwaerts)\n
           Bei 0 wird degree fuer einen Turn benutzt.
  \param[in]
  degree Winkel (- rechts, + links)
  \param[in]
  speed Geschwindigkeit (Wertebereich 0...255)

  \return
  nichts

  \see
  MACRO Go() und MACRO Turn() koennen weiterhin aufgerufen werden um bestehenden
  Programmcode nicht umschreiben zu muessen.

  \see
  In der globale Variable encoder, werden die Hell-/Dunkelwechsel der\n
  Encoderscheiben im Interruptbetrieb gezaehlt.

  \par  Hinweis:
  Die Berechnung der zu fahrenden Ticks beruht auf der Annahme, dass die\n
  Anzahl der schwarzen Teilstuecke und die Raddurchmesser wie bei stochri sind.\n
  (Sternthaler) Vermutung, dass der Hersteller unterschiedlich grosse Raeder\n
  ausgeliefert hat, da die Berechnung in dieser Form bei Sternthaler nicht\n
  funktioniert.

  \par Beispiel:
  (Nur zur Demonstration der Parameter/Returnwerte)
  \code
  // Laesst den Asuro ein Quadrat von 200 mm fahren,
  // bei einer Geschwindigkeit von 150.
  EncoderInit ();
  for (i = 0; i < 4; i++)
  {
    GoTurn (200,  0, 150);  // entspricht Go (200, 150)
    GoTurn (  0, 90, 150);  // entspricht Turn (90, 150)
  }
  \endcode
*****************************************************************************/
void GoTurn (
  int distance,
  int degree,
  int speed)
{
  unsigned  long  enc_count;
            int   tot_count = 0;
            int   diff = 0;
            int   l_speed = speed, r_speed = speed;

  /* stop the motors until the direction is set */
  MotorSpeed (0, 0);

  /* if distance is NOT zero, then take this value to go ... */
  if (distance != 0)
  {
    /* calculate tics from mm */
    enc_count  = abs (distance) * 10000L;
    enc_count /= MY_GO_ENC_COUNT_VALUE;

    if (distance < 0)
      MotorDir (RWD, RWD);
    else
      MotorDir (FWD, FWD);
  }
  /* ... else take the value degree for a turn */
  else
  {
    /*  calculate tics from degree */
    enc_count  = abs (degree) * MY_TURN_ENC_COUNT_VALUE;
    enc_count /= 360L;

    if (degree < 0)
      MotorDir (RWD, FWD);
    else
      MotorDir (FWD, RWD);
  }

  /* reset encoder */
  EncoderSet (0, 0);

  /* now start the machine */
  MotorSpeed (l_speed, r_speed);

  while (tot_count < enc_count)
  {
    tot_count += encoder [LEFT];
    diff = encoder [LEFT] - encoder [RIGHT];

    if (diff > 0)
    { /* Left faster than right */
      if ((l_speed > speed) || (r_speed > 244))
        l_speed -= 10;
      else
        r_speed += 10;
    }

    if (diff < 0)
    { /* Right faster than left */
      if ((r_speed > speed) || (l_speed > 244))
        r_speed -= 10;
      else
        l_speed += 10;
    }
    /* reset encoder */
    EncoderSet (0, 0);

    MotorSpeed (l_speed, r_speed);
    Msleep (1);
  }
  MotorDir (BREAK, BREAK);
  Msleep (200);
}