To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.legosOpen lugnet.robotics.rcx.legos in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / legOS / 3088
3087  |  3089
Subject: 
Re: Interesting BrickOS Timing Results
Newsgroups: 
lugnet.robotics.rcx.legos
Date: 
Wed, 15 Jan 2003 07:46:37 GMT
Viewed: 
3059 times
  
"Dick Swan" <dickswan@sbcglobal.net> wrote:

It's not surprizing that current implementation hogs so much CPU time.
If all four A/D channels are scanned every 150 us then the A/D
interrupt is occuring every 37.5 us since each A/D channel generates
its own interrupt. A 6 us delay loop executed every 37.5 us chews up a
lot of time! Plus a few us of interrupt servicing overhead. I bet even
the popular PC operating systems have trouble servicing interrupts
that fast.

I've found that any interrupt on the RCX has a minimum
overhead of 101 to 113 states (or about 7 us).  This is the time
taken by the CPU to recognize and dispatch the interrupt
plus the time the ROM routine takes to dispatch the interrupt
to the ISR.  This overhead is slightly less if the stack
is in on-chip RAM.

Here's a few things that you can do to improve the sensor handling if
you're getting into serious rewrites:

As Joe's post shows, it turns out that even a minor patch can improve
things dramaticly!

The H8 CPU has a mode where it scans all four A/D channels and
generates a single interrupt when complete. This is the method used by
the standard Lego ROM firmware. The Lego ROM firmware reads sensor
values every third time through the 1-msec interrupt routine. It
avoids the 6 us delay loop by cutting power to the active sensors at
the start of the routine, doing a bunch of other useful 1-msec
interrupt work, and then starting the A/D conversion at the end of the
interrupt handler. I'm not sure of the need for the 6 us delay; in my
homebrew OS I cut off power and immediately start A/D conversion and
don't seem to have any ill effects.

Heh, heh, I've been working on my own homebrew OS/library, too.  ;-)

I did find an improvement in having a delay after cutting off power.
But, like the standard firmware, I filled the delay with doing
useful things.  I haven't settled ;-) on a suitable time though.
I imagine that will involve getting in there with the scope and a few
sensors to nail it down.  I'll post any results when I get to this.

One of the possible drawbacks of the scan all four channels at once
A/D conversion is that it may introduce noise between channels and
reduce the conversion resolution. There was a thread on this a while
back. I don't think there was a definitive view on whether this
"factoid" was true.

I've observed this noise.  The channel previously sampled
can have an impact on the next channel.  Try this program:

#include <conio.h>
#include <unistd.h>
#include <dsensor.h>

int main(int argc, char **argv)
  {
  ds_active(&SENSOR_1);

  while (1)
    {
    cputw(SENSOR_1);
    msleep(500);
    }

  return 0;
  }

If you attach a touch sensor on input 2, press it on and off
and notice how the reading of input 1 is affected.  Run the
program first with no sensor attached to input 1, then attach
a light sensor to input 1.  (Note: The inputs are sampled in
reverse order because A/D channel A is input 3, B is 2,
etc...)

Incidentally, I found a way to virtually eliminate this crosstalk.
What you do is:

1. Cut the power (if it's an active sensor)
2. Start A/D conversion
3. Do something useful for ~20us (or so - still experimenting)
4. Stop A/D conversion
5. Start A/D conversion on same channel
6. Restore power after conversion complete (if active sensor)

I refer to steps 2-4 as a "pre-conversion".  It gets the analog mux
and sample & hold circuitry conditioned for the real conversion which
follows.

There's not much point in performing A/D conversions faster than the
time between different time slices of user tasks. The user task won't
see the changes anyway. Rotation counters are the only exception
because the sensor value is not a simple direct function of the raw
value but rather a counter based on an algorithm looking at difference
between consecutive raw values.

Also, whenever the subsystem handler fires (every 2ms), it certainly
disrupts the steady flow of samples.  This ISR takes from 70-150us,
so sampling every 37.5us (even for a rotation sensor) is wasteful
given the current configuration.

Mark



Message has 1 Reply:
  Re: Interesting BrickOS Timing Results
 
From the second scope screen capture here : (URL) you can see that the analog settling time is about 10 microseconds for the rotation sensor. Philo www.philohome.com (...) (21 years ago, 15-Jan-03, to lugnet.robotics.rcx.legos)

Message is in Reply To:
  Re: Interesting BrickOS Timing Results
 
This was a terrific analysis. It's not surprizing that current implementation hogs so much CPU time. If all four A/D channels are scanned every 150 us then the A/D interrupt is occuring every 37.5 us since each A/D channel generates its own (...) (21 years ago, 14-Jan-03, to lugnet.robotics.rcx.legos)

19 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