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 / 1256
1255  |  1257
Subject: 
Re: light sensor problem?
Newsgroups: 
lugnet.robotics.rcx.legos
Date: 
Mon, 24 Jul 2000 00:42:27 GMT
Viewed: 
2512 times
  
On Mon, 24 Jul 2000, Eddie C. Dost wrote:
I looked through the dsensor stuff, and it looks quite bad to me...

:) Bad is, of course, all relative...

We execute a delay loop inside an interrupt handler.
We issue the command to start the next read from that same handler.

This will read the sensors very quickly, for the cost of high interrupt
load

Yes, though IMHO fast = good. It allows us to do things with legOS that
might not be doable with other firmwares.

and (maybe) inproper driving of the sensors (See Kekoa's comments
in e-mails last year).

I'm not sure which comments you are referring to- do you have a URL for
the lugnet post?

I doubt we need this very fast reading of sensors. This makes implementing
more sophisticated events like change over time and such harder.

You mean change over time of the sensors? Shouldn't that kind of stuff be
done in "user space" anyway?

Another aproach for the dsensor driver would be this:

Get a wakeup every X milliseconds. Inside the called routine:

  - Turn of the output driver to the active sensors.
  - Program timer compare B to wake up after the required
    delay time.

Inside the timer interrupt:

  - Program the A/D to sample all sensors and generate an interrupt.

Inside the A/D interrupt:

  - Turn off A/D sampling.
  - Read the A/D values for all sensors.
  - Turn the output driver for the active sensors back on.

This scheme would be very efficient considering CPU resources. I did
not measure it yet, but we would probably sleep a lot more in the idle
process, so we should have better battery savings.

I do like the idea of battery savings, and the approach would be flexible.

Also all sensors are quaranteed to be driven correctly, once the
constant needed for the 8 bit timer is well known. Speed should not
be a problem, as reading the sensors every 1 ms (for example) would
allow one rotation sensor 'tick' every 1 ms, i.e. one rotation every
16 ms, i.e. 62 rotations per second, which is 3720 rpm...

Has anyone actually measured the length of time for the code? In 0.1.x, it
was less than 0.3 ms, and in some cases that was nice. I suppose that
under this approach, we could set a reasonable default (1 or 2 ms) and
then allow it to be a compile time option via config.h if someone really,
really needed more accurate rotation sensing.

I have implemented some sample code, which takes over the ad_vector
from legOS and handles it similar to the above scheme. The values look
very stable and accurate with that.

If ACTIVE_SENSORS in the sample code below is defined to 0 (the default
state in legOS when no program is run, or no light/rotation sensor are
active), this code reduces power consumption from 26.3 mA to 18.1 mA
(I just measured it, after hacking up the sample, this seems to prove
the statement about efficiency above).

Very nice.

The user, and the battery handler of course ;-) should use the values
latched in ad_value[] as sensor data, this can easily be done with some
defines in dsensor.h.

Personally I like this code (or some code like this, if this evolves
into an actual driver) better for another reason: It contains less
assembly, which makes it easier to follow...

As far as assembly goes, I have to say that the current implementation is
pretty tame.

I will take this into our lab at work to measure the timing for the
light sensor with a scope, just to make shure we have this right. I just
don't know exactly when I will get to this, I hope within this week.

Can we also add this to the 0.2.5 todo list? Again, this is a pretty big
change (possibly).

I should note here that if at all possible, I'd really like to get an
"official" release of 0.2.4 out this week. I'll be going on vacation at
the end of the week, and so I want to keep this type of thing to a minimum
while I'm gone- which means, ideally, getting this out now. That also
means we can get started on 0.2.5 and not have the creeping featurism that
has plagued Linux kernel releases lately.

Luis

P.S. Is anyone else pleasantly surprised that after 7 months without a
release, we can now talk about a couple of releases?


Eddie C. Dost
ecd@skynet.be
--
#include <conio.h>
#include <unistd.h>
#include <sys/h8.h>


#define SENSOR_READ_DELAY 100 /* microseconds (must be << 1ms)   */
/* accuracy is 2 us, could be made */
/* better when changing systime to */
/* use TCR_CLOCK_8                 */
#define SENSOR_READ_INTERVAL 2 /* milliseconds */

#define ACTIVE_SENSORS 7 /* 1, 2, and 3 */


static void ad_handler(void) __attribute__ ((rcx_interrupt));
static void ocib_handler(void) __attribute__ ((rcx_interrupt));

static unsigned char *rom_port6_ddr = (unsigned char *)0xfd85;
static unsigned int *ad_vector = (unsigned int *)0xfdbc;
static unsigned int *ocib_vector = (unsigned int *)0xfda4;

static unsigned short ad_value[4];
static unsigned char active_sensors;
static int display;


static void ad_handler(void)
{
AD_CSR &= ~(ADCSR_ENABLE_IRQ | ADCSR_START);

ad_value[0] = AD_C >> 6;
ad_value[1] = AD_B >> 6;
ad_value[2] = AD_A >> 6;
ad_value[3] = AD_D >> 6;

PORT6 |= active_sensors;

}

static void ocib_handler(void)
{
T_IER &= ~(TIER_ENABLE_OCB);
T_CSR &= ~(TCSR_OCB);

AD_CSR &= ~(ADCSR_END);
AD_CSR |= ADCSR_ENABLE_IRQ | ADCSR_START;
}

int
ad_thread(int argc, char **argv)
{
unsigned short cnt;

while (1) {
msleep(SENSOR_READ_INTERVAL);

/* Program OCRB:
*
* Watch out for wrap arounds! OCRA clears the
* counter at 500.
*/
cnt = (T_CNT + (SENSOR_READ_DELAY >> 1)) % 500;
PORT6 &= ~(active_sensors);

T_OCR |= TOCR_OCRB;
T_OCRB = cnt;
T_CSR &= ~(TCSR_OCB);
T_IER |= TIER_ENABLE_OCB;
}
}

static void ad_init(void)
{
*rom_port6_ddr |= 0x07;
PORT6_DDR = *rom_port6_ddr;

AD_CSR = 0;

*ad_vector = (unsigned int)ad_handler;

AD_CR &= ~(ADCR_EXTERN);
AD_CSR = ADCSR_TIME_266 | ADCSR_SCAN | ADCSR_GROUP_0 | ADCSR_AN_3;

*ocib_vector = (unsigned int)ocib_handler;

PORT6 |= active_sensors;
}

int
display_thread(int argc, char **argv)
{
while (1) {
lcd_number(ad_value[display], sign, e0);
msleep(50);
}
}

int
main(int argc, char **argv)
{
active_sensors = ACTIVE_SENSORS;

ad_init();

execi(ad_thread, 0, NULL, PRIO_HIGHEST - 1, 64);
execi(display_thread, 0, NULL, PRIO_NORMAL, DEFAULT_STACK_SIZE);

while (1) {
cputc_hex_0(display + 1);

wait_event(dkey_pressed, KEY_VIEW);
wait_event(dkey_released, KEY_VIEW);

display = (display + 1) & 3;
}

return 0;
}



-----------------------------------------------------------------------

    "Summertime... and the living is easy...
    fish are jumping and the cotton is high...
    So hush, little baby, baby don't you cry."
-Ella

-----------------------------------------------------------------------



Message has 2 Replies:
  Re: light sensor problem?
 
(...) (URL) > I doubt we need this very fast reading of sensors. This makes implementing (...) Yes, when we have user space timers... (...) This is correct, but there are many good reasons for keeping assembly low bandwidth, like pitfalls in (...) (24 years ago, 24-Jul-00, to lugnet.robotics.rcx.legos)
  Re: light sensor problem?
 
(...) I personally forget the numbers of the lugnet posts. The gist is that the firmware and LegOS were, at the time, different in a critical way. I don't know the current status of LegOS. At the time, LegOS cycled through the 4 A/D sensors, reading (...) (24 years ago, 25-Jul-00, to lugnet.robotics.rcx.legos)

Message is in Reply To:
  Re: light sensor problem?
 
(...) I looked through the dsensor stuff, and it looks quite bad to me... We execute a delay loop inside an interrupt handler. We issue the command to start the next read from that same handler. This will read the sensors very quickly, for the cost (...) (24 years ago, 24-Jul-00, to lugnet.robotics.rcx.legos)

26 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