javaxmlarduinoprocessingteachable-machine

Processing 4.3 Issue : "The package “javax.xml.bind” does not exist. You might be missing a library." while following a GitHub tutorial


I'am trying to run the teachable AI from Google ("Teachable Machine") on my Arduino board to control stuff depending on what the AI detects. I'am following this GitHub tutorial to understand how to run the AI on my Arduino board:

https://github.com/googlecreativelab/teachablemachine-community/blob/master/snippets/markdown/tiny_image/GettingStarted.md

Everything was OK but then I reached the following instruction : "Next Download the [The TMConnector Processing Sketch], unzip it and open it in the Processing IDE by double clicking on the .pde file. Hit play in the upper left corner. You should see a window Like this come up:". But when I run the code on Processing, I get this error : "The package “javax.xml.bind” does not exist. You might be missing a library."

Here is the Processing code :

import processing.serial.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import websockets.*;
import javax.xml.bind.DatatypeConverter;  // I think that the issue comes from here ?
import controlP5.*;
import java.util.*;

Serial myPort;
WebsocketServer ws;

// must match resolution used in the sketch
final int cameraWidth = 96;
final int cameraHeight = 96;
final int cameraBytesPerPixel = 1;
final int bytesPerFrame = cameraWidth * cameraHeight * cameraBytesPerPixel;

PImage myImage;
byte[] frameBuffer = new byte[bytesPerFrame];
String[] portNames;
ControlP5 cp5;
ScrollableList portsList;
boolean clientConnected = false;

void setup()
{
  size(448, 224);
  pixelDensity(displayDensity());
  frameRate(30);
  cp5 = new ControlP5(this);
  portNames = Serial.list();
  portNames = filteredPorts(portNames);
  ws = new WebsocketServer(this, 8889, "/");
  portsList = cp5.addScrollableList("portSelect")
    .setPosition(235, 10)
    .setSize(200, 220)
    .setBarHeight(40)
    .setItemHeight(40)
    .addItems(portNames);

  portsList.close();
  // wait for full frame of bytes
  //myPort.buffer(bytesPerFrame);   
  //myPort = new Serial(this, "COM5", 9600);
  //myPort = new Serial(this, "/dev/ttyACM0", 9600);
  //myPort = new Serial(this, "/dev/cu.usbmodem14201", 9600);   

  myImage = createImage(cameraWidth, cameraHeight, RGB);
  noStroke();
}

void draw()
{  
  background(240);
  image(myImage, 0, 0, 224, 224);

  drawConnectionStatus();
}

void drawConnectionStatus() {
  fill(0);
  textAlign(RIGHT, CENTER);
  if (!clientConnected) {
    text("Not Connected to TM", 410, 100);
    fill(255, 0, 0);
  } else {
    text("Connected to TM", 410, 100);
    fill(0, 255, 0);
  }
  ellipse(430, 102, 10, 10);
}
void portSelect(int n) {
  String selectedPortName = (String) cp5.get(ScrollableList.class, "portSelect").getItem(n).get("text");

  try {
    myPort = new Serial(this, selectedPortName, 9600);
    myPort.buffer(bytesPerFrame);
  } 
  catch (Exception e) {
    println(e);
  }
}


boolean stringFilter(String s) {
  return (!s.startsWith("/dev/tty"));
}
int lastFrame = -1;
String [] filteredPorts(String[] ports) {
  int n = 0;
  for (String portName : ports) if (stringFilter(portName)) n++;
  String[] retArray = new String[n];
  n = 0;
  for (String portName : ports) if (stringFilter(portName)) retArray[n++] = portName; 
  return retArray;
}

void serialEvent(Serial myPort) {
  // read the saw bytes in
  myPort.readBytes(frameBuffer);
  //println(frameBuffer);

  // access raw bytes via byte buffer
  ByteBuffer bb = ByteBuffer.wrap(frameBuffer);
  bb.order(ByteOrder.BIG_ENDIAN);
  int i = 0;
  
  while (bb.hasRemaining()) { 
    //0xFF & to treat byte as unsigned.
    int r = (int) (bb.get() & 0xFF);
    myImage.pixels[i] = color(r, r, r);
    i++;
    //println("adding pixels");
  }
  if (lastFrame == -1) {
    lastFrame = millis();
  }
  else {
    int frameTime = millis() - lastFrame;
    print("fps: ");
    println(frameTime);
    lastFrame = millis();
  }
  
  myImage.updatePixels();
  myPort.clear();
  String data = DatatypeConverter.printBase64Binary(frameBuffer);
  ws.sendMessage(data);
}

void webSocketServerEvent(String msg) {
  if (msg.equals("tm-connected")) clientConnected = true;
}

I installed the library GitHub told me to, and I don't know what to do to solve the problem.

On Internet,I found solutions to solve the problem, but they are not compatible with the Processing code GitHub gave me (it seems that it's written in Arduino language, and the solutions are not). If you have any solution please tell me.


Solution

  • Perhaps the required .jar is no longer supplied in newer versions of Processing ?

    You can grab a copy from the JAXB Download section.

    After you download and unzip jaxb you should be able to drag and drop jaxb-api.jar on top of your sketch (which will copy it into a folder name "code"). This should resolve the "javax.xml.bind" library import issue.