
I was wondering if it would be possible to use B4J to program the Lego Mindstorms EV3 Brick for some time. So, some weeks ago, I finally spend a couple of evenings looking into it. And yes, B4J goes Robotics! It uses a modified LeJOS Firmware.
I upgraded LeJOS to support Java 1.8, which is probably the most technical part of the project. I cannot provide it here, as it depends on your Java version but if you follow the next steps, you can build your own. This is done on a Windows PC:
Upgrading the LeJOS Firmware to use Java 1.8
The following procedure will install the java 8 environment compatible with leJOS 9.0 from windows 7. The only extra tool needed is 7ZIP (a free tool) which can generate tar and gz format. In the following I use a temporary directoyr as F:\temp. Replace it with your own temp directory wherever it appears.
- Go to java site http://www.oracle.com/technetwork/java/ … 82511.html
- Create an account if you dont have one then Accept Licensee agreement and download ejdk-8-xxxxxxx-linux-arm-sflt-xxxxxxxx.tar.gz or the latest java8 jre for EV3.
- Unzip this file in your F:\temp directory. For simpler process you may rename the extracted directory as ejdk8. Run 7zip as administrator!
- Go to directory ejdk8\ejdk1.8.0\bin. Save the file jrecreate.bat. Now right click on jrecreate.bat and select “modify”. Add one first line to the bat file as SET JAVA_HOME=C:\Progra~2\Java\jdk1.8.xxxx. this is where java8 is installed on my system. Program~2 stand for Program Files (x86) but is easier to type.
- Start a command window: Start->All prog->Accessory->commands.
- In this window type in the following commands
F:
cd temp
cd ejdk8\ejdk1.8.0\bin
jrecreate.bat –dest newjre –profile compact2 –vm clientIt should start creating the new jre files in the directory “newjre” under ejdk8\ejdk1.8.0\bin
Wait for the final message.
Close the command window.
- With file explorer go to F:\temp\ejdk8\ejdk1.8.0\bin. Copy “newjre” directory back to F:\temp
- Rename the “newjre” directory as something expected by LeJOS such as
ejre-8-b132-linux-arm-sflt
- Right click on it. Open with 7ZIP and add to archive. Select tar format. It will create ejre-8-b132-linux-arm-sflt.tar file.
- Right click on tar copy then add archive with gzip format. It will create ejre-8-b132-linux-arm-sflt.tar.gz. You have created the JRE file for java8 expected by EV3.
- Insert your SD card and format it.
- Copy the ejre-8-b132-linux-arm-sflt.tar.gz under the sd card top directory.
- Go to C:\Program Files\leJOS EV3
- Now remove the SD from PV and insert the card into the EV3 brick then power it. Wait for the end of the install (about 10mn).
If anything goes wrong, format again the SD, empty the F:\temp directory and restart at step 3. if it persist try another SD card.
Your brick is ready!
Next I wrote a B4J wrapper for the basics like motors, sensors etc. This project is just a hobby and may grow in the future. But I just wanted to share this first video (badly directed so no Oscars here, unless…)
Obviously, I wanted to test out my code, but I had to build a bot first. Well, I was in for a surprise! It took me over 3 hours to build EV3D4 and I can tell you, I’m not a very patient person so I may have taken some shortcuts in the construction.
What happens in the video:
1. I uploaded the B4J created .jar file to the brick via ssh and I’m ready to start it.
2. After some time, it runs (on the brick shows a disclamer and waits for a key).
3. I disconnect the brick, put it on the ground and press a button on the brick.
4. I programmed the IR sensor so if it sees a wall, it turns away, else it keeps going.
Fun fact is you can use B4J-Bridge.jar on the brick!
This is handy as debugging a Brick is a b*tch. You must have a lot of patience and prepared to restart your brick A LOT. This is not a B4J limitation, just to say how unstable programming a Brick is in general.
Coding is straightforward in B4J (this is all the code I wrote, including turning if it is about to hit a wall):
Sub Process_Globals
Private StartTimer As Timer
Public EV3 As ABLegoEV3
Public LeftMotor As ABLLargeRegulatedMotor
Public RightMotor As ABLLargeRegulatedMotor
Public Sensor As ABLIRSensor
Public sp As ABLSensorMode
Public control As Int = 0
Public distance As Int = 255
End Sub
Sub AppStart (Args() As String)
LeftMotor.Initialize("B")
RightMotor.Initialize("C")
LeftMotor.ResetTachoCount
RightMotor.resetTachoCount
LeftMotor.rotateTo(0)
RightMotor.rotateTo(0)
LeftMotor.Speed = 400
RightMotor.Speed = 400
LeftMotor.Acceleration = 800
RightMotor.Acceleration = 800
Log("starting sensor")
Sensor.Initialize("S4")
sp = Sensor.DistanceMode
IntroMessage
StartTimer.Initialize("StartTimer", 100)
StartTimer.Enabled = True
StartMessageLoop
End Sub
Sub StartTimer_Tick
' read the sensor
Dim sample(sp.sampleSize) As Float
control = Sensor.getRemoteCommand(0)
sp.fetchSample(sample, 0)
distance = sample(0)
Log("Control: " & control & " Distance: " & distance)
If distance < 70 Then
Log("A wall!")
EV3.Button.LEDPattern(2)
LeftMotor.rotate2(-180, True) ' start Motor.B rotating backward
RightMotor.rotate(-180) ' rotate C farther To make the turn
If Bit.And(DateTime.Now, 1) <> 0 Then
LeftMotor.rotate2(-180, True) ' start Motor.B rotating backward
RightMotor.rotate(180) ' rotate C farther To make the turn
Else
RightMotor.rotate2(-180, True) ' start Motor.B rotating backward
LeftMotor.rotate(180) ' rotate C farther To make the turn
End If
Else
Log("Let's walk")
EV3.Button.LEDPattern(1)
LeftMotor.Speed = 400
RightMotor.Speed = 400
LeftMotor.Backward ' my motors are installed inverted on this robot
RightMotor.Backward
End If
End Sub
Sub IntroMessage()
Dim g As ABLGraphicsLCD = EV3.GraphicsLCD
g.clear
g.drawString("Bumper Car Demo", 5, 0, 0)
g.Font = g.Font.SmallFont
g.drawString("Demonstration of the Behavior", 2, 20, 0)
g.drawString("subsumption classes. Requires", 2, 30, 0)
g.drawString("a wheeled vehicle with two", 2, 40, 0)
g.drawString("independently controlled", 2, 50, 0)
g.drawString("motors connected to motor", 2, 60, 0)
g.drawString("ports B and C, and an", 2, 70, 0)
g.drawString("infrared sensor connected", 2, 80, 0)
g.drawString("to port 4.", 2, 90, 0)
' Quit GUI button:
g.Font = g.Font.SmallFont
Dim y_quit As Int = 100
Dim width_quit As Int = 45
Dim height_quit As Int = width_quit/2
Dim arc_diam As Int = 6
g.drawString("QUIT", 9, y_quit+7, 0)
g.drawLine(0, y_quit, 45, y_quit) ' top line
g.drawLine(0, y_quit, 0, y_quit+height_quit-arc_diam/2) ' left line
g.drawLine(width_quit, y_quit, width_quit, y_quit+height_quit/2) ' right line
g.drawLine(0+arc_diam/2, y_quit+height_quit, width_quit-10, y_quit+height_quit) ' bottom line
g.drawLine(width_quit-10, y_quit+height_quit, width_quit, y_quit+height_quit/2) ' diagonal
g.drawArc(0, y_quit+height_quit-arc_diam, arc_diam, arc_diam, 180, 90)
' Enter GUI button:
g.fillRect(width_quit+10, y_quit, height_quit, height_quit)
g.drawString2("GO", width_quit+15, y_quit+7, 0,True)
EV3.Button.WaitForAnyPress
If (EV3.Button.ESCAPE.isDown()) Then
ExitApplication2(0)
End If
g.clear
End Sub
As I said, this is just for fun. No idea how far this will go. You can download the source code for the B4J library from my Github.
Cheers,
Alwaysbusy