Пример #1
0
        /// <summary>
        /// Write one line of text to the file. The line will be encoded with ISO-8859-1 encoding and will be terminated with a newline-character (code 10).
        /// </summary>
        /// <param name="handle">The file handle (previously obtained from an Open... call)</param>
        /// <param name="text">The text to write to the file</param>
        public static void WriteLine(Primitive handle, Primitive text)
        {
            int    hdl = handle;
            String txt = (text == null ? "" : text.ToString());

            if (txt.Length > 251)
            {
                txt = txt.Substring(0, 251);   // delimit line size to be written to 251 (which is also string size limit for VM-version)
            }
            lock (openFiles)
            {
                if (hdl >= 0 && hdl < openFiles.Length && openFiles[hdl] != null)
                {
                    ByteCodeBuffer c = new ByteCodeBuffer();
                    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(0x06);   // WRITE_TEXT = 0x06
                    c.LOCVAR(0);
                    c.CONST(6);      // 0x06 : Line feed used as delimiter
                    c.STRING(txt);
                    c.OP(0xC0);      // opFile
                    c.CONST(0x07);   // CLOSE = 0x07
                    c.LOCVAR(0);
                    EV3RemoteControler.DirectCommand(c, 0, 2);
                }
            }
        }
Пример #2
0
        // must be called while holding a lock on commandBuffer
        private static void CheckFlush()
        {
            if ((commandBuffer.Length > 0 && autoflush) ||
                (commandBuffer.Length > 700))                   // prevent to exceed 1024 bytes limit for usb communication
            {
                // add a check that the program is still running
                commandBuffer.OP(0x0C);            // opProgram_Info
                commandBuffer.CONST(0x16);         //  CMD: GET_STATUS = 0x16
                commandBuffer.CONST(1);            //  program slot 1 = user slot
                commandBuffer.LOCVAR(0);           //  result -> when this reseives 0x40, the program was stopped
                commandBuffer.OP(0x6C);            // opJR_EQ8
                commandBuffer.LOCVAR(0);           // running state is in local variable 0
                commandBuffer.CONST(0x40);         // check if program was stopped
                commandBuffer.CONST(2);            // jump over next 2 opocodes

                // trigger the update
                commandBuffer.OP(0x84);           // UI_DRAW
                commandBuffer.CONST(0x00);        // CMD: UPDATE = 0x00

                commandBuffer.OP(0x01);           // NOP  - need this as branch target

                EV3RemoteControler.DirectCommand(commandBuffer, 0, 1);

                commandBuffer.Clear();
            }
        }
Пример #3
0
        internal static Primitive NativeCode(Primitive command)
        {
            String cmd = (command == null) ? "" : command.ToString().Trim();

            if (cmd.Length == 0)
            {
                return(new Primitive(-1));
            }

            // if have not downloaded the native code, do it now
            lock (hasDownloaded)
            {
                if (!hasDownloaded[0])
                {
                    EV3RemoteControler.InstallNativeCode();
                    hasDownloaded[0] = true;
                }
            }

            // start native code process (and wait for termination)
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x60);            // opSYSTEM
            c.STRING("/tmp/nativecode " + command);
            c.GLOBVAR(0);          // result code

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

            return(new Primitive(result[1]));  // for some reasons, the program result is delivered in byte 1
        }
Пример #4
0
        /// <summary>
        /// Move 2 motors synchronously in desired direction 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="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>
        /// <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 ScheduleSyncTurn(Primitive ports, Primitive speed, Primitive turn, Primitive degrees, Primitive brake)
        {
            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);
            int dgr = degrees;

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

            if (dgr > 0)
            {
                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);
            }
        }
Пример #5
0
        /// <summary>
        /// Get the numerical type identifier of a currently connected sensor.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <returns>Sensor type identifier (for example, 16 for a touch sensor)</returns>
        public static Primitive GetType(Primitive port)
        {
            int layer;
            int no;

            DecodePort(port, out layer, out no);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x99);                // INPUT_DEVICE
            c.CONST(0x05);             // CMD: GET_TYPEMODE = 0x05
            c.CONST(layer);
            c.CONST(no);
            c.GLOBVAR(0);
            c.GLOBVAR(1);
            byte[] result = EV3RemoteControler.DirectCommand(c, 2, 0);

            if (result == null || result.Length < 2)
            {
                return(new Primitive(0));
            }
            else
            {
                return(new Primitive(result[0]));
            }
        }
Пример #6
0
        /// <summary>
        /// Get the name and mode of a currently connected sensor.
        /// This function is mainly intended for diagnostic use because you normally know which sensor is plugged to which port on the model.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <returns>Description text (for example, "TOUCH")</returns>
        public static Primitive GetName(Primitive port)
        {
            int layer;
            int no;

            DecodePort(port, out layer, out no);

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x99);                // INPUT_DEVICE
            c.CONST(0x15);             // CMD: GET_NAME = 0x15
            c.CONST(layer);
            c.CONST(no);
            c.CONST(32);
            c.GLOBVAR(0);
            byte[] result = EV3RemoteControler.DirectCommand(c, 32, 0);

            if (result == null)
            {
                return(new Primitive(""));
            }
            else
            {
                return(new Primitive(Encoding.ASCII.GetString(result).Replace((char)0, ' ').Trim()));
            }
        }
Пример #7
0
        /// <summary>
        /// Write a single byte of data to the file.
        /// </summary>
        /// <param name="handle">The file handle (previously obtained from an Open... call)</param>
        /// <param name="data">One byte to write (value of 0 - 255)</param>
        public static void WriteByte(Primitive handle, Primitive data)
        {
            int hdl = handle;
            int dta = data;

            lock (openFiles)
            {
                if (hdl >= 0 && hdl < openFiles.Length && openFiles[hdl] != null)
                {
                    ByteCodeBuffer c = new ByteCodeBuffer();
                    c.OP(0x34);       // opMove16_8
                    c.CONST(dta);
                    c.LOCVAR(2);
                    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(1);      // write 1 byte
                    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, 3);
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Create a mailbox on the local brick that can receive messages from other bricks.
        /// Only after creation of the box incoming messages can be stored for retrieval.
        /// There is a total limit of 30 mailboxes that can be created.
        /// </summary>
        /// <param name="boxname">Name of the message box to be created.</param>
        /// <returns>A numerical identifier of the mailbox. This is needed to actually retrieve messages from the box.</returns>
        public static Primitive Create(Primitive boxname)
        {
            String bn = boxname == null ? "" : boxname.ToString();
            int    no = -1;

            lock (sync)
            {
                // determine next number to use
                if (numboxes < 30)
                {
                    no = numboxes;
                    numboxes++;
                }
            }

            if (no >= 0)
            {
                // send box creation request
                ByteCodeBuffer c = new ByteCodeBuffer();
                c.OP(0xD8);       // opMailbox_Open
                c.CONST(no);
                c.STRING(bn);
                c.CONST(4);       // 0x04 : DataS Zero terminated string
                c.CONST(0);       // FIFOSIZE – Not used at this point
                c.CONST(0);       // VALUES – Not used
                EV3RemoteControler.DirectCommand(c, 0, 0);
            }
            return(new Primitive(no));
        }
Пример #9
0
        /// <summary>
        /// Check which buttons were clicked since the last call to GetClicks and returns a text containing their letters.
        /// The 'clicked' state of the buttons is then removed. Also a sound is emitted from the brick when a click was detected.
        /// </summary>
        /// <returns>A text containing the letters of the clicked buttons (can be empty)</returns>
        public static Primitive GetClicks()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x01);        // CMD: SHORTPRESS = 0x01
            c.CONST(0x01);        // up
            c.GLOBVAR(1);
            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x01);        // CMD: SHORTPRESS = 0x01
            c.CONST(0x02);        // enter
            c.GLOBVAR(2);
            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x01);        // CMD: SHORTPRESS = 0x01
            c.CONST(0x03);        // down
            c.GLOBVAR(3);
            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x01);        // CMD: SHORTPRESS = 0x01
            c.CONST(0x04);        // right
            c.GLOBVAR(4);
            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x01);        // CMD: SHORTPRESS = 0x01
            c.CONST(0x05);        // left
            c.GLOBVAR(5);
            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x01);        // CMD: SHORTPRESS = 0x01
            c.CONST(0x07);        // any other button
            c.GLOBVAR(0);

            return(CreateFlags(EV3RemoteControler.DirectCommand(c, 6, 0)));
        }
Пример #10
0
        /// <summary>
        /// Query the current speed of a single motor.
        /// </summary>
        /// <param name="port">Motor port name</param>
        /// <returns>Current speed in range -100 to 100</returns>
        public static Primitive GetSpeed(Primitive port)
        {
            int layer;
            int no;

            DecodePortDescriptor(port == null ? "" : port.ToString(), out layer, out no);

            if (no < 0)
            {
                return(new Primitive(0));
            }
            else
            {
                ByteCodeBuffer c = new ByteCodeBuffer();
                c.OP(0xA8);
                c.CONST(layer);
                c.CONST(no);
                c.GLOBVAR(4);
                c.GLOBVAR(0);
                byte[] reply = EV3RemoteControler.DirectCommand(c, 5, 0);

                int spd = reply == null ? 0 : (sbyte)reply[4];
                if (inverted[layer * 4 + no])
                {
                    spd = -spd;
                }
                return(new Primitive(spd));
            }
        }
Пример #11
0
        /// <summary>
        /// Read the current sensor value and apply some sensible percentage scaling.
        /// Most sensors can translate the current reading to a meaningful single percentage value like light intensity or button press state.
        /// </summary>
        /// <param name="port">Number of the sensor port</param>
        /// <returns>The percentage value (For example, the touch sensor gives 100 for pressed and 0 for non-pressed)</returns>
        public static Primitive ReadPercent(Primitive port)
        {
            int layer;
            int no;

            DecodePort(port, out layer, out no);

            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(-1);               // -1 = don't change mode
            c.GLOBVAR(0);
            byte[] result = EV3RemoteControler.DirectCommand(c, 1, 0);

            if (result == null || result.Length < 1)
            {
                return(new Primitive(0));
            }
            else
            {
                int v = result[0];
                return(new Primitive(v > 127 ? 0 : v));
            }
        }
Пример #12
0
        /// <summary>
        /// Similar to ReadRawValue, but returns only a first raw value for port 2. Has a high data return rate.
        /// </summary>
        /// <returns>First element of a raw sensor reading</returns>
        public static Primitive Raw1()
        {
            int _values = 1;

            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x9E);                // Input_ReadExt
            c.CONST(0);
            c.CONST(0);
            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, 0 * 4);

            return(new Primitive(v < -1000000000 ? 0 : v));
        }
Пример #13
0
        /// <summary>
        /// Wait until the specified motor(s) has finished a "Schedule..." or "Move..." operation.
        /// Using this method is normally better than calling IsBusy() in a tight loop.
        /// </summary>
        /// <param name="ports">Motor port name(s)</param>
        public static void Wait(Primitive ports)
        {
            int layer, nos;

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

            if (nos != 0)
            {
                ByteCodeBuffer c = new ByteCodeBuffer();
                c.Clear();
                c.OP(0xA9);
                c.CONST(layer);
                c.CONST(nos);
                c.GLOBVAR(0);

                for (; ;)
                {
                    byte[] reply = EV3RemoteControler.DirectCommand(c, 1, 0);
                    if (reply == null || reply[0] == 0)
                    {
                        break;
                    }
                    System.Threading.Thread.Sleep(2);
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Query the current rotation count of a single motor.
        /// 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>
        /// <param name="port">Motor port name</param>
        /// <returns>The current rotation count in degrees</returns>
        public static Primitive GetCount(Primitive port)
        {
            int layer, no;

            DecodePortDescriptor(port == null ? "" : port.ToString(), out layer, out no);

            if (no < 0)
            {
                return(new Primitive(0));
            }
            else
            {
                ByteCodeBuffer c = new ByteCodeBuffer();
                c.OP(0xB3);
                c.CONST(layer);
                c.CONST(no);
                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);
                }

                if (inverted[layer * 4 + no])
                {
                    tacho = -tacho;
                }
                return(new Primitive(tacho));
            }
        }
Пример #15
0
        /// <summary>
        /// Stop any currently playing sound or tone.
        /// </summary>
        public static void Stop()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x94);       // opSOUND
            c.CONST(0x00);    // CMD: BREAK = 0x00
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Пример #16
0
        /// <summary>
        /// Remove any clicked-state of all buttons. Subsequent calls to GetClicks will only deliver the buttons that were clicked after the flush.
        /// </summary>
        public static void Flush()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x83);           // UI_BUTTON
            c.CONST(0x04);        // CMD: FLUSH = 0x04
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Пример #17
0
        /// <summary>
        /// Set the rotation count of motor port A to 0.
        /// </summary>
        public static void ResetCount()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xB2);
            c.CONST(0);
            c.CONST(1); // nos
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Пример #18
0
        /// <summary>
        /// Check whether the speaker is still busy playing a previous sound.
        /// </summary>
        /// <returns>"True", if there is a sound still playing, "False" otherwise</returns>
        public static Primitive IsBusy()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0x95);       // opSound_Test (BUSY)
            c.GLOBVAR(0);
            byte[] reply = EV3RemoteControler.DirectCommand(c, 1, 0);
            return(new Primitive((reply == null || reply[0] == 0) ? "False" : "True"));
        }
Пример #19
0
        private static void schedulesteer(Primitive ports, double speed, double turn, double degrees, int brake)
        {
            int layer, nos;

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

            if (dgr < 0)
            {
                dgr = -dgr;
            }

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

            if (dgr > 0 && 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);        // start scheduled command
                c.CONST(layer);
                c.CONST(nos);
                c.CONST((int)speed);
                c.CONST((int)turn);
                c.CONST(dgr);
                c.CONST(brake);
                EV3RemoteControler.DirectCommand(c, 0, 0);
            }
        }
Пример #20
0
        /// <summary>
        /// Sets the direct polarity for motor to port A
        /// </summary>
        public static void SetReversPolarity()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xA7);
            c.CONST(0);
            c.CONST(1); // nos
            c.CONST(-1);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Пример #21
0
        /// <summary>
        /// Stop motor port A. This will also cancel any scheduled movement for this motor.
        /// Motor will stop completely
        /// </summary>
        public static void OffAndBrake()
        {
            ByteCodeBuffer c = new ByteCodeBuffer();

            c.OP(0xA3);
            c.CONST(0);
            c.CONST(1);
            c.CONST(1);
            EV3RemoteControler.DirectCommand(c, 0, 0);
        }
Пример #22
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);
        }
Пример #23
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);
        }
Пример #24
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));
        }
Пример #25
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);
        }
Пример #26
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);
        }
Пример #27
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));
        }
Пример #28
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);
        }
Пример #29
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));
        }
Пример #30
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"));
        }