To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.roboticsOpen lugnet.robotics in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / 13034
13033  |  13035
Subject: 
Re: How2 'count' in NQC
Newsgroups: 
lugnet.robotics
Date: 
Fri, 3 Nov 2000 06:03:08 GMT
Original-From: 
Steve Baker <sjbaker1@airmail#Spamless#.net>
Reply-To: 
sjbaker1@%nomorespam%airmail.net
Viewed: 
737 times
  
Jerry Kalpin wrote:

I have spent about 4 hours discovering that a touch sensor can count many
times where you expect it to count *once*.

The sensor returns 1 for as long as it's held down.

In your code:

#define BUMPER SENSOR_2
#define LAMP OUT_B
#define FLASH_TIME 10
#define DELAY 50

int counter;

void check_switch()
{
    if (BUMPER == 1)
    {
        counter += 1;
        Wait (DELAY); //to register 1 count only
    }
}

You are actually counting how long the switch is held down - in units of about
a half second.  So if you press and hold the switch for ten seconds, you'll get
a count of about 20 in 'counter.

Perhaps you want this:

int last_bumper_state ;
int counter ;

void check_switch ()
{
  int bumper_state ;

  bumper_state = BUMPER ;

  if ( last_bumper_state == 0 && bumper_state == 1 )
    counter++ ;

  last_bumper_state = bumper_state ;
}


...this will now count only when the routine sees that the last time it was called,
the bumper was NOT pushed - but now it IS pushed.  Hence the counter will count just
once when you push the button - and not change again until you release the button and
then press it a second time.

void check_counter()
{
    if (counter > 5) //light flashes after the 6th actuation
    {
        On (LAMP);
        counter = 0;
        Wait (FLASH_TIME);
        Off (LAMP);
    }
}

It's better to try to avoid delays like this since while this task is
delaying, it can't be doing anything else.  If someone pressed the
button (and immediately released it again) while you were in
"Wait(FLASH_TIME);" then you'd miss it!

A better solution would be this program:

#define BUMPER SENSOR_2
#define LAMP OUT_B
#define FLASH_TIME 100

int last_bumper_state ;
int counter ;
int lamp_time_left ;

void check_switch ()
{
  int new_bumper_state ;

  new_bumper_state = BUMPER ;

  if ( last_bumper_state == 0 && new_bumper_state == 1 )
    counter++ ;

  last_bumper_state = new_bumper_state ;
}


void update_lamp ()
{
  if ( counter > 5 ) //light flashes after the 6th actuation
  {
    On ( LAMP ) ;
    lamp_time_left = FLASH_TIME ;
    counter = 0 ;
  }
  else
  if ( lamp_time_left < 1 )
    Off ( LAMP ) ;
  else
    lamp_time_left -- ;
}


task main()
{
  counter           = 0 ;
  last_bumper_state = 0 ;
  lamp_time_left    = 0 ;

  SetSensor ( BUMPER, SENSOR_TOUCH ) ;

  while ( true )
  {
    check_switch () ;
    update_lamp  () ;
    Wait ( 1 ) ;
  }
}


This program will flash the lamp on for a whole second after every sixth
sensor press...but it won't miss *any* sensor presses unless they are less
than 1/100th second in duration.

Actually, an even easier way would be to run two tasks at once - one
monitoring the switch and the other flashing the light.


#define BUMPER      SENSOR_2
#define LAMP        OUT_B
#define FLASH_TIME  100

int last_bumper_state ;
int counter ;

void check_switch ()
{
  int new_bumper_state ;

  new_bumper_state = BUMPER ;

  if ( last_bumper_state == 0 && new_bumper_state == 1 )
    counter++ ;

  last_bumper_state = new_bumper_state ;
}


task update_lamp ()
{
  while ( true )
  {
    if ( counter > 5 ) //light flashes after the 6th actuation
    {
      counter = 0 ;
      On ( LAMP ) ;
      Wait ( FLASH_TIME ) ;
      Off ( LAMP ) ;
    }
    else
      Wait ( 1 ) ;
  }
}


task main()
{
  counter           = 0 ;
  last_bumper_state = 0 ;

  SetSensor ( BUMPER, SENSOR_TOUCH ) ;

  start update_lamp () ;

  while ( true )
    check_switch () ;
}


This should be even better than the previous program because the time-critical
switch testing loop has no delays in it at all.

Anyway, there are yet more levels of sophistication that could be employed if you
truly utterly *had* to flash the light *EXACTLY* on every sixth push for even VERY
short/rapid clicks...however, events that short are rare with physical/mechanical
systems such as are found in Lego robots.

--
Steve Baker   HomeEmail: <sjbaker1@airmail.net>
              WorkEmail: <sjbaker@link.com>
              HomePage : http://web2.airmail.net/sjbaker1
              Projects : http://plib.sourceforge.net
                         http://tuxaqfh.sourceforge.net
                         http://tuxkart.sourceforge.net
                         http://prettypoly.sourceforge.net



Message has 2 Replies:
  Re: How2 'count' in NQC
 
Steve, this is the third time you have helped me, and this time you obviously spent a lot of time working out the alternatives. First of all, the Wait (DELAY); in my inept code was not to flash every half second. It was to prevent additional counts (...) (24 years ago, 3-Nov-00, to lugnet.robotics)
  Re: How2 'count' in NQC
 
I have noticed this ongoing thread about the difficulties of debouncing and counting switch closures, and I must say that it is a very real problem anywhere electromechanical switches are interfaced to electronics which is orders of magnitude (...) (24 years ago, 3-Nov-00, to lugnet.robotics)

Message is in Reply To:
  How2 'count' in NQC
 
In NQC you count by adding 1 to a variable like this: int counter; counter += 1 But it's hard to know *how much* you have counted; however, you can build a little program to (say) flash a light when you reach a certain count. I have spent about 4 (...) (24 years ago, 2-Nov-00, to lugnet.robotics)

6 Messages in This Thread:


Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR