Example Source Code:
RoboJDE Java Test Program
For HandyBoards and Sumo11s


Description

This is a custom version of the test program distributed with RoboJDE. We've added a test for the WheelWatcher, similar to the one in the Interactive C test program. Note that RoboJDE does not use the same pin numbers for encoder objects as the Interactive C encoder.ic file does. See the comments.

The good news is that the encoder objects built into the HandyBoard class work just fine with the WheelWatcher -- and, they count all edges of ChA and ChB, resulting in 128 counts per wheel rotation.
 

Download

HandyBoardTest.java - Java source
Sumo11Test.java - Java source
HBTNativ.asm - assembly source
HandyBoardTest.rjp - RoboJDE project file
Sumo11Test.rjp - RoboJDE project file

 

Source Code


HandyBoardTest.java


/*
 * HandyBoardTest
 *
 * Copyright 2003 by RidgeSoft, LLC., PO Box 482, Pleasanton, CA  94566, U.S.A.
 * www.ridgesoft.com
 *
 * RidgeSoft grants you the right to use, modify, make derivative works and
 * redistribute this source file provided you do not remove this copyright notice.
 *
 * 8/5/2004 - PLS, Noetic Design, Inc. - added WheelWatcher WW-01 tests
 * NOTE: the HandyBoard class's ShaftEncoders were designed by RidgeSoft to
 * connect encoder 0 to pins 10 and 11, and encoder 1 to 12 and 13.
 * So, wire the WW-01s up like this:
 * (left WW-01) 
 * pin 11 = ChB/Blue; pin 10 = ChA/Yellow; pin 8 = DIR/Orange; pin 7 = CLK/Purple
 * (right WW-01)
 * pin 13 = ChA/Yellow; pin 12 = ChB/Blue; pin 14 = DIR/Orange; pin 15 = CLK/Purple
 */

import com.ridgesoft.io.Display;
import com.ridgesoft.robotics.AnalogInput;
import com.ridgesoft.robotics.PushButton;
import com.ridgesoft.robotics.Motor;
import com.ridgesoft.robotics.Servo;
import com.ridgesoft.io.Speaker;
import com.ridgesoft.handyboard.HandyBoard;
import com.ridgesoft.vm.VM;
import com.ridgesoft.ui.*;

/**
 * This class implements tests of the Handy Board.  
 *
 * The START button, STOP button and thumbwheel are used to control the tests.
 * -> Choose a test by using the thumbwheel to scroll through the list of tests.
 * -> Start the test by pressing the START button.
 * -> Most tests use the thumbwheel to vary the test.  For example, for
 *    motor tests, the thumbwheel varies the motor speed.
 * -> Stop the test by pressing the STOP button. 
 */
public class HandyBoardTest {
    public static void main(String args[]) {
        try {
            System.out.println("HandyBoardTest");

            // Tell virtual machine to ignore the stop button
            HandyBoard.setTerminateOnStop(false);

            // Create the main test menu
            MenuItemList mainMenu = new BasicMenuItemList("Select Category", new MenuItem[] {
                                                                        new ThumbTest("Thunbwheel"), 
                                                                        new BuzzerTest("Buzzer"),
                                                                        new AnalogTests("Analogs", 0, 7),
                                                                        new DigitalInTest("Digital Inputs"),
                                                                        new Digital9OutputTest("Digital 9 Out"),
                                                                        new MotorTestList("Motors", 4),
                                                                        new IRRxTest("IR Receiver"),
                                                                        new IRTxTest("IR Transmitter"),
                                                                        new AnalogTests("Exp. Analogs", 16, 16),
                                                                        new DigitalOutTest("Exp. Dig. Outs"),
                                                                        new ServoTestList("Exp. Servos", 6),
                                                                        new WW01Test("WheelWatcher")
                                                                        });

            // Create a MenuController
            TwoLineDisplayMenuController menuController = new TwoLineDisplayMenuController(
                                                                        HandyBoard.getLcdDisplay(),
                                                                        HandyBoard.getStartButton(),
                                                                        HandyBoard.getStopButton(),
                                                                        HandyBoard.getThumbWheel(),
                                                                        HandyBoard.getBuzzer(),
                                                                        mainMenu);

            // Show the menus
            menuController.show();
        }
        catch (Throwable t) {
            // Catch all exceptions and print a stack trace.
            t.printStackTrace();
        }
    }

    /**
     * Abstract base class for all tests, which implements the MenuItem interface
     * because test objects are used as menu choices.
     */
    public abstract static class Test implements MenuItem {
        private String mName;

        protected Test(String name) {
            mName = name;
        }

        public String toString() {
            return mName;
        }

        public abstract void select(PushButton selectButton, PushButton exitButton, MenuController menuController);
    }

    /**
     * Thumbwheel test.
     */
    public static class ThumbTest extends Test {
        public ThumbTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            while (!exitButton.isPressed())
                menuController.printStatus(Integer.toString(HandyBoard.readThumbWheel())); 

            menuController.buttonPressed();
        }
    }

    /**
     * Analog inputs test.
     */
    public static class AnalogTests extends Test {
        private int mBaseIndex;
        private int mCount;

        public AnalogTests(String name, int baseIndex, int count) {
            super(name);
            mBaseIndex = baseIndex;
            mCount = count;
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            while (!exitButton.isPressed()) {
                int i = menuController.getScrollIndex(mCount) + mBaseIndex;
                menuController.printStatus(Integer.toString(i) + ": " + HandyBoard.analog(i)); 
            }
            menuController.buttonPressed();
        }
    }

    /**
     * Motor selection menu.
     */
    public static class MotorTestList extends MenuItemList {
        private byte mNumberOfMotors;
        private MotorTest[] mMotorTests;

        public MotorTestList(String name, int numberOfMotors) {
            super(name);
            mNumberOfMotors = (byte)numberOfMotors;
        }

        /**
         * Gets the list of menu items in this list.
         * @return      array of MenuItems
         */
        public MenuItem[] getMenuItems() {
            if (mMotorTests == null) {
                mMotorTests = new MotorTest[mNumberOfMotors];
                for (int i = 0; i < mNumberOfMotors; ++i)
                    mMotorTests[i] = new MotorTest("Motor " + i, HandyBoard.getMotor(i));
            }
            return mMotorTests;
        }

        /**
         * Frees menuItems.
         */
        public void freeMenuItems() {
            mMotorTests = null;
        }
    }

    /**
     * Motor test.
     */
    public static class MotorTest extends Test {
        private Motor mMotor;

        public MotorTest(String name, Motor motor) {
            super(name);
            mMotor = motor;
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            while (!exitButton.isPressed()) {
                // Vary the power according to the thumbwheel position
                int power = menuController.getScrollIndex(Motor.MAX_FORWARD - Motor.MAX_REVERSE + 1) + Motor.MAX_REVERSE;
                mMotor.setPower(power);
                menuController.printStatus("power:  " + power); 
            }
            menuController.buttonPressed();
            mMotor.setPower(0);
        }
    }

    /**
     * Digital inputs test.
     */
    public static class DigitalInTest extends Test {
        public DigitalInTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            while (!exitButton.isPressed()) {
                int id = menuController.getScrollIndex(10) + 6;
                if (id == 6) {
                    StringBuffer bitStringBuffer = new StringBuffer();
                    for (int i = 15; i > 6; --i) {
                        if (HandyBoard.isDigitalInputSet(i))
                            bitStringBuffer.append('1');
                        else
                            bitStringBuffer.append('0');
                    }   
                    menuController.printStatus("15-7: " + bitStringBuffer.toString()); 
                }
                else {
                    char value;
                    if (HandyBoard.isDigitalInputSet(id))
                        value = '1';
                    else
                        value = '0';
                    menuController.printStatus(Integer.toString(id) + ": " + value); 
                }
            }
            menuController.buttonPressed();
        }
    }

    /**
     * Buzzer test.
     */
    public static class BuzzerTest extends Test {
        public BuzzerTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            menuController.printStatus(""); 
            int duration = 250;
            HandyBoard.play(262, duration);     // C
            HandyBoard.play(277, duration);     // C sharp
            HandyBoard.play(294, duration);     // D
            HandyBoard.play(311, duration);     // D sharp
            HandyBoard.play(330, duration);     // E
            HandyBoard.play(349, duration);     // F
            HandyBoard.play(370, duration);     // F sharp
            HandyBoard.play(392, duration);     // G
            HandyBoard.play(415, duration);     // G sharp
            HandyBoard.play(440, duration);     // A
            HandyBoard.play(466, duration);     // A sharp
            HandyBoard.play(494, duration);     // B
        }
    }

    /**
     * Native method for reading the count of IR pulses seen by the
     * IR demodulator.  Pointing an IR remote control at the demodulator
     * and pressing buttons should cause the count to increase if the
     * remote control transmits at the frequency of the demodulator ~40 Hz.
     */
    public static native int irPulseCount();

    /**
     * IR demodulator test.  Use an IR remote control to send IR pulses to the
     * demodulator or use another Handy Board running the IR transmitter test
     * to generate pulses.
     */
    public static class IRRxTest extends Test {
        public IRRxTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            int lastValue = -1;
            while (!exitButton.isPressed()) {
                int pulseCount = irPulseCount();
                if (pulseCount != lastValue) {
                    menuController.printStatus("Pulses: " + Integer.toString(pulseCount));
                    lastValue = pulseCount;
                }
            }
            menuController.buttonPressed();
        }
    }

    /**
     * Modulated IR transmitter test.  You must connect an IR LED to pins 1 and 3 of the IR OUT port
     * on the Handy Board with a current limiting resistor (~100-400 ohms) in the circuit.  Using another
     * Handy Board running the IR receive test you will see the pulse count increment if the transmitter
     * and receiver work.
     */
    public static class IRTxTest extends Test {
        public IRTxTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            menuController.printStatus("Running");
            boolean setIt = true;
            while (!exitButton.isPressed()) {
                if (setIt) {
                    VM.setBit(HandyBoard.PORTA, 6);
                    setIt = false;
                }
                else {
                    VM.clearBit(HandyBoard.PORTA, 6);
                    setIt = true;
                }
            }
            VM.clearBit(HandyBoard.PORTA, 6);
            menuController.buttonPressed();
        }
    }

    /**
     * Digital output 9 test.  Digital input #9 can be configured to be a digital output.  This
     * tests digital 9 as an output.
     */
    public static class Digital9OutputTest extends Test {
        public Digital9OutputTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            menuController.printStatus("Running");
            HandyBoard.setDigital9Direction(true);
            while (!exitButton.isPressed()) {
                switch (menuController.getScrollIndex(3)) {
                case 0:
                    HandyBoard.clearDigitalOutput(9);
                    menuController.printStatus("0");
                    break;
                case 1:
                    HandyBoard.setDigitalOutput(9);
                    menuController.printStatus("1");
                    break;
                case 2:
                    HandyBoard.toggleDigitalOutput(9);
                    menuController.printStatus("toggle");
                    try {
                        Thread.sleep(500);
                    }
                    catch (InterruptedException e) {}
                    break;
                }
            }
            HandyBoard.clearDigitalOutput(9);
            HandyBoard.setDigital9Direction(false);
            menuController.buttonPressed();
        }
    }

    /**
     * Test the 9 digital outputs (0 - 8) on the expansion board.  Digital 8 is not pinned out
     * to a header.  It is routed to the pin marked dig8 under the LCD screen.
     */
    public static class DigitalOutTest extends Test {
        public DigitalOutTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            while (!exitButton.isPressed()) {
                int id = menuController.getScrollIndex(12) - 1;
                if (id < 0 || id > 8) {
                    if (id < 0) {
                        digitalsOff();
                        menuController.printStatus("8-0: off");
                    }
                    else if (id == 9) {
                        digitalsOn();
                        menuController.printStatus("8-0: on");
                    }
                    else {
                        digitalsToggle();
                        menuController.printStatus("8-0: toggle");
                        try {
                            Thread.sleep(500);
                        }
                        catch (InterruptedException e) {}
                    }
                }
                else {
                    for (int i = 0; i < 9; ++i) {
                        if (i == id)
                            HandyBoard.setDigitalOutput(i);
                        else
                            HandyBoard.clearDigitalOutput(i);
                    }
                    menuController.printStatus(Integer.toString(id) + ": " + "on");
                }
            }
            digitalsOff();  
        }

        private void digitalsOff() {
            for (int i = 0; i < 9; ++i)
                HandyBoard.clearDigitalOutput(i);
        }

        private void digitalsOn() {
            for (int i = 0; i < 9; ++i)
                HandyBoard.setDigitalOutput(i);
        }

        private void digitalsToggle() {
            for (int i = 0; i < 9; ++i)
                HandyBoard.toggleDigitalOutput(i);
        }
    }

    /**
     * Servo selection menu.
     */
    public static class ServoTestList extends MenuItemList {
        private byte mNumberOfServos;
        private ServoTest[] mServoTests;

        public ServoTestList(String name, int numberOfServos) {
            super(name);
            mNumberOfServos = (byte)numberOfServos;
        }

        /**
         * Gets the list of menu items in this list.
         * @return      array of MenuItems
         */
        public MenuItem[] getMenuItems() {
            if (mServoTests == null) {
                mServoTests = new ServoTest[mNumberOfServos];
                for (int i = 0; i < mNumberOfServos; ++i)
                    mServoTests[i] = new ServoTest("Servo " + i, HandyBoard.getServo(i));
            }
            return mServoTests;
        }

        /**
         * Frees menuItems.
         */
        public void freeMenuItems() {
            mServoTests = null;
        }
    }

    /**
     * Servo test.
     */
    public static class ServoTest extends Test {
        private Servo mServo;

        public ServoTest(String name, Servo servo) {
            super(name);
            mServo = servo;
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            int oldPosition = -1;
            while (!exitButton.isPressed()) {
                int position = menuController.getScrollIndex(101);
                if (position != oldPosition) {
                    menuController.printStatus("position: " + position); 
                    mServo.setPosition(position);
                    oldPosition = position;
                }
            }
            menuController.buttonPressed();
            mServo.off();
        }
    }

    /**
     * WheelWatcher test.
     */
    public static class WW01Test extends Test {
        public WW01Test(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            HandyBoard.enableEncoder(0); // left WheelWatcher
            HandyBoard.enableEncoder(1); // right WheelWatcher      
            while (!exitButton.isPressed()) {
                HandyBoard.getLcdDisplay().print(0, "R c:" + HandyBoard.getEncoderCounts(1) + " s:" + HandyBoard.getEncoderRate(1) + " d:" + (HandyBoard.isDigitalInputSet(14) ? 'F' : 'B'));
                HandyBoard.getLcdDisplay().print(1, "L c:" + HandyBoard.getEncoderCounts(0) + " s:" + HandyBoard.getEncoderRate(0) + " d:" + (HandyBoard.isDigitalInputSet(8) ? 'B' : 'F')); 
            }
            menuController.buttonPressed();
        }
    }


}

Sumo11Test.java


/*
 * Sumo11Test
 *
 * Copyright 2003 by RidgeSoft, LLC., PO Box 482, Pleasanton, CA  94566, U.S.A.
 * www.ridgesoft.com
 *
 * RidgeSoft grants you the right to use, modify, make derivative works and
 * redistribute this source file provided you do not remove this copyright notice.
 *
 * 8/5/2004 - PLS, Noetic Design, Inc. - added WheelWatcher WW-01 tests
 */

import com.ridgesoft.handyboard.HandyBoard;
import com.ridgesoft.robotics.PushButton;
import com.ridgesoft.ui.*;

/**
 * This class implements tests of the Sumo11 robot controller.  Most of the
 * test cases are inherited from the HandyBoardTest class.
 *
 * The START button, STOP button and thumbwheel are used to control the tests.
 * -> Choose a test by using the thumbwheel to scroll through the list of tests.
 * -> Start the test by pressing the START button.
 * -> Most tests use the thumbwheel to vary the test.  For example, for
 *    motor tests, the thumbwheel varies the motor speed.
 * -> Stop the test by pressing the STOP button. 
 */
public class Sumo11Test extends HandyBoardTest {

    // Override main method from the parent class.
    public static void main(String args[]) {
        try {
            System.out.println("Sumo11Test");

            // Set board type to Sumo11
            HandyBoard.setBoardType(HandyBoard.TYPE_SUMO11);

            // Tell virtual machine to ignore the stop button
            HandyBoard.setTerminateOnStop(false);

            // Create the main test menu
            MenuItemList mainMenu = new BasicMenuItemList("Select Category", new MenuItem[] {
                                                                        new ThumbTest("Thunbwheel"), 
                                                                        new BuzzerTest("Buzzer"),
                                                                        new AnalogTests("Analogs", 0, 7),
                                                                        new Digital8OutputTest("Digital 8 Output"),
                                                                        new Digital9OutputTest("Digital 9 Output"),
                                                                        new DigitalInTest("Digital Inputs"),
                                                                        new MotorTestList("Motors", 2),
                                                                        new ServoTestList("Servos", 4),
                                                                        new IRRxTest("IR Receiver"),
                                                                        new IRTxTest("IR Transmitter"),
                                                                        new WW01Test("WheelWatcher")
                                                                        });

            // Create a MenuController
            TwoLineDisplayMenuController menuController = new TwoLineDisplayMenuController(
                                                                        HandyBoard.getLcdDisplay(),
                                                                        HandyBoard.getStartButton(),
                                                                        HandyBoard.getStopButton(),
                                                                        HandyBoard.getThumbWheel(),
                                                                        HandyBoard.getBuzzer(),
                                                                        mainMenu);

            // Show the menus
            menuController.show();
        }
        catch (Throwable t) {
            // Catch all exceptions and print a stack trace.
            t.printStackTrace();
        }
    }

    /**
     * Test for digital output 8, the only dedicated digital output on the Sumo11.
     */
    public static class Digital8OutputTest extends Test {
        public Digital8OutputTest(String name) {
            super(name);
        }

        public void select(PushButton selectButton, PushButton exitButton, MenuController menuController) {
            while (!exitButton.isPressed()) {
                switch (menuController.getScrollIndex(3)) {
                case 0:
                    HandyBoard.clearDigitalOutput(8);
                    menuController.printStatus("0");
                    break;
                case 1:
                    HandyBoard.setDigitalOutput(8);
                    menuController.printStatus("1");
                    break;
                case 2:
                    HandyBoard.toggleDigitalOutput(8);
                    menuController.printStatus("toggle");
                    try {
                        Thread.sleep(500);
                    }
                    catch (InterruptedException e) {}
                    break;
                }
            }
            HandyBoard.clearDigitalOutput(8);
            menuController.buttonPressed();
        }
    }
}

HBTNativ.asm


* HBTNativ.asm

* Copyright 2003 by RidgeSoft, LLC., PO Box 482, Pleasanton, CA  94566, U.S.A.
* www.ridgesoft.com
*
* RidgeSoft grants you the right to use, modify, make derivative works and
* redistribute this source file provided you do not remove this copyright notice.

* The following symbol defines the area in high memory where the native
* methods will be located.  When this file is assembled it must fit between
* this location and the end of memory.

NATIVE_AREA     equ     $fc00               ; the start address for native methods

* The native pointer enables the virtual machine to find the native methods.
* The location of the pointer is address $bfbe.

                org     $bfbe               ; location of the native pointer
                fdb     #NATIVE_AREA        ; point to the start of the native area

* Native methods header used by the virtual machine to register native methods.

                org     NATIVE_AREA
natvSignature   fdb     #$4e4d              ; native method signature
natvEnd         fdb     #nativeEnd          ; pointer to byte after native area
natvInitialize  fdb     #initialize         ; startup initialization routine
natvCount       fdb     #natvVectorsEnd-natvVectors/2 ; vector table size
natvVectors     fdb     #irPulseCount       ; read the number of IR pulses detected
natvVectorsEnd  equ     *

* Defines

REGISTERS       equ     $1000               ; base of HC11 registers
TIC1            equ     $10                 ; Timer Input Capture 1
TCTL2           equ     $21                 ; Timer Control Register 2
TMSK1           equ     $22                 ; Timer Interrupt Mask 1 Register
TFLG1           equ     $23                 ; Timer Interrupt Flag 1 Register

VECTORS         equ     $bfc0               ; base of interrupt vectors
IV_TIC1         equ     $2e                 ; timer input capture 1

TMSK1_IC1I      equ     $04                 ; T1C1 interrupt enable bit

TCTL2_EDG1B     equ     $20                 ; Input Capture 1 edge control bit B
TCTL2_EDG1A     equ     $10                 ; Input Capture 1 edge control bit A

TFLG1_IC1F      equ     $04                 ; TIC1 interrupt flag bit

* Native variables

pulseCount      rmb     4                   ; value of count on previous read

* Initialization routine

initialize      ldd     #0                  ; init. pulse count to zero
                std     pulseCount
                std     pulseCount+2

                ldx     #VECTORS            ; set IR (TIC1) interrupt vector
                ldd     #irInterrupt
                std     IV_TIC1,X

                ldx     #REGISTERS
                bset    TCTL2,X TCTL2_EDG1B ; set falling edge capture
                bclr    TCTL2,X TCTL2_EDG1A
                bset    TMSK1,X TMSK1_IC1I  ; enable interrupts
                rts

* Interrupt service routine

irInterrupt     ldd     pulseCount+2        ; increment the 32 bit pulse count
                addd    #1
                std     pulseCount+2
                ldd     pulseCount
                adcb    #0
                adca    #0
                std     pulseCount
                ldx     #REGISTERS
                ldaa    #TFLG1_IC1F         ; clear the interrupt
                staa    TFLG1,X
                rti                         ; return from interrupt

* Native Method

* static int irPulseCount()
* reads the count of IR pulses detected
irPulseCount    tpa                         ; disable interrupts while
                sei                         ; reading pulse count
                ldy     pulseCount          ; return count in Y:D
                ldx     pulseCount+2
                tap                         ; restore interrupts
                xgdx                        ; transfer low 16 bits to D
                rts

nativeEnd       equ     *               ; first byte after the end of native method memory


HandyBoardTest.rjp


Cookie=hbp
Version=1
MainClass=HandyBoardTest
StackSize=150
BuildBeforeLoad=true
NativeMethodFile=HBTNativ.asm
NativeMethod=static int HandyBoardTest.irPulseCount()
OpenFile=HandyBoardTest.java
OpenFile=HBTNativ.asm


 

 © 2004-2013 Noetic Design, Inc. All Rights Reserved. Nubotics, Unicoder, WheelCommander, and WheelWatcher are trademarks of Noetic Design, Inc.