Skip to main content

Welcome to Geoff Hayward's Weblog

Commenting on Java, JavaFX, Java EE, Joomla, and IoT.

I have been keen to use Java on the Intel Edison since hearing that the Edison supports Java. At the time of writing this, I could not find much information on how to use Java with the Edison. So I decided to try and get a simple LED blink program going. While a blink program is very simple, the hello world of hardware, it thought me the important bits about using the Edison with Java.

Here is the blink program in action:

And here is the blink program's code:

import mraa.Gpio;

public class EdisonTest {

    static {
        try {
            System.loadLibrary("mraajava");
        } catch (UnsatisfiedLinkError e) {
            System.err.println("Native code library failed to load.");
            System.exit(1);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Gpio gpio = new Gpio(11);
        gpio.dir(Dir.DIR_OUT);
        int state = 1;

        while (true){
            gpio.write(state);
            state = (state==1?0:1); 
            Thread.sleep(1000);
        }
    } 

}

The command to run the program is java -Djava.library.path=/usr/lib/java/ -jar EdisonTest.jar. I used WinSCP to put the EdisonTest.jar and its lib folder into /home/root/ (where I ran the program from).

If you get any problems check that your manifest file includes the lib folder. And that the lib folder includes the mraa.jar. You can download the mraa.jar and UPM jars from Intel.



Read: Blinking an LED with Java on the Intel Edison

It turns out that getting EJB timer beans configured into a WildFly 9 domain cluster is quite easy. This post records how I got EJB timers working on a WildFly 9 cluster with a MySQL database as the timer bean's datasource. The domain profile I used was the 'ha' profile.

Note this post deals with EJB timer beans and assumes you already have a WildFly 9 HA domain configured with a MySQL connection.

All I had to do was configure the "timer-service" element. Here is the configuration that worked for me:

<timer-service thread-pool-name="default" default-data-store="clustered-store">
   <data-stores>
       <database-data-store name="clustered-store" datasource-jndi-name="java:/MySqlDS" database="mysql" partition="timer"/>
   </data-stores>
</timer-service>

I have read another posts about configuring a 'timer-service' with PostgreSQL that talked about updating the SQL in the 'timer-sql.properties' file. I found that MySQL just worked without the need to change the 'timer-sql.properties' file.

I created an example project to help validate the configuration. Here is the code from the example project:

MessageManager.java

@Stateless
public class MessageManager {
    
    @PersistenceContext
    private EntityManager em;
    
    public Message save(Message m){
        return em.merge(m);
    }

}

MessageTimer.java

@Stateless
public class MessageTimer {
    
    @Inject
    private MessageManager mm;
  
    @Schedule(hour = "*", minute = "*", second = "*/10", info ="Runs every 10 seconds", persistent = true)
    public void printDate() { 
        Message m = new Message();
        m.setServer(System.getProperty("server.name"));
        m.setTime(new java.util.Date().toString());
        mm.save(m);
    }
  
}

Message.java

@Entity
@Table(name="message")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Message implements Serializable {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;
    private String time;
    private String server;
    // with getters and setters 

}

With this code the message table should get exactly one entry, from a cluster bigger than a size of one, every ten seconds. The instance that runs should be seemingly random.

Note: you need to set 'server.name' for each server in the HA group via the server's 'System Properties'.



Read: Clustering EJB Timers on WildFly 9 with MySQL

I have been struggling to configure the Java EE WildFly application server's Logging subsystem. I was finding that any changes to the configuration within domain.xml where not making any difference to what was or was not actually being logged. I finally got to the bottom of the issue.

The project, I am working on, used to run with embedded Jetty. This means some old configuration files have hung around erroneously. The old configuration files should have been deleted - but never was.

What I have learnt: WildFly's Logging subsystem uses deployment level configuration over container level configuration by default. That means old Log4j configuration files were being read by WildFly. Once I removed the old Log4j configuration files WildFly began logging as expected.

I have found out that any of the file names in the following list documented by Ritchie (2014) will be read as deployment level configuration by WildFly.

  • logging.properties
  • jboss-logging.properties
  • log4j.properties
  • log4j.xml
  • jboss-log4j.xml

Hope this helps.


Ritchie, C. 2014. WildFly Configuration, Deployment, and Administration (Second Edition), Packt Publishing, p 56.



Read: Struggling to Configure the WildFly Logging Subsystem

In this post I will describe how you can make a 4 wheel drive robot car that can be controlled by HTTP GET requests. HTTP GET requests are what you use to request webpages. The types of requests will be 'stop', 'forward', 'left', etc..

This post outlines how to make the car itself. You can send HTTP GET request via any web browser using the browser's address bar. Or, you can even make a simple webpage if you like. I will be keen to hear about the controllers you make.

I made the car for the local FabLab Edison and BlueMix Hackathon. During the Hackathon the car's controller I made was with JavaFX and is a voice controller. The voice controller uses BlueMix's Watson voice-to-text service. The car controller I made is outside the scope of this post. But you can see it in action in the video bellow.



To Build the Robot Car You Will Need

Step 1 Build the Car Kit

​The Car Kit will arrive in a bag. The bag contains 4 wheels, 8 wires (4 red and 4 black), 4 motors, the chassis, and the fittings. The instructions that I received were in Chinese (I assume Chinese). I cannot read Chinese, but the diagrams on the instructions were very easy to follow.

Begin by stripping the paper off of the chassis.This took me about 20 minutes to do as it was quite fiddly.

Next attach the motors using the fixings that are provided in the kit. Then attach the wheels to the motor shafts. Attaching the motors did not take very long, there are 2 bolts per motor.

Slide a wheel onto the shaft of each of the motors.

Once the motors are attached, you can solder the wires to the motors (1 black negative wire and 1 red positive wire per motor).

Before fitting the top of the chassis; fit the h-bridges (Step 2). Once the h-bridges are fitted and wired up you can fit the top of the chassis.

Step 2 Attach the H-bridges

The h-bridges are not supplied in the car chassis kit; they have to be purchased separately.

First you will need to wire the 4 motors to the 2 L298N H-bridges, one motor per h-bridge output A & B respectively.

Then for each L298N H-bridges connect one 4 AA battery holder. Connect the positive wire from the battery holder to the 5+ vault h-bridge in. As well as connecting the battery holder's negative wire to the h-bridge's ground you will need a second ground wire. The second ground wire will take a common ground out from the Edison's breakout board.

I found the following video from LessonStudio to be very helpful (this car, we are making, does not use pulse width modulation - leave the jumpers in place):



Step 3 Set up the Edison

First Connect your Edison to your PC. If you have not connected your Edison to a PC before, I recommend watching this 'step-by-step guide to windows' by Carlos Montesionos.



Next connect your Edison to your local WiFi (if you haven't already). The WiFi will let you send commands to the car wireless. SSH into the Edison and run configure_edison --wifi; then follow the prompt. If you get stuck, I can recommend Connecting your Intel Edison board using Wi-Fi by Intel (the Edison's maker).

Next add Node-RED to the Edison. Node-RED will give you the functionality to receive the boundary HTTP GET requests. Node-RED can then take these requests to signal to the h-bridges to drive the motors. In other words Node-RED will manage the car's business logic.

To set-up Node-RED, SSH into the Edison and issues the following commands:

npm install -g --unsafe-perm node-red 
npm install -g --unsafe-perm pm2
npm install node-red-node-intel-gpio 
pm2 start /usr/bin/node-red --node-args="--max-old-space-size=256"
pm2 save
pm2 startup

Step 4 Wire the Edison to the Car

Once you have wired the car's power and h-bridges and set up the Edison, it's time to attach the Edison to the car. The Edison Arduino breakout board comes with legs. I attached the legs so that the breakout board stands over the top of the 4 AA battery holders.

Begin by wiring jumper cables from the Edison Arduino breakout board's digital outs to the h-bridge's ins. There are 2 jumper cables per motor. This means you will need to use 8 digital outputs in total.

Next, from each h-bridge take the common ground and wire it into one of the spare grounds on the Edison Arduino breakout board. The grounds are marked 'GND'. An Edison Arduino breakout board has 3 grounds available.

Connect the 9 volt battery once you have programmed Node-RED. In the meantime, power the Edison Arduino breakout board from the mains. I found the 9 volt battery only lasted 3-4 hours before the Edison could no longer boot.

Step 5 Program Node-RED to Handle the HTTP requests

Begin by navigation to Node-RED. Node-RED has a web browser based user interface. You may find the following address works; if it doesn't work, change 'edison.local' to the IP address. 1880 is Node-RED's default port.

http://edison.local:1880

Next, drag an 'HTTP' input onto the Node-RED canvas. It is important to send an 'HTTP' response back to whatever sent the request (otherwise the request will block the client). Therefore, drag a 'HTTP' output onto the canvas. Join the 'HTTP' input to the 'HTTP' output. Double click the input and set the address to /forwared. Then, using the address bar of your browser, send http://edison.local:1880/forwared. If everything works, you will see { } printed inside your web browser.

Next, drag 2 functions onto the canvas. Name one function 'low' and the other one 'high'. In each function set msg.payload = 0 and msg.payload = 1 respectively (0 being low, 1 being high).

// example high
msg.payload = 1;
return msg;

Next, drag 8 GPIO digital outputs onto the canvas. You will need to work through each GPIO digital output to match up with the motors. For each motor there are 2 GPIO outputs and 2 h-bridge inputs. Once you have each motor GPIO connected, you can send the highs and lows functions respectively.

You will need to repeat these steps until /left, /left, /back, and /stop can be processed by Node-red. Tip, don't try and reuse the high/low funciton blocks add 2 more for each command.

Here is a video of me testing what I had programmed (wired) Node-RED correctly .



Would you like to take a short cut? Just import this Node-RED Edison Car Configuration Node-RED via its import option. The file is a JSON array that I exported from my own configuration (The configuration is mostly as it was when tested in the video above).

Step 6 Have fun

That's it. If you follow the steps closely, you will have created a working HTTP controlled Edison Car. Good luck and I hope you enjoy making it. You can, also, find more fun project to do with the Edison over at Intel's Instructables page.



Read: HTTP Controlled Edison Car

Sending a 404 "page not found" response with JSF is easily achieved. In the example below a 404 "page not found" is sent back to the requester if a search on a primary key does not yield a result.

 public Post findPost(Long id) throws IOException {
        Post post =em.find(Post.class, id);
        if (post == null) {
            FacesContext.getCurrentInstance().getExternalContext().responseSendError(HttpServletResponse.SC_NOT_FOUND, "Page not found");
            FacesContext.getCurrentInstance().responseComplete();
        }
        return post;
    }

As can be seen from the example: to send a 404 "page not found" response with JSF you need to get the external context via the 'FacesContext' object. Then using the external context, of the JSF, set the response code. In this case the response code is an error. Finally, It's important to complete the response to halt server side processing.



Read: Sending a 404 with JSF's FacesContext

Responsive Media

With the ResponsiveMedia plugin for Joomla it is easy to add 3rd party content from YouTube, Vimeo, and Instagram right in to any Joomla! article.

ResponsiveMedia: find out more