Img.1.: Robo4J with Adafruit LED Backpacks |
Inspired by a motto : Plug&Play.
It looks very simple. It's possible to add the value by the character reference on by its 16-bit value. The module robo4j-units-rpi, similar as in previous cases, provides a advanced features that can be used for controlling the Alphanumeric LED Backpack, see the code bellow:
It's a lot of fun to have all those LEDs under the control and due to Robo4J you don't have to use C++ example, just a pure Java ...
The Adafruit is quite great company, they do provide a lot of easy to implement breakout boards for RaspberryPi platform. One of them are LED Backpacks.
Robo4J does contain implementations for Bargraphs, Matrixes and Alphanumeric ones. The agenda:
- Bi-Color 24 Bargraph
- Bi-Color 8x8 Matrix
- 0.54" Alphanumeric
To assemble any of backpacks I'd recommend to go through the well described manuals on the official Adafruit web pages.
example requirements:
1. RaspberryPi3 B+
2. Java 11 (example: Bell-Soft Liberica 11+)
3. one of Adafruit LED Backpack
Before we enjoy a LED shows, let's take a quick look how all is bundled. It should give you an idea how to connect LEDs in other than discussed cases.
As you know Robo4J is a light weight messaging framework. It's separated to the dedicated modules according to the purpose. In following blog post we do use robo4j-core, robo4j-units-rpi and robo4j-hw-rpi as you can see in the diagram bellow. The all three mentioned I2C examples are by default configured as following:
Important: If you intent to use only the robo4j-hw-rpi, it means only the hardware, the module can be used alone without any additional dependencies.
As you know Robo4J is a light weight messaging framework. It's separated to the dedicated modules according to the purpose. In following blog post we do use robo4j-core, robo4j-units-rpi and robo4j-hw-rpi as you can see in the diagram bellow. The all three mentioned I2C examples are by default configured as following:
int bus = I2CBus.BUS_1;
int address = 0x70;\
int address = 0x70;\
Important: If you intent to use only the robo4j-hw-rpi, it means only the hardware, the module can be used alone without any additional dependencies.
Img.2.: Robo4J Adafruit backpack schema |
Let's suppose we have all assembled and we start with the 1st Bi-Color 24 Bargraph.
We have connected the device over the I2C interface to the RaspberryPi according to the Adafruit Documentation. As the first step we test the hardware, let's create a simple example that uses only the robo4j-hw-rpi module. :
The next example snippet shows how the Robo4J hardware is exposed to the units from robo4j-units-rpi module. The following module offers more advanced features upon the hardware, like command or continual operations, which allows more advanced usages.
Congratulation the 1.st LED Backpack is in use and running!
public class BiColor24BargraphExample {
public static void main(String[] args) throws Exception {
BiColor24BarDevice device = new BiColor24BarDevice();
device.clear();
device.display();
int counter = 0;
while(counter < 3){
for (int i=0; i<12; i++){
int colorNumber = (i+counter) % 3 + 1;
XYElement element = new XYElement(i, BiColor.getByValue(colorNumber));
device.addBar(element);
TimeUnit.MILLISECONDS.sleep(200);
device.display();
}
counter++;
}
}
}
The code above (Img.1.) shows how the elements are created and send to the Robo4j hardware unit. public static void main(String[] args) throws Exception {
BiColor24BarDevice device = new BiColor24BarDevice();
device.clear();
device.display();
int counter = 0;
while(counter < 3){
for (int i=0; i<12; i++){
int colorNumber = (i+counter) % 3 + 1;
XYElement element = new XYElement(i, BiColor.getByValue(colorNumber));
device.addBar(element);
TimeUnit.MILLISECONDS.sleep(200);
device.display();
}
counter++;
}
}
}
The next example snippet shows how the Robo4J hardware is exposed to the units from robo4j-units-rpi module. The following module offers more advanced features upon the hardware, like command or continual operations, which allows more advanced usages.
RoboContext ctx = new RoboBuilder().add(settings).build();
ctx.start();
RoboReference<LEDBackpackMessage> barUnit = ctx.getReference("bargraph");
LEDBackpackMessage<XYElement> clearMessage = new LEDBackpackMessage<>();
AtomicInteger position = new AtomicInteger();
executor.scheduleAtFixedRate(() -> {
if (position.get() > BiColor24BarDevice.MAX_BARS - 1) {
position.set(0);
}
barUnit.sendMessage(clearMessage);
XYElement element = new XYElement(
position.getAndIncrement(),
BiColor.getByValue(position.get() % 3 + 1));
LEDBackpackMessage<XYElement> addMessage = new LEDBackpackMessage<>(LEDBackpackMessageType.DISPLAY);
addMessage.addElement(element);
barUnit.sendMessage(addMessage);
}, 2, 1, TimeUnit.SECONDS);
ctx.start();
RoboReference<LEDBackpackMessage> barUnit = ctx.getReference("bargraph");
LEDBackpackMessage<XYElement> clearMessage = new LEDBackpackMessage<>();
AtomicInteger position = new AtomicInteger();
executor.scheduleAtFixedRate(() -> {
if (position.get() > BiColor24BarDevice.MAX_BARS - 1) {
position.set(0);
}
barUnit.sendMessage(clearMessage);
XYElement element = new XYElement(
position.getAndIncrement(),
BiColor.getByValue(position.get() % 3 + 1));
LEDBackpackMessage<XYElement> addMessage = new LEDBackpackMessage<>(LEDBackpackMessageType.DISPLAY);
addMessage.addElement(element);
barUnit.sendMessage(addMessage);
}, 2, 1, TimeUnit.SECONDS);
Congratulation the 1.st LED Backpack is in use and running!
The 2nd example is Bi-Color 8x8 LED Matrix. It is really a lot of fun as you can display a simple images or animations. The Matrix is provided exactly in the same manner as the previous example. The hardware can be use only by robo4j-hw-rpi module to make hardware testing simpler, quicker and more fun ;). Here is the simple code snippet:
Having the hardware tested we can move the the robo4j-units-rpi module and enjoy a bit advanced hardware usages. Now we have an opportunity to connect the units with another ones and create a more advanced system based on messages passing, see a example snippet bellow:
3. 0.54" Alphanumeric
The previous examples were only about to just turning on/off a specific LED diodes. The last example shows how to display ASCII Characters on 14-segments (Img.6.) display (see wiki). The value can be transmitted as the ASCII character of specific segments can be turned off/on as is visible from the picture above (Img.5.).
The robo4j-hw-rpi module provides an example that shows how to configure and run Adafruit hardware:
char[] faceSmile = "00333300,03000030,30300303,30000003,
30300303,30033003,03000030,00333300".toCharArray();
...
List<char[]> availableFaces = Arrays.asList(faceSad, faceNeutral, faceSmile);
for (char[] face : availableFaces) {
matrix.clear();
matrix.display();
byte[] faceByte = LEDBackpackUtils.createMatrixBiColorArrayByCharSequence(
matrix.getMatrixSize(), ',',face);
XYElement[] faceElements = LEDBackpackUtils.createMatrixByBiColorByteArray(matrix.getMatrixSize(), faceByte);
matrix.addPixels(faceElements);
matrix.display();
TimeUnit.SECONDS.sleep(1);
}
30300303,30033003,03000030,00333300".toCharArray();
...
List<char[]> availableFaces = Arrays.asList(faceSad, faceNeutral, faceSmile);
for (char[] face : availableFaces) {
matrix.clear();
matrix.display();
byte[] faceByte = LEDBackpackUtils.createMatrixBiColorArrayByCharSequence(
matrix.getMatrixSize(), ',',face);
XYElement[] faceElements = LEDBackpackUtils.createMatrixByBiColorByteArray(matrix.getMatrixSize(), faceByte);
matrix.addPixels(faceElements);
matrix.display();
TimeUnit.SECONDS.sleep(1);
}
Having the hardware tested we can move the the robo4j-units-rpi module and enjoy a bit advanced hardware usages. Now we have an opportunity to connect the units with another ones and create a more advanced system based on messages passing, see a example snippet bellow:
RoboContext ctx = new RoboBuilder().add(settings).build();
ctx.start();
RoboReference<LEDBackpackMessage> barUnit = ctx.getReference("matrix");
LEDBackpackMessage<XYElement> clearMessage = new LEDBackpackMessage<>();
AtomicInteger position = new AtomicInteger();
executor.scheduleAtFixedRate(() -> {
if (position.get() > 7) {
position.set(0); }
barUnit.sendMessage(clearMessage);
XYElement element = new XYElement(
position.get(), position.getAndIncrement(),
BiColor.getByValue(position.get() % 3 + 1));
LEDBackpackMessage<XYElement> addMessage =
new LEDBackpackMessage<>(LEDBackpackMessageType.DISPLAY);
addMessage.addElement(element);
barUnit.sendMessage(addMessage);
}, 2, 1, TimeUnit.SECONDS);
ctx.start();
RoboReference<LEDBackpackMessage> barUnit = ctx.getReference("matrix");
LEDBackpackMessage<XYElement> clearMessage = new LEDBackpackMessage<>();
AtomicInteger position = new AtomicInteger();
executor.scheduleAtFixedRate(() -> {
if (position.get() > 7) {
position.set(0); }
barUnit.sendMessage(clearMessage);
XYElement element = new XYElement(
position.get(), position.getAndIncrement(),
BiColor.getByValue(position.get() % 3 + 1));
LEDBackpackMessage<XYElement> addMessage =
new LEDBackpackMessage<>(LEDBackpackMessageType.DISPLAY);
addMessage.addElement(element);
barUnit.sendMessage(addMessage);
}, 2, 1, TimeUnit.SECONDS);
3. 0.54" Alphanumeric
Img.5.: Adafruit Alphanumeric LED Backpack |
Img.6.: 14-segments LED (source: Adafruit) |
AlphanumericDevice device = new AlphanumericDevice();
device.clear();
device.display();
device.addCharacter('R', false);
device.addCharacter('O', true);
device.addCharacter('B', false);
device.addByteValue((short) 0x3FFF, true);
device.display();
device.clear();
device.display();
device.addCharacter('R', false);
device.addCharacter('O', true);
device.addCharacter('B', false);
device.addByteValue((short) 0x3FFF, true);
device.display();
It looks very simple. It's possible to add the value by the character reference on by its 16-bit value. The module robo4j-units-rpi, similar as in previous cases, provides a advanced features that can be used for controlling the Alphanumeric LED Backpack, see the code bellow:
RoboContext ctx = new RoboBuilder().add(settings).build();
ctx.start();
RoboReference<LEDBackpackMessage> alphaUnit = ctx.getReference("alphanumeric");
LEDBackpackMessage<AsciElement> clearMessage = new LEDBackpackMessage<>();
LEDBackpackMessage<AsciElement> displayMessage = new LEDBackpackMessage<>(LEDBackpackMessageType.DISPLAY);
AtomicInteger textPosition = new AtomicInteger();
executor.scheduleAtFixedRate(() -> {
if(textPosition.getAndIncrement() >= MESSAGE.length - 1){
textPosition.set(0);
}
alphaUnit.sendMessage(clearMessage);
LEDBackpackMessage<AsciElement> messageAdd = new LEDBackpackMessage<>(LEDBackpackMessageType.ADD);
char currentChar = MESSAGE[textPosition.get()];
adjustBuffer(currentChar);
messageAdd.addElement(new AsciElement(0, BUFFER[0], false));
messageAdd.addElement(new AsciElement(1, BUFFER[1], false));
messageAdd.addElement(new AsciElement(2, BUFFER[2], false));
messageAdd.addElement(new AsciElement(3, BUFFER[3], false));
alphaUnit.sendMessage(messageAdd);
alphaUnit.sendMessage(displayMessage);
}, 1, 500, TimeUnit.MILLISECONDS);
ctx.start();
RoboReference<LEDBackpackMessage> alphaUnit = ctx.getReference("alphanumeric");
LEDBackpackMessage<AsciElement> clearMessage = new LEDBackpackMessage<>();
LEDBackpackMessage<AsciElement> displayMessage = new LEDBackpackMessage<>(LEDBackpackMessageType.DISPLAY);
AtomicInteger textPosition = new AtomicInteger();
executor.scheduleAtFixedRate(() -> {
if(textPosition.getAndIncrement() >= MESSAGE.length - 1){
textPosition.set(0);
}
alphaUnit.sendMessage(clearMessage);
LEDBackpackMessage<AsciElement> messageAdd = new LEDBackpackMessage<>(LEDBackpackMessageType.ADD);
char currentChar = MESSAGE[textPosition.get()];
adjustBuffer(currentChar);
messageAdd.addElement(new AsciElement(0, BUFFER[0], false));
messageAdd.addElement(new AsciElement(1, BUFFER[1], false));
messageAdd.addElement(new AsciElement(2, BUFFER[2], false));
messageAdd.addElement(new AsciElement(3, BUFFER[3], false));
alphaUnit.sendMessage(messageAdd);
alphaUnit.sendMessage(displayMessage);
}, 1, 500, TimeUnit.MILLISECONDS);
The final words and conclusion
The Robo4j framework delivers easy to use hardware abstractions. Such abstractions are exposed through the Robo4j units. The Units provide an additional functionalities (example: simple matrix operation, bargraph led selection etc.) The Robo4j Units allow to employ scheduled or time based operations. All units can be extended about any features/possibilities provided by the Java Ecosystem.
The Robo4j Adafruit LED Backpack implementation gives a power to create any LED show.
Enjoy and Happy Coding !
No comments:
Post a Comment