Esempio n. 1
0
        /// <summary>
        /// Stop motors port BC. This will also cancel any scheduled movement for this motors.
        /// Motors will stop completely
        /// </summary>
        public static void OffAndBrake()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xA3);
            c.CONST(0);
            c.CONST(6);
            c.CONST(1);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 2
0
        /// <summary>
        /// Set the rotation count of one or more motors to 0.
        /// </summary>
        /// <param name="ports">Motor port name(s)</param>
        public static void ResetCount(Primitive ports)
        {
            int layer, nos;

            DecodePortsDescriptor(ports == null ? "" : ports.ToString(), out layer, out nos);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xB2);
            c.CONST(layer);
            c.CONST(nos);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 3
0
        private static void startsteer(Primitive ports, double speed, double turn)
        {
            int layer, nos;

            DecodePortsDescriptor(ports == null ? "" : ports.ToString(), out layer, out nos);

            int f = firstof2[nos];
            int s = secondof2[nos];

            if (f >= 0)
            {
                // the motor with lower letter is the "master"
                if (turn >= 0)
                {   // when the master is inverted, use inverted overall speed
                    if (inverted[f])
                    {
                        speed = -speed;
                    }
                    // when the slave's inversion is different from the master, modify the turn value
                    if (inverted[s] != inverted[f])
                    {
                        turn = 200 - turn;
                    }
                    // the motor with higher letter is the "master"
                }
                else
                {
                    // when the master is inverted, use inverted overall speed
                    if (inverted[s])
                    {
                        speed = -speed;
                    }
                    // when the slave's inversion is different from the master, modify the turn value
                    if (inverted[f] != inverted[s])
                    {
                        turn = -200 - turn;
                    }
                }

                ByteCodeBuffer c = new ByteCodeBuffer();
                c.OP(0xB0);        // turn on synchronized movement
                c.CONST(layer);
                c.CONST(nos);
                c.CONST((int)speed);
                c.CONST((int)turn);
                c.CONST(0);
                c.CONST(0);
                EV3RemoteControler.DirectCommand(c, 0, 0);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Query the current speed of a single motor for port A.
        /// Note that this command does not work for motors connected via daisy-chaining.
        /// </summary>
        /// <returns>Current speed in range -100 to 100</returns>
        public static Primitive GetSpeed()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xA8);
            c.CONST(0);
            c.CONST(0);
            c.GLOBVAR(4);
            c.GLOBVAR(0);
            byte[] reply = EV3RemoteControler.DirectCommand(c, 5, 0);
            int    spd   = reply == null ? 0 : (sbyte)reply[4];

            return(new Primitive(spd));
        }
Esempio n. 5
0
        /// <summary>
        /// Tries to establish a Bluetooth connection to another brick if it is not already connected.
        /// Only after a connection has been made (either by this command or manually from the on-brick menu), can messages be exchanged in both directions.
        /// </summary>
        /// <param name="brickname">Name of the remote brick.</param>
        public static void Connect(Primitive brickname)
        {
            String brick = brickname == null ? "" : brickname.ToString();

            // send connection request
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xD4);           // opCom_Set
            c.CONST(0x07);        // CMD: SET_CONNECTION = 0x07
            c.CONST(2);           // HARDWARE:  2: Bluetooth communication interface
            c.STRING(brick);
            c.CONST(1);           // connect
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 6
0
        /// <summary>
        /// Start playing a simple tone of defined frequency.
        /// </summary>
        /// <param name="volume">Volume can be 0 - 100</param>
        /// <param name="frequency">Frequency in Hz can be 250 - 10000</param>
        /// <param name="duration">Duration of the tone in milliseconds</param>
        public static void Tone(Primitive volume, Primitive frequency, Primitive duration)
        {
            int vol = volume;
            int frq = frequency;
            int dur = duration;

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x94);       // opSOUND
            c.CONST(0x01);    // CMD: TONE = 0x01
            c.CONST(vol);
            c.CONST(frq);
            c.CONST(dur);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 7
0
        /// <summary>
        /// This command addresses one device on the I2C-bus and tries to write the values of multiple registers of a connected I2C slave.
        /// Note that this command does not work over daisy-chaining.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <param name="address">Address (0 - 127) of the I2C slave on the I2C bus</param>
        /// <param name="registernumber">Number of the first register in the slave to write data to.</param>
        /// <param name="writebytes">How many bytes to write into the registers (maximum 30).</param>
        /// <param name="writedata">Array holding the data bytes to be written (starting at 0).</param>
        public static void WriteI2CRegisters(Primitive port, Primitive address, Primitive registernumber, Primitive writebytes, Primitive writedata)
        {
            int layer;
            int no;

            // decode parameters
            DecodePort(port, out layer, out no);
            int addr = address;
            int reg  = registernumber;
            int wrt  = writebytes;

            if (wrt <= 0)
            {
                return;   // not writing anything
            }
            if (wrt > 31) // can not write more than 31 bytes in one transmission
            {
                wrt = 31;
            }

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x2F);                // opInit_Bytes
            c.LOCVAR(0);               // prepare sending data from local variable
            c.CONST(3 + wrt);          // number of bytes: the address and the register number and the payload and space for dummy read
            c.CONST(addr & 0x7f);      // first byte: address (from 0 - 127)
            c.CONST(reg & 0xff);       // second byte: register number (from 0 - 255)
            for (int i = 0; i < wrt; i++)
            {
                Primitive v = writedata == 0 ? null : Primitive.GetArrayValue(writedata, new Primitive((double)i));
                int       d = v;
                c.CONST(d & 0xff);    // values to write in registers
            }
            c.CONST(0);               // reserve one more byte to receive unused response into

            c.OP(0x99);               // opInput_Device
            c.CONST(0x09);            // CMD: SETUP = 0x09
            c.CONST(layer);
            c.CONST(no);
            c.CONST(1);                // repeat
            c.CONST(0);                // time
            c.CONST(2 + wrt);          // bytes to write (address and register number and payload)
            c.LOCVAR(0);               // data to write is in local variables, beginning from 0
            c.CONST(1);                // number of bytes to read (one byte is mandatory)
            c.LOCVAR(2 + wrt);         // buffer to read into is local variable

            EV3RemoteControler.DirectCommand(c, 0, 3 + wrt);
        }
Esempio n. 8
0
        /// <summary>
        /// This command addresses one device on the I2C-bus and tries to receive the values of multiple registers of a connected I2C slave.
        /// Note that this command does not work over daisy-chaining.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <param name="address">Address (0 - 127) of the I2C slave on the I2C bus</param>
        /// <param name="registernumber">Number of the first register in the slave to read data from.</param>
        /// <param name="readbytes">How many register to read (maximum 32).</param>
        /// <returns>An array holding the requested number of values. Index starts at 0.</returns>
        public static Primitive ReadI2CRegisters(Primitive port, Primitive address, Primitive registernumber, Primitive readbytes)
        {
            int layer;
            int no;

            // decode parameters
            DecodePort(port, out layer, out no);
            int addr = address;
            int reg  = registernumber;
            int rd   = readbytes;

            if (rd < 1)       // must read at least one byte to not confuse the firmware
            {
                rd = 1;
            }
            if (rd > 32)      // can not read more than 32 bytes
            {
                rd = 32;
            }

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x2F);                // opInit_Bytes
            c.LOCVAR(0);               // prepare sending data from local variable
            c.CONST(1 + 1);            // number of bytes: the address and the register number
            c.CONST(addr & 0x7f);      // first byte: address (from 0 - 127)
            c.CONST(reg & 0xff);       // second byte: register number (from 0 - 255)

            c.OP(0x99);                // opInput_Device
            c.CONST(0x09);             // CMD: SETUP = 0x09
            c.CONST(layer);
            c.CONST(no);
            c.CONST(1);                // repeat
            c.CONST(0);                // time
            c.CONST(2);                // bytes to write (address and register number)
            c.LOCVAR(0);               // data to write is in local variables, beginning from 0
            c.CONST(rd);               // number of bytes to read
            c.GLOBVAR(0);              // buffer to read into is global variable, beginning from 0

            byte[] result = EV3RemoteControler.DirectCommand(c, rd, 2);
            Dictionary <Primitive, Primitive> map = new Dictionary <Primitive, Primitive>();

            for (int i = 0; i < rd; i++)
            {
                map[new Primitive((double)i)] = new Primitive((result != null && result.Length == rd) ? result[rd - 1 - i] : 0);
            }
            return(Primitive.ConvertFromMap(map));
        }
Esempio n. 9
0
        /// <summary>
        /// Stop one or multiple motors. This will also cancel any scheduled movement for this motor.
        /// </summary>
        /// <param name="ports">Motor port name(s)</param>
        /// <param name="brake">"True", if the motor should use the brake.</param>
        public static void Stop(Primitive ports, Primitive brake)
        {
            int layer;
            int nos;

            DecodePortsDescriptor(ports == null?"":ports.ToString(), out layer, out nos);
            int brk = (brake == null?"":brake.ToString()).Equals("true", StringComparison.OrdinalIgnoreCase) ? 1 : 0;

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xA3);
            c.CONST(layer);
            c.CONST(nos);
            c.CONST(brk);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 10
0
        /// <summary>
        /// Read current sensor value where the result from ReadPercent() is not specific enough.
        /// Some sensor modes deliver values that cannot be translated to percentage (for example a color index) or that contain multiple values at once (for example the individual red, green, blue light intensities that make up RGB).
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <param name="values">Requested size of result array</param>
        /// <returns>An array holding the requested number of values. Index starts at 0. Elements that got no data are set to 0.</returns>
        public static Primitive ReadRaw(Primitive port, Primitive values)
        {
            int layer;
            int no;

            DecodePort(port, out layer, out no);

            int _values = values;

            if (_values <= 0)
            {
                return(new Primitive());  // no values requested - just return empty object
            }
            if (_values > 8)
            {
                _values = 8;
            }

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x9E);                // Input_ReadExt
            c.CONST(layer);
            c.CONST(no);
            c.CONST(0);                // 0 = don't change type
            c.CONST(-1);               // -1 = don't change mode
            c.CONST(18);               // FORMAT = raw (32bit)
            c.CONST(_values);          // return desired number of 32bit-values
            for (int i = 0; i < _values; i++)
            {
                c.GLOBVAR(4 * i);      // values should be stored in global variables
            }

            byte[] result = EV3RemoteControler.DirectCommand(c, 4 * _values, 0);

            Dictionary <Primitive, Primitive> map = new Dictionary <Primitive, Primitive>();

            for (int i = 0; i < _values; i++)
            {
                double v = 0;
                if (result != null && i * 4 + 3 < result.Length)
                {
                    v = DecodeRaw(result, i * 4);
                }
                map[new Primitive((double)i)] = new Primitive(v < -1000000000 ? 0:v);
            }
            return(Primitive.ConvertFromMap(map));
        }
Esempio n. 11
0
        /// <summary>
        /// Start playing a simple tone defined by its text representation.
        /// </summary>
        /// <param name="volume">Volume can be 0 - 100</param>
        /// <param name="note">Text defining a note "C4" to "B7" or halftones like "C#5"</param>
        /// <param name="duration">Duration of the tone in milliseconds</param>
        public static void Note(Primitive volume, Primitive note, Primitive duration)
        {
            int vol = volume;
            int dur = duration;

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x63);       // opNote_To_Freq
            c.STRING(note == null ? "":note.ToString());
            c.LOCVAR(0);
            c.OP(0x94);       // opSOUND
            c.CONST(0x01);    // CMD: TONE = 0x01
            c.CONST(vol);
            c.LOCVAR(0);
            c.CONST(dur);
            EV3RemoteControler.DirectCommand(c, 0, 2);
        }
Esempio n. 12
0
        /// <summary>
        /// Checks if one or more motors are currently running.
        /// </summary>
        /// <param name="ports">Motor port name(s)</param>
        /// <returns>"True" if at least one of the motors is running, "False" otherwise.</returns>
        public static Primitive IsBusy(Primitive ports)
        {
            int layer;
            int nos;

            DecodePortsDescriptor(ports == null ? "" : ports.ToString(), out layer, out nos);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xA9);
            c.CONST(layer);
            c.CONST(nos);
            c.GLOBVAR(0);
            byte[] reply = EV3RemoteControler.DirectCommand(c, 1, 0);

            return(new Primitive((reply != null && reply[0] != 0) ? "True" : "False"));
        }
Esempio n. 13
0
        /// <summary>
        /// Move 2 motors synchronously a defined number of degrees.
        /// The two motors are synchronized which means that when one motor experiences some resistance and cannot keep up its speed, the other motor will also slow down or stop altogether. This is especially useful for vehicles with two independently driven wheels which still need to go straight or make a specified turn.
        /// The distance to move is for the motor with the higher speed.
        /// This function returns immediately. You can use IsBusy() to detect the end of the movement or call Wait() to wait until movement is finished.
        /// </summary>
        /// <param name="ports">Names of 2 motor ports (for example "AB" or "CD"</param>
        /// <param name="speed1">Speed value from -100 (full reverse) to 100 (full forward) of the motor with the lower port letter.</param>
        /// <param name="speed2">Speed value from -100 (full reverse) to 100 (full forward) of the motor with the higher port letter.</param>
        /// <param name="degrees">The angle through which the faster motor should rotate.</param>
        /// <param name="brake">"True", if the motors should switch on the brake after movement.</param>
        public static void ScheduleSync(Primitive ports, Primitive speed1, Primitive speed2, Primitive degrees, Primitive brake)
        {
            int layer, nos;

            DecodePortsDescriptor(ports == null ? "" : ports.ToString(), out layer, out nos);
            double spd1 = fclamp(speed1, -100, 100);
            double spd2 = fclamp(speed2, -100, 100);
            int    dgr  = degrees;

            if (dgr < 0)
            {
                dgr = -dgr;
            }
            int brk = (brake == null ? "" : brake.ToString()).Equals("true", StringComparison.OrdinalIgnoreCase) ? 1 : 0;

            if (dgr > 0)
            {
                // the computed values that will be needed by the firmware function
                int spd;
                int trn;

                // motor with lower letter is faster or equally fast and must become master
                if ((spd1 >= 0?spd1:-spd1) >= (spd2 >= 0?spd2:-spd2))
                {
                    spd = (int)spd1;
                    trn = 100 - (int)((100.0 * spd2) / spd1);
                }
                // motor with higher letter is faster and must become master
                else
                {
                    spd = (int)spd2;
                    trn = -(100 - (int)((100.0 * spd1) / spd2));
                }

                ByteCodeBuffer c = new ByteCodeBuffer();
                c.OP(0xB0);        // start scheduled command
                c.CONST(layer);
                c.CONST(nos);
                c.CONST(spd);
                c.CONST(trn);
                c.CONST(dgr);
                c.CONST(brk);
                EV3RemoteControler.DirectCommand(c, 0, 0);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Wait until the current sound has finished playing.
        /// When no sound is playing, this function returns immediately.
        /// </summary>
        public static void Wait()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.Clear();
            c.OP(0x95);       // opSound_Test (BUSY)
            c.GLOBVAR(0);

            for (; ;)
            {
                byte[] reply = EV3RemoteControler.DirectCommand(c, 1, 0);
                if (reply == null || reply[0] == 0)
                {
                    break;
                }
                System.Threading.Thread.Sleep(2);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Send a message to a mailbox on another brick.
        /// </summary>
        /// <param name="brickname">The name of the brick to receive the message. A connection to this brick must be already open for this command to work. You can specify empty Text here, in which case the message will be sent to all connected bricks.</param>
        /// <param name="boxname">Name of the message box on the receiving brick.</param>
        /// <param name="message">The message as a text. Currently only text messages are supported.</param>
        public static void Send(Primitive brickname, Primitive boxname, Primitive message)
        {
            String bn    = boxname == null ? "" : boxname.ToString();
            String brick = brickname == null ? "" : brickname.ToString();
            String msg   = message == null ? "" : message.ToString();

            // send message send request
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xD9);       // opMailbox_Write
            c.STRING(brick);
            c.CONST(0);       // HARDWARE - not used
            c.STRING(bn);
            c.CONST(4);       // 0x04 : DataS Zero terminated string
            c.CONST(1);       // VALUES
            c.STRING(msg);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 16
0
        /// <summary>
        /// Receive the latest message from a local mailbox. When no message is present, the command will block until some message arrives.
        /// The message will then be consumed and the next call to Receive will wait for the next message.
        /// To avoid blocking, you can check with IsAvailable() whether there is a message in the box.
        /// When no message box with the name exists, the command will return "" immediately.
        /// </summary>
        /// <param name="id">Identifier of the local mailbox</param>
        /// <returns>The message as a Text. Currently only text messages are supported.</returns>
        public static Primitive Receive(Primitive id)
        {
            int no = id;

            ByteCodeBuffer c = new ByteCodeBuffer();

            for (; ;)
            {
                // send request that checks for existence and tries to retrieve the message
                c.Clear();
                c.OP(0xDB);        // opMailbox_Test
                c.CONST(no);
                c.GLOBVAR(0);      // return value for the existence test
                c.OP(0xDA);        // opMailbox_Read
                c.CONST(no);
                c.CONST(252);      // maximum string size
                c.CONST(1);        // want to read 1 value
                c.GLOBVAR(1);      // where to store the data (if any available)

                byte[] response = EV3RemoteControler.DirectCommand(c, 253, 0);

                // check response
                if (response != null && response.Length >= 232 && response[0] == 0)
                {
                    // find the null-termination
                    for (int len = 0; len < 252; len++)
                    {
                        if (response[1 + len] == 0)
                        {
                            // extract the message text
                            char[] msg = new char[len];
                            for (int i = 0; i < len; i++)
                            {
                                msg[i] = (char)response[1 + i];
                            }
                            return(new Primitive(new String(msg)));
                        }
                    }
                }

                // when response did not match requirement, retry later
                System.Threading.Thread.Sleep(2);
            }
        }
Esempio n. 17
0
        static FileHandle[] openFiles = new FileHandle[100];   // all file handles in use (0 will not be used at any time)


        private static Primitive OpenWriteImpl(Primitive filename, bool append)
        {
            String f = (filename == null ? "" : filename.ToString());

            if (!f.StartsWith("/"))
            {
                f = "/home/root/lms2012/prjs/" + f;
            }
            lock (openFiles)
            {
                if (findHandle(f) >= 0)       // already have open file with this name
                {
                    return(new Primitive(0));
                }
                int i = findUnusedHandleSlot();
                if (i <= 0)                   // can not hold any more files
                {
                    return(new Primitive(0));
                }

                // create a new empty file. must close handle immediately because it can not be kept accross direct commands
                ByteCodeBuffer c = new ByteCodeBuffer();
                c.OP(0xC0);                   // opFile
                c.CONST(append ? 0x00: 0x02); // OPEN_APPEND = 0x00   OPEN_WRITE = 0x02
                c.STRING(f);
                c.GLOBVAR(0);                 // result: 16-bit handle
                c.OP(0xC0);                   // opFile
                c.CONST(0x07);                // CLOSE = 0x07
                c.GLOBVAR(0);

                // check if could indeed create/append file on the brick
                byte[] reply = EV3RemoteControler.DirectCommand(c, 2, 0);

                if (reply == null || reply.Length < 2 || (reply[0] == 0 && reply[1] == 0))
                {
                    return(new Primitive(0));
                }

                // memorize the open file
                openFiles[i] = new FileHandle(f);

                return(new Primitive((double)i));
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Execute one system command by the command shell of the EV3 linux system. All threads of the virtual machine are halted until the system command is finished.
        /// </summary>
        /// <param name="commandline">The system command.</param>
        /// <returns>Exit status of the command.</returns>
        public static Primitive SystemCall(Primitive commandline)
        {
            String cmd = (commandline == null ? "" : commandline.ToString());

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x60);           // SYSTEM
            c.STRING(cmd);
            c.LOCVAR(0);
            c.OP(0x30);           // MOVE8_8
            c.LOCVAR(1);          // for some reason, the SYSTEM command returns the result value as 8 bit in byte 1 !
            c.GLOBVAR(0);
            byte[] result = EV3RemoteControler.DirectCommand(c, 1, 4);
            if (result == null || result.Length < 1)
            {
                return(new Primitive(-1));
            }
            return(new Primitive((double)result[0]));
        }
Esempio n. 19
0
        /// <summary>
        /// Wait until at least one button is clicked. If a buttons was already clicked before calling this function, it returns immediately.
        /// </summary>
        public static void Wait()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x0c);        // CMD: TESTSHORTPRESS = 0x0C
            c.CONST(0x07);        // any button
            c.GLOBVAR(0);

            for (; ;)
            {
                byte[] response = EV3RemoteControler.DirectCommand(c, 1, 0);
                if (response[0] != 0)
                {
                    return;
                }
                System.Threading.Thread.Sleep(2);
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Query the current rotation count of a single motor for port A.
        /// As long as the counter is not reset it will accurately measure all movements of a motor, even if the motor is driven by some external force while not actively running.
        /// Note that this command does not work for motors connected via daisy-chaining.
        /// </summary>
        /// <returns>The current rotation count in degrees for motor port B</returns>
        public static Primitive GetTacho()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xB3);
            c.CONST(0);
            c.CONST(0);
            c.GLOBVAR(0);
            byte[] reply = EV3RemoteControler.DirectCommand(c, 4, 0);

            int tacho = 0;

            if (reply != null)
            {
                tacho = ((int)reply[0]) | (((int)reply[1]) << 8) | (((int)reply[2]) << 16) | (((int)reply[3]) << 24);
            }

            return(new Primitive(tacho));
        }
Esempio n. 21
0
        /// <summary>
        /// Set two motors to run synchronized at their chosen speed levels and turn in desired direction.
        /// The two motors will be synchronized which means that when one motor experiences some resistance and cannot keep up its speed, the other motor will also slow down or stop altogether. This is especially useful for vehicles with two independently driven wheels which still need to go straight or make a specified turn.
        /// The motors will keep running until stopped by another command.
        /// </summary>
        /// <param name="ports">Name of two motor ports (for example "AB" or "CD").</param>
        /// <param name="speed">Speed value from -100 (full reverse) to 100 (full forward) of the motors.</param>
        /// <param name="turn">Turn value from -100 (full left) to 100 (full right).</param>
        public static void StartSyncTurn(Primitive ports, Primitive speed, Primitive turn)
        {
            int layer, nos;

            DecodePortsDescriptor(ports == null ? "" : ports.ToString(), out layer, out nos);
            int spd = (int)fclamp(speed, -100, 100);
            int trn = (int)fclamp(turn, -100, 100);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xB0);        // turn on synchronized movement
            c.CONST(layer);
            c.CONST(nos);
            c.CONST(spd);
            c.CONST(trn);
            c.CONST(0);
            c.CONST(0);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 22
0
        /// <summary>
        /// Start one or more motors with the requested power or set an already running motor to this power.
        /// </summary>
        /// <param name="ports">Motor port name(s)</param>
        /// <param name="power">Power value from -100 (full reverse) to 100 (full forward).</param>
        public static void StartPower(Primitive ports, Primitive power)
        {
            int layer;
            int nos;

            DecodePortsDescriptor(ports == null ? "" : ports.ToString(), out layer, out nos);
            int pwr = clamp(power, -100, 100);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xAD);       // opOutput_Time_Power
            c.CONST(layer);
            c.CONST(nos);
            c.CONST(pwr);
            c.CONST(0);           // step1
            c.CONST(2147483647);  // step2 (run over three weeks)
            c.CONST(0);           // step3
            c.CONST(0);           // don't brake
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Esempio n. 23
0
        /// <summary>
        /// Checks if there is a message in the specified mailbox.
        /// </summary>
        /// <param name="id">Identifier of the local mailbox</param>
        /// <returns>"True" if there is a message waiting. "False" otherwise.</returns>
        public static Primitive IsAvailable(Primitive id)
        {
            int no = id;
            // send message info request
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xDB);          // opMailbox_Test
            c.CONST(no);
            c.GLOBVAR(0);        // return value
            byte[] response = EV3RemoteControler.DirectCommand(c, 1, 0);
            // check response
            if (response != null && response.Length >= 1 && response[0] == 0)
            {
                return(new Primitive("True"));
            }
            else
            {
                return(new Primitive("False"));
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Write a whole array of numbers in binary fom to the file. The numbers are encoded in IEEE single precision floating point representation.
        /// </summary>
        /// <param name="handle">The file handle (previously obtained from an Open... call)</param>
        /// <param name="size">Number of values to write</param>
        /// <param name="data">Array holding the values</param>
        public static void WriteNumberArray(Primitive handle, Primitive size, Primitive data)
        {
            int hdl = handle;
            int siz = size;

            lock (openFiles)
            {
                if (hdl >= 0 && hdl < openFiles.Length && openFiles[hdl] != null && siz > 0)
                {
                    ByteCodeBuffer c = new ByteCodeBuffer();
                    c.OP(0x2F);                   // opInit_Bytes
                    c.LOCVAR(2);                  // prepare writing data from local variable
                    c.CONST(4 * siz);             //  number of bytes (including the address)
                    for (int i = 0; i < siz; i++) // extract the written data from the array
                    {
                        Primitive v = data == 0 ? null : Primitive.GetArrayValue(data, new Primitive((double)i));
                        double    d = v;
                        //  optional payload floats
                        byte[] b = BitConverter.GetBytes((Single)d);
                        for (int j = 0; j < 4; j++)
                        {
                            c.CONST(b[j]);
                        }
                    }

                    c.OP(0xC0);       // opFile
                    c.CONST(0x00);    // OPEN_APPEND = 0x00
                    c.STRING(openFiles[hdl].name);
                    c.LOCVAR(0);      // result: 16-bit handle
                    c.OP(0xC0);       // opFile
                    c.CONST(0x1D);    // WRITE_BYTES = 0x1D
                    c.LOCVAR(0);
                    c.CONST(4 * siz); // write 4 bytes for each number
                    c.LOCVAR(2);      // where to take the byte from
                    c.OP(0xC0);       // opFile
                    c.CONST(0x07);    // CLOSE = 0x07
                    c.LOCVAR(0);
                    EV3RemoteControler.DirectCommand(c, 0, 2 + 4 * siz);
                }
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Similar to ReadRaw, but returns only a single raw value instead of an array of raw values.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <param name="index">Index of the value that should be picked from the result array (starting with index 0).</param>
        /// <returns>One element of a raw sensor reading.</returns>
        public static Primitive ReadRawValue(Primitive port, Primitive index)
        {
            int layer;
            int no;

            DecodePort(port, out layer, out no);

            int _index = index;

            if (_index < 0 || _index > 7)
            {
                return(new Primitive(0));  // index out of range - just return 0
            }
            int _values = _index + 1;

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x9E);                // Input_ReadExt
            c.CONST(layer);
            c.CONST(no);
            c.CONST(0);                // 0 = don't change type
            c.CONST(-1);               // -1 = don't change mode
            c.CONST(18);               // FORMAT = raw (32bit)
            c.CONST(_values);          // return desired number of 32bit-values
            for (int i = 0; i < _values; i++)
            {
                c.GLOBVAR(4 * i);      // values should be stored in global variables
            }

            byte[] result = EV3RemoteControler.DirectCommand(c, 4 * _values, 0);
            if (result == null || result.Length < 4 * _values)
            {
                return(new Primitive(0));
            }

            double v = DecodeRaw(result, _index * 4);

            return(new Primitive(v < -1000000000 ? 0 : v));
        }
Esempio n. 26
0
        /// <summary>
        /// Switches the mode of a sensor.
        /// Many sensors can work in different modes giving quite different readings. The meaning of each mode number depends on the specific sensor type. For further info, see the sensor list in the appendix.
        /// Note that a sensor will stay in the selected mode even after the program stops and another (or the same) program is started. To avoid confusion, best practice is to always set the mode of all used sensors at program start.
        /// This command blocks execution until mode switching is finished and first sensor data is available.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <param name="mode">New mode to switch to. This only succeeds when the mode is indeed supported by the sensor.</param>
        public static void SetMode(Primitive port, Primitive mode)
        {
            Wait(port);  // make sure a previous mode change/init was already finished before attempting switching mode

            int layer;
            int no;

            DecodePort(port, out layer, out no);
            int mod = mode;

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x9A);                // Input_Read
            c.CONST(layer);
            c.CONST(no);
            c.CONST(0);                // 0 = don't change type
            c.CONST(mod);              // set mode
            c.LOCVAR(0);
            EV3RemoteControler.DirectCommand(c, 0, 1);

            Wait(port);  // make sure mode switch is finished
        }
Esempio n. 27
0
        /// <summary>
        /// Sends data to devices which are attached to the UART (universal asynchronous receiver transmitter) of one of the
        /// sensor ports. This can be useful to send custom commands to custom made sensors/actuators.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <param name="writebytes">Number of bytes to write to the device (maximum 32).</param>
        /// <param name="writedata">Array holding the data bytes to be sent (starting at 0).</param>
        public static void SendUARTData(Primitive port, Primitive writebytes, Primitive writedata)
        {
            int layer;
            int no;

            // decode parameters
            DecodePort(port, out layer, out no);
            int wrt = writebytes;

            if (wrt < 0)
            {
                wrt = 0;
            }
            if (wrt > 32)     // can not write more than 32 bytes in one transmission
            {
                wrt = 32;
            }

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x2F);                   // opInit_Bytes
            c.LOCVAR(0);                  // prepare sending data from local variable
            c.CONST(wrt);                 //  number of bytes
            for (int i = 0; i < wrt; i++) // extract the send bytes from the array
            {
                Primitive v = writedata == 0 ? null : Primitive.GetArrayValue(writedata, new Primitive((double)i));
                int       d = v;
                c.CONST(((int)d) & 0xff);       //  optional payload bytes
            }

            c.OP(0x9F);                // opInput_Write
            c.CONST(layer);
            c.CONST(no);
            c.CONST(wrt);              // bytes to write
            c.LOCVAR(0);               // data to write is in local variables, beginning from 0

            EV3RemoteControler.DirectCommand(c, 0, wrt);
        }
Esempio n. 28
0
        /// <summary>
        /// Move one or more motors with the specified power. The power can be adjusted along the total rotation to get a soft start and a soft stop if needed.
        /// The total angle to rotate the motor is degrees1+degrees2+degrees3. At the end of the movement, the motor stops automatically (with or without using the brake).
        /// This function returns immediately. You can use IsBusy() to detect the end of the movement or call Wait() to wait until the movement is finished.
        /// </summary>
        /// <param name="ports">Motor port name(s)</param>
        /// <param name="power">Power level from -100 (full reverse) to 100 (full forward)</param>
        /// <param name="degrees1">The part of the rotation during which to accelerate</param>
        /// <param name="degrees2">The part of the rotation with uniform motion</param>
        /// <param name="degrees3">The part of the rotation during which to decelerate</param>
        /// <param name="brake">"True", if the motor(s) should switch on the brake after movement</param>
        public static void SchedulePower(Primitive ports, Primitive power, Primitive degrees1, Primitive degrees2, Primitive degrees3, Primitive brake)
        {
            int layer, nos;

            DecodePortsDescriptor(ports == null ? "" : ports.ToString(), out layer, out nos);
            int pwr  = clamp(power, -100, 100);
            int dgr1 = degrees1;
            int dgr2 = degrees2;
            int dgr3 = degrees3;

            if (dgr1 < 0)
            {
                dgr1 = -dgr1;
            }
            if (dgr2 < 0)
            {
                dgr2 = -dgr2;
            }
            if (dgr3 < 0)
            {
                dgr3 = -dgr3;
            }
            int brk = (brake == null ? "" : brake.ToString()).Equals("true", StringComparison.OrdinalIgnoreCase) ? 1 : 0;

            if (nos != 0)
            {
                ByteCodeBuffer c = new ByteCodeBuffer();
                c.OP(0xAC);        // start scheduled movement
                c.CONST(layer);
                c.CONST(nos);
                c.CONST(pwr);
                c.CONST(dgr1);
                c.CONST(dgr2);
                c.CONST(dgr3);
                c.CONST(brk);
                EV3RemoteControler.DirectCommand(c, 0, 0);
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Wait until a sensor has finished its reconfiguration. When no sensor is plugged into the port, this function returns immediately.
        /// Normally you would not need to call this command, because SetMode() blocks until the sensor is ready anyway. It can be useful in special circumstances, like when the mode was switched by a different thread, or when a sensor is plugged into the brick at runtime.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        public static void Wait(Primitive port)
        {
            int layer;
            int no;

            DecodePort(port, out layer, out no);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x9B);    // Input_Test
            c.CONST(layer);
            c.CONST(no);
            c.GLOBVAR(0);
            for (;;)
            {
                byte[] response = EV3RemoteControler.DirectCommand(c, 1, 0);
                if (response == null || response.Length < 1 || response[0] == 0)
                {
                    return;
                }
                System.Threading.Thread.Sleep(2);
            }
        }
Esempio n. 30
0
        /// <summary>
        /// Check if a sensor is currently busy switching mode or in process of initialization. After mode switching a sensor may take some time to become ready again.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <returns>"True" if the sensor is currently busy</returns>
        public static Primitive IsBusy(Primitive port)
        {
            int layer;
            int no;

            DecodePort(port, out layer, out no);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x9B);    // Input_Test
            c.CONST(layer);
            c.CONST(no);
            c.GLOBVAR(0);
            byte[] response = EV3RemoteControler.DirectCommand(c, 1, 0);
            if (response == null || response.Length < 1 || response[0] == 0)
            {
                return(new Primitive("False"));
            }
            else
            {
                return(new Primitive("True"));
            }
        }