Share My Creation Programming LEGO Mindstorms EV3 with B4J

B4Lego.jpg


I was wondering if it wouldn't be possible to use B4J to program the Lego Mindstorms EV3 Brick for some time. So, last week I finally spend a couple of evenings looking into it. And yes, B4J goes Robotics! It uses a modified LeJOS Firmware (I upgraded it to support Java 1.8).

Next I wrote a B4J wrapper for the basics like motors, sensors etc. This project is a hobby project and may grow and become public in the future. But I just wanted to share this first (badly directed) video ;)

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 it if the IR sensor sees a wall, it turns away, else it keeps going


Fun fact is you can use b4j-bridge.jar too 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 straight forward in B4J (this is all the code used, including turning if it is about to hit a wall):
B4X:
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 I will take this.

Cheers,

Alwaysbusy
 
Last edited:

Cableguy

Expert
Licensed User
Longtime User
The mindstorm series was launched after I went into adolescence... So never could find a valid excuse to buy one... Maybe now I have...
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Very nice - good job.
Back in 2012, build a few LeJOS programs (at that time leJOS_NXJ_0.9.1beta) with Lego NXT ... do still have the kit ... which make me think, if your wrapper would work with the older Lego NXT. More then happy to test.
 
Top