To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.nqcOpen lugnet.robotics.rcx.nqc in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / NQC / 564
563  |  565
Subject: 
RCX2 API Update
Newsgroups: 
lugnet.robotics.rcx.nqc
Date: 
Sat, 29 Apr 2000 09:01:22 GMT
Viewed: 
2155 times
  
I made some mistakes in the first release, so here is a new version. I've
also added counter support.

<-Readme.txt->
RCX2 Header file for NQC2.1r2  -  27 April 2000  - James Pritchard

rcx2api.nqh - NQC Header file that contains constant and macros for RCX2
Firmware
sample.nqc - Sample program using some of the new features of RCX2

To use these files you will need to install the Pre-Alpha release of the
RCX2 firmware into your RCX brick. These files have been tested with version
326 that can be found at the Lego Mindstorms website www.legomindstorms.com
You should read "LASM Byte Codes" to get a better understanding of the
functions. For the most part I've useds similar names and syntax.

Unfortunatly I can't implemt the event driven features of the new firmware
fully, we'll have to wait till Dave Baum releases a version of NQC with RCX2
support (Soon please Dave).
Another feature that I've not workout yet is access control. It looks like
you can get a task to take over a resource (Motor or Sound) so that it has
sole control. I think this is where the priority setting comes in allowing
one task to take control off of a lower task. For the time being you should
avoid using the event and access control.
I'm not sure whether the counters will work correctly with nqc at the
moment. This is because the counters are really just global varibles that
can be manipulated and used as a sensor for an event. I would avoid using
them for the moment. See lstop7.nqc for how to use them in nqc.

Allot of the stuff in RCX2 is also used in the scout so most of the stuff in
rcx2h.nqh is copied out of Dave's nqc2.nqh file.


Functions

ViewSourceValue(decimal_point, data_source) -Setup USER display mode
MuteSound()     -Turns off sound buffer PlayTone and PlaySound are ignored
UnMuteSound()     -Turns on sound buffer
ClearSound()     -Clears sound buffer immediatly ready for next sound
SleepNow()     -Switchs RCX off immediatly
Sleep(minutes)     -Set inactivity timeout
SelectProgram(program_number)   -Switch to program_number and runs,
program_number is from (0-4)
SetPriority(priority)    -Sets tasks prioity for access or resources (0-255)
IncCounter(counter)    -Increase value of counter by 1 (0 to 2)   Note these
counter may cause problems because they are actually global varibles.
DecCounter(counter)    -Decrease value of counter by 1 (0 to 2)
ClearCounter(counter)    -Clears counter
SeedRandom(seed)    -Seeds random number generator with seed
GSetOutput(motorlist, ON/OFF)
GSetDirection(motorlist, FWD/REV)
GSetPower(motorlist, power)
GOn(motorlist)
GOff(motorlist)
GFloat(motorlist)
GToggle(motorlist)
GFwd(motorlist)
GRev(motorlist)
GOnFwd(motorlist)
GOnRev(motorlist)
GOnFor(motorlist, time)
Event(event)
WaitEvents(exp)
ClearAllEvents()
StopEvents()
SetEvent(event,eventsensor,eventtype)
ClearEvent(event,eventsensor)
SetEventClicks(event,clicks)
SetEventUT(event, upper_threshold)
SetEventLT(event, lower_threshold)
SetEventHyst(event, hysterisis)
SetEventDur(event, duration)


Expressions

Counter(n)  -Read Counter
OutputStatus(n)  -Output Status checkout the RCX2 SDK for info on this.
OutputPower(n)  -Output power on n
OutputDir(n)  -Output direction on n  0=rev 1=fwd
OutputMode(n)  -Output is ON/BRAKE/FLOAT 0=float 1=brake 2=on
GOutputStatus(n) -Global Motor Status
GOutputPower(n)  -Output power on n
GOutputDir(n)  -Output direction on n  0=rev 1=fwd
GOutputMode(n)  -Output is ON/BRAKE/FLOAT 0=off 1=on
CurrentProgram  -Current Program Slot
Battery   -Battery level in mV
Version   -Firmware version x100


Constants

DISPLAY_USER -Use with SelectDisplay(n) to select USER display mode
EVENT_SENSOR_INPUT1
EVENT_SENSOR_INPUT2
EVENT_SENSOR_INPUT3
EVENT_SENSOR_TIMER1
EVENT_SENSOR_TIMER2
EVENT_SENSOR_TIMER3
EVENT_SENSOR_TIMER4
EVENT_SENSOR_MAILBOX
EVENT_SENSOR_COUNTER1
EVENT_SENSOR_COUNTER2
EVENT_SENSOR_COUNTER3
EVENT_TYPE_PRESS
EVENT_TYPE_RELEASE
EVENT_TYPE_PERIOD
EVENT_TYPE_TRANSITION
EVENT_TYPE_FASTCHANGE
EVENT_TYPE_LOW
EVENT_TYPE_NORMAL
EVENT_TYPE_HIGH
EVENT_TYPE_CLICK
EVENT_TYPE_DOUBLECLICK
EVENT_TYPE_MAILBOX

Contact me either through the nqc newsgroup at lugnet or by email
dungeon@madasafish.com

<-rcx2api.nqc->
/*
*  rcx2api.nqh - Addition Header file for use with NQC 2.1r2
*  Copyright (C) 2000 James Pritchard
*
*  Date:27-04-2000
*
*  This file allows you to use some of the new features of
*  RCX2 Firmware Version 326 April 18, 2000 Pre-Alpha
*
*
*  The contents of this file are subject to the Mozilla Public License
*  Version 1.0 (the "License"); you may not use this file except in
*  compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
*
*  Software distributed under the License is distributed on an "AS IS"
*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
*  License for the specific language governing rights and limitations
*  under the License.
*
*  Thanks to Dave Baum for creating such an excelent compiler and language.
*
*  All Rights Reserved.
*/

// Some new data sources

#define OutputStatus(n)  @(0x30000 + (n)) // Needs some refining to extract
PWR, DIR, ON/OFF/FLOAT
#define OutputPower(n)  (@(0x30000 + (n)) & 7) // Power set on motor n
#define OutputDir(n)  ((@(0x30000 + (n)) & 8)/8) // Dir set on motor n.
1=fwd 0=rev
#define OutputMode(n)  ((@(0x30000 + (n)) & 192)/64) // 0=float 1=brake 2=on

#define GOutputStatus(n) @(0x110000 + (n)) // Needs some refining to extract
PWR, DIR, ON/OFF/FLOAT
#define GOutputPower(n)  (@(0x110000 + (n)) & 7) // Power set on motor n
#define GOutputDir(n)  ((@(0x110000 + (n)) & 8)/8) // Dir set on motor n.
1=fwd 0=rev
#define GOutputMode(n)  ((@(0x110000 + (n)) & 128)/128) // 1=On 0=Off

#define CurrentProgram  @(0x80000) // Current Selected Program Slot 0-4
#define Battery   @(0x220000) // Battery level in mV
#define Version   @(0x230000) // Firmware Version Number x100



#define EVENT_SENSOR_INPUT1 0
#define EVENT_SENSOR_INPUT2 1
#define EVENT_SENSOR_INPUT3 2
#define EVENT_SENSOR_TIMER1 3
#define EVENT_SENSOR_TIMER2 4
#define EVENT_SENSOR_TIMER3 5
#define EVENT_SENSOR_TIMER4 6
#define EVENT_SENSOR_MAILBOX 7
#define EVENT_SENSOR_COUNTER1 8
#define EVENT_SENSOR_COUNTER2 9
#define EVENT_SENSOR_COUNTER3 10

#define EVENT_TYPE_PRESS 0
#define EVENT_TYPE_RELEASE 1
#define EVENT_TYPE_PERIOD 2
#define EVENT_TYPE_TRANSITION 3
#define EVENT_TYPE_FASTCHANGE 7
#define EVENT_TYPE_LOW  8
#define EVENT_TYPE_NORMAL 9
#define EVENT_TYPE_HIGH  10
#define EVENT_TYPE_CLICK 11
#define EVENT_TYPE_DOUBLECLICK 12
#define EVENT_TYPE_MAILBOX 14

#define COUNTER_1  0
#define COUNTER_2  1
#define COUNTER_3  2

// Use with SelectDisplay
#define DISPLAY_USER  7 // User display mode that will show most sources

// Set user display data source
void ViewSourceValue(const int p, const int &v) { asm { 0xE5, 0, p, &v }; }

// RCX2 Sound Buffer Control
void MuteSound()  { asm { 0xD0 }; } // Makes RCX Ignore all PlayTone and
PlaySound commands
void UnMuteSound()  { asm { 0xE0 }; }
void ClearSound()  { asm { 0x80 }; } // Clears Sound Buffer Ready for next
sound.

// Turn off Brick
void SleepNow()   { asm { 0x60 }; } // Switch brick off immediately

// Auto Time Off
void Sleep(const int m)  { asm { 0xB1, m }; } // Inactive time out after m
minutes 0=never

// Change Program Slot
// Slot numbers 0 - 4
void SelectProgram(const int p)  { asm { 0x91, p }; }

// Seed Random Generator
void SeedRandom(const int c) { asm { 0x04, 0x0, 0x02, c }; }


// These are Dave Baum's not mine (There from the scout code in RCX2.NQH)

// Set Global Motor Controls

void GSetOutput(const int o, const int m) { asm { 0x67, (o) + (m) }; }
void GSetDirection(const int o, const int d) { asm { 0x77, (o) + (d) }; }
void GSetPower(const int o, const int &p) { asm { 0xa3, (o), &p :
0x1000015}; }
void GOn(const int o) { GSetOutput(o, OUT_ON); }
void GOff(const int o) { GSetOutput(o, OUT_OFF); }
void GFloat(const int o) { GSetOutput(o, OUT_FLOAT); }
void GToggle(const int o) { GSetDirection(o, OUT_TOGGLE); }
void GFwd(const int o) { GSetDirection(o, OUT_FWD); }
void GRev(const int o) { GSetDirection(o, OUT_REV); }
void GOnFwd(const int o) { GFwd(o); GOn(o); }
void GOnRev(const int o) { GRev(o); GOn(o); }
void GOnFor(const int o, const int &t) { GOn(o); Wait(t); GOff(o); }

// This will be used to decide which task can control a resource. The lower
the value the more important the task. (0-255)
void SetPriority(const int p)  { asm { 0xD7, p }; }

// counter support
void IncCounter(const int c) { asm { 0x97, c }; }
void DecCounter(const int c) { asm { 0xA7, c }; }
void ClearCounter(const int c) { asm { 0xb7, c}; }

// use this to read a counter
//
// x = Counter(0);
//
#define Counter(n)   @(0x150000 + (n))

// events
void Event(const int e)    { asm { 0x03, 0, e, e>>8 }; }  // Mimics event e
void WaitEvents(const int &mask) { asm { 0xb4, &mask : 0x0015, 3, 0x27,
0x81 }; }

// End of Dave's scout code

// Clear all events use with extream caution.
void ClearAllEvents() { asm { 0x06 }; }

void StopEvents() { asm { 0xB0 }; } // Stops event monitoring in the current
task

// SetEvent( righthit, EVENT_SENSOR_INPUT1, EVENT_TYPE_PRESSED) - Sets up
event ready for monitoring
void SetEvent(const int e, const int s, const int t) { asm { 0x93, e, s,
t }; }

void ClearEvent(const int e, const int s) { asm { 0x93, e, s, 16 }; }

void SetEventClicks(const int e, const int c) { asm { 0x05, 0x1B, 0x02,
c }; }
void SetEventUT(const int e, const int c) { asm { 0x05, 0x1C, 0x02, c }; }
void SetEventLT(const int e, const int c) { asm { 0x05, 0x1D, 0x02, c }; }
void SetEventHyst(const int e, const int c) { asm { 0x05, 0x1E, 0x02, c }; }
void SetEventDur(const int e, const int c) { asm { 0x05, 0x1F, 0x02, c }; }

<-lstop7.nqc->
/*
*  lstop7.nqc - Line and Wall avoider
*
*  Copyright (C) 2000 James Pritchard
*
*  Date:27-04-2000
*
*
*  The contents of this file are subject to the Mozilla Public License
*  Version 1.0 (the "License"); you may not use this file except in
*  compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
*
*  Software distributed under the License is distributed on an "AS IS"
*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
*  License for the specific language governing rights and limitations
*  under the License.
*
*  Thanks to Dave Baum for creating such an excelent compiler and language.
*
*  All Rights Reserved.
*/
#include "../rcx2api/rcx2api.nqh"
#define sens 10
#define nsens -10
#define speed 5
#define reversetime 150
#define turntime 200
int count;  // We must initate the first global varible as the counter or
else nqc will use the counter as a varible.
int rl1;
int rl2;
int rlavg;
int orlavg;
int statlight;
int stattouch;
int whr;

task main()
{
        Sleep(0);
        ClearCounter(COUNTER_1);
        ViewSourceValue(0, count);
        SelectDisplay(DISPLAY_USER);
        SeedRandom(2782);
        SetSensorType(SENSOR_1, SENSOR_TYPE_TOUCH);
        SetSensorMode(SENSOR_1, SENSOR_MODE_BOOL);
        SetSensorType(SENSOR_2, SENSOR_TYPE_TOUCH);
        SetSensorMode(SENSOR_2, SENSOR_MODE_BOOL);
        SetSensorType(SENSOR_3, SENSOR_TYPE_LIGHT);
        SetSensorMode(SENSOR_3, SENSOR_MODE_RAW);
        SetDirection(OUT_A + OUT_C, OUT_FWD);
        SetPower(OUT_A + OUT_C, speed);
        SetOutput(OUT_A + OUT_C, OUT_ON);
        start actionlight;
        start actiontouch;
  start mlight;
        start monitorleft;
        start monitorright;
}

task mlight()
{
       SetPriority(10);
       int temp;
temp = 1;
       while (true)
{
              rl2 = rl1;
              rl1 = SENSOR_3;
              rlavg = rl2;
              rlavg + rl1;
              rlavg / 2;
  if (temp == 1) {
   temp = 0;
   } else {
                        if (rlavg - orlavg > sens) { PlayTone(1100,5);
statlight = 0; } // On Dark
                        if (rlavg - orlavg < nsens) { PlayTone(990,5);
statlight = 1; } // On Light
                        }
  orlavg = rlavg;
}
}

task actionlight()
{
        SetPriority(40);
        while(true)
        {
                until (statlight == 0); // Wait until on dark
                    IncCounter(COUNTER_1);
                    Rev(OUT_A + OUT_C);
                until (statlight == 1); // Wait until on light
                    Wait(reversetime);
                    if (Random(10) > 5) {
                       Fwd(OUT_A);} else {
                       Fwd(OUT_C);}
                    Wait(turntime);
                    Fwd(OUT_A + OUT_C);
        }
}

task monitorleft()
{
        SetPriority(20);
        while(true)
        {
                until (SENSOR_1 == 1); // Wait until Sensor1 Pushed LEFT
                stattouch |= 1;
                IncCounter(COUNTER_1);
                until (SENSOR_1 == 0); // Wait until unpressed on LEFT
                stattouch &= 2;
        }
}

task monitorright()
{
        SetPriority(20);
        while(true)
        {
                until (SENSOR_2 == 1); // Wait until Sensor1 Pushed RIGHT
                stattouch |= 2;
                IncCounter(COUNTER_1);
                until (SENSOR_2 == 0); // Wait until unpressed on RIGHT
                stattouch &= 1;
        }
}

task actiontouch()
{
        SetPriority(30);
        while(true)
        {
                if (stattouch == 3) {
                   // Both pressed
                   PlayTone(880,5);
                   whr = 2;
                   backup();
                }
                if (stattouch == 1) {
                   // Left only pressed
                   PlayTone(440,5);
                   whr = 0;
                   backup();
                }
                if (stattouch == 2) {
                   // Right only pressed
                   PlayTone(660,5);
                   whr = 1;
                   backup();
                }
        }
}

sub backup()
{
  Rev(OUT_A + OUT_C);
  Wait(reversetime);
  if (whr == 0)
  {
  Fwd(OUT_A);
  Wait(turntime);
  }
  if (whr == 1)
  {
  Fwd(OUT_C);
  Wait(turntime);
  }
  if (whr == 2)
  {
    if (Random(10) > 5)
    {
        Fwd(OUT_A);
        Wait(Random(200));
    } else {
        Fwd(OUT_C);
        Wait(Random(200));
    }
  }
  Fwd(OUT_A + OUT_C);
}

<-sample.nqc->
#include "../rcx2api/rcx2api.nqh"
int foo;
task main()
{
  foo = Battery;  // Put battery level into varible foo
  ViewSourceValue(0,foo);  // Set USER mode data source to varible foo and
decimal places to zero
  SelectDisplay(DISPLAY_USER);  // Change LCD Display into USER mode
  Wait(500);
  foo = CurrentProgram;  // Show current selected program slot
  Wait(500);
  foo = Version;  // Show the firmware version (should be 321 to 326)
  Wait(500);
  foo = 2782;  // Show the value 2782
  Wait(500);
  PlaySound(SOUND_CLICK); // PlaySound
  Wait(200);
  MuteSound();  // Turn off sound buffer
  PlaySound(SOUND_CLICK); // PlaySound but can't hear
  UnMuteSound();  // Turn sound buffer back on
  Wait(500);
  SleepNow();  // Turn brick off
}



1 Message in This Thread:

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

Custom Search

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