Jul 03

MQTT.fx 0.0.4 released

Just released new version of MQTT.fx.
Download binaries HERE.

MQTT.fx - v0.0.4

New:
- revisited UI (return of “real” buttons)
- extended support for $SYS-topics: subscription for mosquitto or Hive MQ can be choosen (in respect to @dobermai).
- publish and subcrive/receive are now different tabs
- experimental support for http-proxy (in respect to @dimaki123).
- last choosen broker & port is restored at next app start
- updated 3rd party libs (e.g. now using features of ControlsFX 8.0.6)
MQTT.fx - v0.0.4 - broker status
MQTT.fx - v0.0.4 - subscribe
MQTT.fx - v0.0.4 - connection options
MQTT.fx - v0.0.4 - validation

Fixed:
- publish to topics even if not subscribed before (in respect to @_efwe_)

Hint:
Configuration-format has changed, v0.0.4 might conflict with former versions.
In this case just delete (or rename) the mqttfx-config.xml.
Windows: [USER_HOME]\MQTT-FX\mqttfx-config.xml
OS X: [USER_HOME]/Library/Application Support/MQTT-FX/mqttfx-config.xml
The new configration is automatically created on next app start.

Jun 14

MQTT.fx 0.0.3 released

Most significant change: I have added a pane to show some status values of the broker:

mqtt-0.0.3

In v0.0.3 these $SYS topics are recognised (Tooltips are showing the descriptions):

Version: $SYS/broker/version
Build: $SYS/broker/timestamp
Uptime: $SYS/broker/uptime
Subscriptions Count: $SYS/broker/subscriptions/count
Changeset: $SYS/broker/changeset
Clients Connected: $SYS/broker/clients/active
Clients Expired: $SYS/broker/clients/expired
Clients Disconnected: $SYS/broker/clients/inactive
Clients Maximum: $SYS/broker/clients/maximum
Clients Total: $SYS/broker/clients/total
Connection: $SYS/broker/connection/#
Messages Inflight: $SYS/broker/messages/inflight
Messages Received: $SYS/broker/messages/received
Messages Sent: $SYS/broker/messages/sent
Messages Stored: $SYS/broker/messages/stored
Messages Publish Dropped: $SYS/broker/publish/messages/dropped
Messages Publish Received: $SYS/broker/publish/messages/received
Messages Publish Sent: $SYS/broker/publish/messages/sent
Messages Retained Count: $SYS/broker/retained/messages/count
Bytes Received: $SYS/broker/bytes/received
Bytes Sent: $SYS/broker/bytes/sent
Load Connections: $SYS/broker/load/connections/+
Load Bytes Received: $SYS/broker/load/bytes/received/+
Load Bytes Sent: $SYS/broker/load/bytes/sent/+
Load Messages Received: $SYS/broker/load/messages/received/+
Load Messages Sent: $SYS/broker/load/messages/sent/+
Load Publish Dropped: $SYS/broker/load/publish/dropped/+
Load Publish Received: $SYS/broker/load/publish/received/+
Load Publish Sent: $SYS/broker/load/publish/sent/+
Load Sockets Count: $SYS/broker/load/sockets/+

Download binaries:
Mac OSX DMG
Windows 32bit Installer
Zipped executable jar

May 14

MQTT.fx 0.0.2

A new version of MQTT.fx is available and I have polished the pre-alpha version and added some new features to MQTT.fx.

Download binaries:
Mac OSX DMG
Windows 32bit Installer
Zipped executable jar

The Video for Jim Weaver’s “Real World Apps” talk @GeeCon2014 in Kraków

Controls to connect to the broker and to subscribe to topics are now placed in the header:

mqtt-fx-1-0.0.2

“Connection Options” can be reached from here:

mqtt-fx-2-0.0.2

“Publish” and “Receive” are place in one tab:

mqtt-fx-3-0.0.2

I have added an option to enable notifications on received messages:

mqtt-fx-3-2-0.0.2

AND NEW: “Arrived Messages” are collected in a separate tab with one color by topic.
The related messaged are colored accordingly thus they can be easily identified:

mqtt-fx-4-0.0.2

Also I found out an easy way to apply a noise and gradient effect via CSS like this:

mqtt-fx-6-noise-0.0.2

May 09

JavaFX based MQTT Testing Utility

New Version: MQTT.fx 0.0.2

Now that MQTT is on its way to become THE industry-standard protocol for IoT and M2M communication the IoT community might have to review current message strategies.

Isn’t it a very good way to start with a JavaFX-Client to get into MQTT ;-)?
So, currently I am working on JavaFX based frontend based on Eclipse Paho.

Featured so far:

  • connect to an MQTT broker (tested with mosquitto yet)
  • modify some connection options
  • subscribe to topics
  • publish to topics
  • continuous logging of arrived messages
  • load and save settings (working directory: [user.home]/mqttfx)
  • an ugly application icon

Like to give it a try?
Download executable JAR (with dependencies) (requires an installed Java8-JRE)
Download Mac OSX DMG
Download Windows (x86) Installer

Main Screen
mqtt-fx-1

Logging Arrived-Messages
mqtt-fx-2

Editing Connection Options
mqtt-fx-3

Stored Configuration and UI-Settings
mqtt-fx-4

Apr 27

NetBeans 8 – Shortcut to Remote Platforms

The recently released NetBeans 8 holds a great gift for all Java Embedded Developers:

Build-in support for Remote Java Standard Edition platform.

To introduce this great and handy feature I created some screencasts:

Part1: headless

Part2: JavaFX on Pi

Part 3 – Remote Platform Debugging

José Pereda has also blogged about this feature in action: He and Mark Heckler used it in a distributed environment for their talk G-Force! Self-Powering Global Sensor Nets for IoT (JFokus 2014).

In addition to the support for a full JRE Environment its also worth to mention there is a nice editor as a fronted to the “recreate”-command provided by the all new EJDK 8:

ejdk

Update/Hint
To launch Raspberry PI Java applications from within Eclipse a project called LaunchPI has been started.

For Intellij/IDEA there is a plugin called “sourcesync” that might be helpful for even remote deployment.

But by now I can’t find other approaches that are such seamless and well integrated as NetBeans Remote Platform support.

Apr 24

Between 0 and 1 – PWM with Raspberry Pi

Switch on and off an LED and let run a motor at one speed and direction is easy, but what if I want to e.g. control the brightness of an LED or control motor-speed?

A kind of analog signal is needed:
This is done with Pulse-width modulation (PWM). PWM is a “modulation technique that conforms the width of the pulse, formally the pulse duration, based on modulator signal information.” (Wikipedia).

In a nutshell:
The average value of voltage is depending on the frequency the load is switched on and off.

Basically there are two ways to create PWM:

Hardware PWM

  • very fast (max. possible frequency / period)
  • software independent, independent from program flow
  • clean signal

BUT:

  • not all pins might support HW PWM

Software PWM

  • each I/O pin can be used for SW PWM

BUT:

  • software controlled timing has to be implemented
  • implementation and timing have to respect CPU usage
  • not a real clean signal

In other words: HW PWM is clearly prefered!

But unfortunately there is only one HW PWM pin (#18) available on the Rasperry Pis GPIO header (also its shared with the Audio system. That means that you can’t use PWM or Servo output and play audio through the 3.5mm jack at the same time).

If a RasPi project needs more than 1 PWM it has to use soft-pwm.
However thank god all the hard work is almost done by using Gordon Henderson’s wiringPi-lib and its Java-API Pi4J.

Pi4J provides a class called “SoftPwm”. As it uses wiringPi functions, the GPIO subsytem has to be initialzed first.
Therefore the programm has to executed as “sudo”!

Here is a simple example:

public class WiringPiSoftPWMExample {
    
    public static void main(String[] args) throws InterruptedException {
        
        // initialize wiringPi library
        Gpio.wiringPiSetup();

        // create soft-pwm pins (min=0 ; max=100)
        SoftPwm.softPwmCreate(0, 0, 100);

        IntegerProperty value1 = new SimpleIntegerProperty();
        value1.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
            SoftPwm.softPwmWrite(0, newValue.intValue());
        });

        // continuous loop
        while (true) {
            // fade LED to fully ON
            for (int i = 0; i <= 100; i++) {
                value1.set(i);
                Thread.sleep(25);
            }

            // fade LED to fully OFF
            for (int i = 100; i >= 0; i--) {
                value1.set(i);
                Thread.sleep(25);
            }
        }
    }
}

LED blink

Works!
What’s next?

IMG_3176

3 x optical coupler + RGB LED stripe triggered by JavaFX UI contolled SoftPwms:

Oct 04

Solved: eGalax Touch Screen issues with JavaFX (on Raspberry Pi)

In a former post I wrote about my trouble getting touch support up an running with my eGalax Touch Display, JavaFX and the Raspberry Pi.
Today Simon gave me a hint how he solved that touch event issues with JavaFX.

Many Kudos to Simon Ritter (@speakjava)!

The Clue

It turns out that the screen driver actually creates two event devices in /dev/input: event0 and event1. JavaFX sees /dev/input/event0 and assumes that events come from that, but for some unknown reason no events are actually sent: they all go to /dev/input/event1.

The Cure

Recreate /dev/input/event0 with the same device as /dev/input/event1, so JavaFX gets the information it needs:

eGalax_patch1

Make it suitability for daily usage

Create an init-script to apply the patch at start-up:
Required-Start: $all‘ tells insserv to start the script after all the other scripts, at the end of the boot sequence:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          egalax-patch
# Required-Start:    $all
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description:
# Description:       Recreates event0 with the same device as event1, so JavaFX gets the information it needs.
### END INIT INFO

. /lib/lsb/init-functions

rm -f /dev/input/event0
mknod /dev/input/event0 c 13 65

log_success_msg "eGalax Touch Screen patch for JavaFX applied."

You can load it here.

  • copy the script to /etc/init.d/
  • make sure it’s executable: sudo chmod 755 egalax_patch
  • then enable the script: sudo insserv egalax-patch

One last thing

The event devices are re-created by the driver when the USB connection was interrupted.
In this case you will have to reboot the Raspi or (much better) execute the script manually:

eGalax_patch2

Sep 09

RasPi does the Home Automation (Part V): Just around the corner

Looking for a lightweight Java-based solution to run REST services on embedded systems I already had an eye on the Vert.x project. I was excited to see there is a talk about it on the agenda of the Herbstcampus in Nuremberg last week (I talked about my RasPi projects).

It was a pleasure to attend the talk with Eberhard Wolff about Vert.x!

Inspired by Eberhards presentation I was thrilled to give it a try and I created my first “Vertical” as a REST service for my little home automation project (as an alternative to my custom HttpServer).
Clearly I will only need a very small fraction of the provided power!

Setup Vert.x on RasPi

  • Download and Install Vert.x
    e.g. extract the package to /opt
  • put ‘vert.x-2.0.1-final/bin‘ on path:
    e.g. add 'export PATH=/opt/vert.x-2.0.1-final/bin:$PATH' at the and of ~/.bashrc.

Check installation

vertx-version

Implementing the service

I added vertx-core & vertx-platform as maven dependency to my Sweethome project.
Note the ‘provided’ scope: the dependencies are just used at compile time. At runtime the needed libs will be provided by the vertx environment.

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>2.0.1-final</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-platform</artifactId>
    <version>2.0.1-final</version>
    <scope>provided</scope>
</dependency>

Now I am prepared to give it a try with a very simple so called ‘Verticle‘ implementing a request handler which is called in case the REST call signature is matching.

Basically the URL contains the parameter for my Send-command mentioned in a previous post:

http://IP:PORT/intertechno/send/HOUSE_CODE/GROUP/DEVICE>/COMMAND

public class IntertechnoVerticle extends Verticle {

    @Override
    public void start() {
        RouteMatcher routeMatcher = new RouteMatcher();
        routeMatcher.get("/intertechno/send/:houseCode/:group/:device/:command", new Handler<HttpServerRequest>() {
            @Override
            public void handle(HttpServerRequest req) {
                container.logger().info("received request from: " + req.remoteAddress());
                
                String deviceCode = String.format("%s %s %s", req.params().get("houseCode"), req.params().get("group"), req.params().get("device"));
                String commandParam = (String) req.params().get("command");
                Send.Command command = "0".equals(commandParam) ? Send.Command.TURN_OFF : Send.Command.TURN_ON;
                
                container.logger().info("Send: " + deviceCode + " " + command.name());
                new Send().send(deviceCode, command);
                container.logger().info("OK");
                
                req.response().setStatusCode(200);
                req.response().end("<b>Send: " + deviceCode + " " + command.name() + "</b>");
            }
        });

        int port = 14880;
        HttpServer server = vertx.createHttpServer();
        server.requestHandler(routeMatcher)
                .listen(port);

        container.logger().info("---------------------------------------");
        container.logger().info("-                                     -");
        container.logger().info("-      S W E E T H O M E  SERVER      -");
        container.logger().info("-                                     -");
        container.logger().info("---------------------------------------");
        container.logger().info("Server started.");
        container.logger().info("Listening on port " + port);
        container.logger().info("Waiting for incoming requests...");
    }
}

Deploy and run vertx

Start the server…

vertx run de.jensd.sweethome.server.vertx.IntertechnoVerticle -cp /opt/lib/sweethome-1.0.4-SNAPSHOT.jar

vertx-intertechno-verticle

… and call the service:

vertx-intertechno-url

You can get the code here.

[EOM]

Aug 31

JavaFX on Raspberry Pi: Some fun with stepper motor

Recently had some fun when controlling my stepper motor with my Raspberry Pi.

The motor: a 28BYJ-48 with ULN2003 driver unit:

DSC_5687

Cool: Pi4J has a ready to use GpioStepperMotorComponent.

Let’s assume this architecture:

StepperMotorControl2

Thus we start with the StepperMotorAdapter using this component.

First some helpfull defines:

private final int oneRevolution = 2038;
private final int quarterRevolution = oneRevolution / 4;
private final int halfRevolution = oneRevolution / 2;
private final int oneDegreeRevolution = oneRevolution / 360;

then we need to get the GpioController and provide 4 GPIO pins set to digital output mode

gpio = GpioFactory.getInstance();

final GpioPinDigitalOutput[] pins = {
    gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, PinState.LOW),
    gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, PinState.LOW),
    gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, PinState.LOW),
    gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, PinState.LOW)};

and we need a byte array to define a step sequence e.g. a single motor step sequence (every coil is turned on once per step):

singleStepSequence = new byte[4];
    singleStepSequence[0] = (byte) 0b0001;
    singleStepSequence[1] = (byte) 0b0010;
    singleStepSequence[2] = (byte) 0b0100;
    singleStepSequence[3] = (byte) 0b1000;

Now we can create the motor:

motor = new GpioStepperMotorComponent(pins);
        motor.setStepSequence(currentStepSequence);
        motor.setStepsPerRevolution(oneRevolution);

and some methods to control the motor:

public void stop() {
    motor.stop();
}

public void forward() {
    motor.reverse();
}

public void backward() {
    motor.forward();
}

public void oneStepBackward() {
    motor.step(oneDegreeRevolution);
}

public void oneStepForward() {
    motor.step(-oneDegreeRevolution);
}

public void halfRevolutionBackward() {
    motor.step(halfRevolution);
}

public void halfRevolutionForward() {
    motor.step(-halfRevolution);
}

public void quarterRevolutionBackward() {
    motor.step(quarterRevolution);
}

public void quarterRevolutionForward() {
    motor.step(-quarterRevolution);
}

This adapter is used by the StepperMotorControl which implements handlers like:

adjustBackwardButton.setOnMousePressed(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent t) {
        stepperMotorAdapter.backward();
    }
});
adjustBackwardButton.setOnMouseReleased(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent t) {
        stepperMotorAdapter.stop();
    }
});
adjustForwardButton.setOnMousePressed(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent t) {
        stepperMotorAdapter.forward();
    }
});
adjustForwardButton.setOnMouseReleased(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent t) {
        stepperMotorAdapter.stop();
    }
});

and provides FXML usable methods like:

@FXML
public void backward() {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            stepperMotorAdapter.backward();
        }
    });
}

@FXML
public void forward() {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            stepperMotorAdapter.forward();
        }
    });
}

@FXML
public void stop() {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            stepperMotorAdapter.stop();
        }
    });
}

Finally this is the JavaFX UI running on the RasPi:
StepperMotorControl

Get the complete code here:

https://bitbucket.org/Jerady/raspberry-cpio-control-fx

Icons on the buttons are provided by:
FontAwesomeFX

Jul 22

RasPi does the Home Automation (Part IV): Cut the ‘rope’

Hi all,

until now all UI-Actions to control my wireless gears had to run directly on the Pi which controls the remote as e.g. deviceControl.turnOn(device); is called.

But now I’d rather make a web service available for this purpose to be more independently.
Question is: Which server should I use?

  • Apache/PHP: too less Java ;-)
  • GlassFish/Java EE: too fat for this purpose and hard to take for a RasPi

But wait a minute: wasn’t there a HttpServer class that comes with Java6?
Using HttpServer I wrote a very small Server to provide the desired service.

Now I can switch my devices by an URL like this:

http://RASPI-IP:PORT/CONTEXT?houseCode=HOUSE-CODE&group=GROUP&device=DEVICE&command=COMMAND

e.g. http://raspi.home:22222/homeserver?houseCode=a&group=1&device=2&command=1

SEND URL:
RasPi_HomeServer1

SERVER (RE-)ACTION:
RasPi_HomeServer2

Recently my Pi received a command from Madrid (thanks José for supporting me ;-)):

2013-07-18 08_53_13-Twitter _ Interactions

For a more convenient usage with e.g. an JavaFX-EventHandler I use a HttpCommand to act like a DeviceContol:

public class SendHttpCommand {

    public static void main(String[] args) {
        Settings settings = new Settings();
        HttpCommand httpCommand = new HttpCommand(settings.getProperty("sweethome.server.ip.local"));
        Device terrace = new Device("Terrace", "a", "1", "2");
        String result = httpCommand.turnOn(terrace);
        System.out.println(result);
    }
}

Now the DevicePane looks like this:

public class DevicePane extends AnchorPane {

    @FXML
    private Button offButton;
    @FXML
    private Button onButton;
    @FXML
    private Text deviceNameText;

    private Device device;
    
    private DeviceControl deviceControl;
    private HttpCommand httpCommand;
    
    public DevicePane(final Device device) {
        this.device = device;
        init();
    }

    private void init() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/DevicePane.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
        try {
            fxmlLoader.load();
        } catch (IOException ex) {
            Logger.getLogger(DevicePane.class.getName()).log(Level.SEVERE, null, ex);
        }

        Settings settings = new Settings();
        httpCommand = new HttpCommand(settings.getProperty("sweethome.server.ip.local"));
        
        deviceControl = new DeviceControl();
        
        deviceNameText.setText(device.getName());

        offButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                turnOff();
            }
        });

        onButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                turnOn();
            }
        });
    }

    private void turnOn() {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                deviceControl.turnOn(device);
                httpCommand.turnOn(device);
            }
        });

    }

    private void turnOff() {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                deviceControl.turnOff(device);
                httpCommand.turnOff(device);
            }
        });

    }
}