Objective:
The color sensor will be set to recognise standard colors (mode 2). If the sensor detects green then the robot will advance for one wheel rotation and otherwise the 'Click' sound will be played once to completion and the robot will then pause. The robot will continue checking until the program is interrupted.
Solution:
This program assumes that have you have downloaded all the standard Lego sound and image files to the brick in accordance with the instructions on this page.
'Connect color sensor to port 3
Sensor.SetMode(3,2) 'Set color sensor to mode 2: detect standard colors
While "True"
ColorCode=Sensor.ReadRawValue(3,0)
If ColorCode=3 Then 'color 3 = green
Motor.Move("BC",50,360,"True")
Else
Speaker.Play(100,"Sounds/Click")
'File and folder names in the brick are case-sensitive!
Speaker.Wait() 'Wait until the sound finishes playing
Program.Delay(1000) 'pause 1 second
EndIf
EndWhile
Notes:
Color sensor mode 2 (recognise standard colors) is fussy about colors - your best chance of success is to use green Lego pieces.
Objective:
The user will press the touch sensor several times and then, 5 seconds after the program was launched, the robot will move straight forward with speed 50 for a number of wheel rotations equal to the number of times the sensor was pressed.
Solution:
The official EV3-G solution to this problem (shown below) is to use a thread (a branch of code that can run simultaneously with other threads) to interrupt the main loop after 5 seconds. I think the best EV3 Basic solution would not use threads, partly because I am not sure that EV3 Basic has a neat way for code in a thread to interrupt a loop in a different thread.
Counting the number of presses needs a little thought. Each complete 'press' is really a 'press and release' - this double action is what the Lego software calls a 'bump'. We could look for the presses or releases or both - my program looks for releases. When the touch sensor button is released then its value (as read with Sensor.ReadPercent) will change from 100 to 0, so my program compares the current value of the sensor ('CurrentState') with the value that it had the last time the While loop was run through ('PreviousState'). If the current value is 0 and the previous value was 100 then the button has just been released and we can add one to the press count ('Presses').
Sensor.SetMode(1,0) 'Set the touch sensor on port 1 to mode 0
Presses=0 'Number of presses (actually releases)
PreviousState=0
While EV3.Time<5000 'loop until 5 seconds have passed
CurrentState=Sensor.ReadPercent(1)
If PreviousState=100 And CurrentState=0 Then 'button has been released
Presses=Presses+1
EndIf
PreviousState=CurrentState 'Ready for next loop
Program.Delay(10)
EndWhile
Motor.Move("BC",50,Presses*360,"True")
Notes:
Recall that Sensor.ReadPercent() returns 0 when the button is not pressed and 100 when it is pressed. This program demonstrates an excellent way of detecting and counting 'bumps' or touch sensor button releases.
Here is the official EV3-G solution to the same problem. Again, compare the EV3 Basic solution with the EV3-G solution and ask yourself which seems to be the clearer, neater solution (taking into account that the EV3-G solution has no comments)...
Objective:
The exact procedure will be this:
User brings a 'black' surface close to the sensor and notes that the displayed value is not close to 0
User presses the touch sensor button to indicate that the dark surface is in place
Program recalibrates the sensor reading to 0% for that surface
Program plays a Click sound to indicate that the recalibration is complete
User checks that a value very close to 0 is indeed displayed when the 'black' object is in place
User brings a 'white' surface close to the sensor and notes that the displayed value is not close to 100
User presses the touch sensor button to indicate that the 'white' surface is in place
Program recalibrates the sensor reading to 100% for that surface
Program plays a Click sound to indicate that the recalibration is complete
User checks that a value very close to 100 is indeed displayed when the 'white' object is in place AND that a value very close to 0 is indeed displayed when the 'black' object is in place
User presses the touch sensor button to reset the sensor to its factory calibration
Program resets the sensor
Program plays a Click sound to indicate that the resetting is complete.
User checks that the original reflectance values are again displayed for both the black and the white surfaces
Solution:
As in the EV3-G solution, we will use a separate thread to continuously display the sensor value (the ADJUSTED sensor value, that is, after the first and second clicks).
It is normal that after the adjustment has been made for 'black' the displayed value will then be negative when no object is near the color sensor.
Sensor.SetMode(1,0) 'Set touch sensor on port 1 to mode 0
Sensor.SetMode(3,0) 'Set color sensor on port 3 to mode 0
Thread.Run = DISPLAYVALUE 'launch the thread called DISPLAYVALUE
BlackAdjust=0 'BlackAdjust value will be subtracted from sensor reading
WhiteAdjust=1 'Adjusted-for-black reading will be divided by WhiteAdjust
' to give a reading which is now adjusted for both black AND white
Sub DISPLAYVALUE 'Continuously display the (adjusted) sensor reading
While "True"
LCD.StopUpdate()
LCD.Clear()
LCD.Text(1,45,55,2,Math.Round((Sensor.ReadPercent(3)-BlackAdjust)/WhiteAdjust))
LCD.Update()
EndWhile
EndSub
Sub WaitForBump
Loop="True"
While Loop
CurrentState=Sensor.ReadPercent(1)
If PreviousState=100 And CurrentState=0 Then 'button has been released
Loop="False" 'button has just been released so stop looping
EndIf
PreviousState=CurrentState 'Ready for next loop
Program.Delay(10)
EndWhile
EndSub
PreviousState=0
WaitForBump()
BlackAdjust=Sensor.ReadPercent(3) 'BlackAdjust value will be subtracted from
'sensor reading to give 'adjusted-for-black' reading which is now displayed
Speaker.Play(100,"Sounds/Click") 'File names on the brick are case-sensitive!
Speaker.Wait()
WaitForBump()
WhiteAdjust=(Sensor.ReadPercent(3)-BlackAdjust)/100
'Adjusted-for-black reading is divided by WhiteAdjust/100 to give a reading
'which is now adjusted for both black and white and which is now displayed.
'Bring your black and white objects near the sensor and they should now
'give adjusted readings of 0 and 100 (or very close)
Speaker.Play(100,"Sounds/Click")
Speaker.Wait()
WaitForBump()
BlackAdjust=0 'reset adjustment values
WhiteAdjust=1
Speaker.Play(100,"Sounds/Click")
Speaker.Wait()
Program.Delay(20000) 'You have 20 seconds to check that the
'initial values for your black and 'white surfaces have returned...
Notes:
This is a relatively long and clumsy EV3 Basic solution - perhaps you can find a better one?
This program neatly puts the code for checking for a 'bump' of the touch sensor button into a subroutine (subprogram) called WaitForBump to avoid having to put all that code into the program three times. Instead, the subroutine is simply called into action at the appropriate times with the statement WaitForBump().
Here is the official EV3-G solution to this exercise. Note how the recalibration blocks (such as the one just to the left of the 'play Click' block in the top line) do not get any information directly from the sensor, as most people would expect, they have to be fed a number through a data wire in order to do the recalibration.
Objective:
In computer programming the logical (or 'Boolean') values are 'true' and 'false'. Logical operators include AND, and OR.
When the AND operator is applied to two expressions the output will be 'true' only if both the expressions are true.
When the OR operator is applied to two expressions the output will be 'true' if either (or both) of the expressions are true.
Objective:
Solution:
The color sensor must be detecting black
The object must be more than 6 cm away.
The object must be less than 25 cm away.
Sensor.SetMode(4,0) 'Set ultrasound sensor on port 4 to mode 0: distance in mm
Sensor.SetMode(3,2) 'Set color sensor on port 3 to mode 2: detect standard colors
Motor.Start("BC",50)
While "True" 'forever
Distance=Sensor.ReadRawValue(4,0)/10
Color=Sensor.ReadRawValue(3,0)
If Distance>6 And Distance<25 And Color = 1 Then '1 = black
Motor.Stop("BC", "True")
Program.End()
EndIf
EndWhile
Notes:
It would have been possible to save several lines by putting all the conditions in the While line but the line would have then been long and hard to read.
Small Basic does not include the 'NOT' operator. If this is a problem for you then try running this workaround:
Logical="True"
Not = "True=False;False=True" 'an array
LCD.Clear()
LCD.Text(1,50,55,2,Not[Logical]) 'notice the square brackets
Program.Delay(3000)
Here is the official EV3-G solution to this exercise. It demonstrates how to use the 'Range' block and the 'Logic' block.
In the video that accompanies the official EV3-G exercise the robot is initially far from the reflecting object and over a white mat. The conditions are met for the robot to move forward. It passes over a black line but does not stop because the robot is not yet within the defined range. It continues moving forward until it reaches a second black line and there it stops because it detects black AND the robot is within the defined range.
It seems to me the above EV3-G program has an error. It should not be necessary to repeatedly turn on the motors. Shouldn't the first motor block be placed before the loop, not within it?
Recall that it is vitally important that the gyro sensor should be absolutely still when the brick is powered up or the sensor plugged in, otherwise the sensor reading will wander away from the correct value.
Objective:
Solution:
Sensor.SetMode(2,0) 'Set gyro sensor on port 2 to mode 0
Motor.StartSync("BC",10,-10)'Robot slowly turns to the right on the spot
While Sensor.ReadRawValue(2,0) < 45
EndWhile
Motor.Stop("BC", "True")
'Small Basic trig functions like cos() work in RADIANS
Radians=Sensor.ReadRawValue(2,0)/57.3 'convert to radians.1 rad = 57.3°
Length = 25/Math.Cos(Radians) 'calculate length of hypotenuse
Rots=Length/17.6 'calculate wheel rotations (wheel circumference=17.6cm)
Motor.Move("BC",30, Rots*360, "True")'convert wheel rotations to degrees
Notes:
Once again, know that Small Basic trig functions work in radians, not degrees, and that 1 rad = 57.3°.
The above solution is an awkward mix of degrees and radians, but this could not be avoided.
Don't confuse the angle that the robot turns with the angle that the wheels turn.
Here is the official EV3-G solution to this exercise. Note that EV3-G trig functions use degrees, not radians.
Objective:
First, the user will give coded instructions to the robot by showing it a sequence of four colors. Each color is an instruction to carry out a certain movement. Then the robot will carry out the corresponding movements.
More specifically, the procedure will be:
The robot makes a 'Click' sound to indicate that it is ready.
The user presses the touch sensor button to indicate that (s)he is also ready.
The program waits until the user presents an object with a valid color (blue, green or yellow) to the color sensor.
When the color sensor recognises a valid color it stores the corresponding color code number in an array. An 'array' is a variable that can hold multiple values.
The above sequence is repeated four times to store four color codes in the same array.
The robot then plays the sound 'Horn 2' at 100% volume, waiting for the sound to finish playing before continuing.
Then the program begins reading the contents of the array, carrying out the corresponding movement for each color code.
The program stops when all four color codes have been read and the corresponding four movements carried out.
If the user presents a blue object then the robot should turn turn 90° left.
If the user presents a green object then the robot should go straight forward for one wheel rotation.
If the user presents a yellow object then the robot should turn 90° right.
Solution:
We will use an array to store the four color code numbers. An 'array' is a variable that can hold multiple values. In EV3 Basic you can have an array of numbers or an array of text strings but not an array of logical values. (This contrasts with EV3-G in which, I believe, you can have an array of numbers or an array of logical values but not an array of text strings.)
The order of the elements in an array is important, so the elements in an array are like a list. Each element in the list has an index number, and the first element has index number zero. Here is an example of a numeric array: [5; 2.7; 3.1] . This array has three elements - we say the array has a 'length' of three. The elements have index numbers 0, 1 and 2, so the third element has index number 2 not 3.
This exercise uses standard Lego sounds. It is assumed that have you have downloaded all the standard Lego sound and image files to the brick in accordance with the instructions on this page.
'Set color sensor on port 3 to mode 2: detect standard colors
Sensor.SetMode(3,2)
Sub WaitForBump
PreviousState=0
Loop="True"
While Loop
CurrentState=Sensor.ReadPercent(1)
If PreviousState=100 And CurrentState=0 Then 'button has been released
Loop="False" 'button has just been released so stop looping
EndIf
PreviousState=CurrentState 'Ready for next loop
Program.Delay(10)
EndWhile
EndSub
ColorSounds[2]="Blue" 'NOT IN EV3-G VERSION
ColorSounds[3]="Green"
ColorSounds[4]="Yellow"
For i=0 to 3
Speaker.Play(100,"Sounds/Click")
Speaker.Wait()
WaitForBump()
'Wait for a valid color to be detected
Loop="True"
While Loop
ColorCode=Sensor.ReadRawValue(3,0)
If ColorCode=2 OR ColorCode=3 OR ColorCode=4 Then'blue,green,yellow
ColorArray[i]=ColorCode
Speaker.Play(100,"Sounds/"+ColorSounds[ColorCode]) 'NOT IN EV3-G
Speaker.Wait() 'NOT IN EV3-G VERSION
Loop="False" 'prevent loop running again
EndIf
EndWhile
EndFor
Speaker.Play(100,"Sounds/Horn 2")
Speaker.Wait()
For k=0 to 3
If ColorArray[k]=2 Then 'blue
Motor.MoveSync("BC",0,50,345,"True")
ElseIf ColorArray[k]=3 Then 'green
Motor.Move("BC",50,360,"True")
ElseIf ColorArray[k]=4 Then 'yellow
Motor.MoveSync("BC",50,0,345,"True")
EndIf
EndFor
Notes:
I added a feature to my program which is not found in the official EV3-G solution to this problem (shown below): I made the robot speak the color when the color sensor recognised it. The lines I added are clearly highlighted.
Here is the official EV3-G solution to this problem:
Conclusion
You have now completed the EV3 Basic versions of the 'Basics' and 'Beyond Basics' exercises that are included in the Education version of the EV3 software. You have seen how EV3 Basic is almost always capable of performing the same tasks as the standard Lego EV3-G software, while at the same time giving you valuable experience of textual programming. But EV3 Basic is capable of handling programs that go beyond the capabilities of the standard Lego software (such as programs that allow for an interaction between the robot and the Small Basic graphical window). Going beyond what EV3-G can do will be the theme of the next set of exercises... so stay tuned!