Jolie Rouge


all ur parentheses Я belong to me


Qt C++: Threaded Communication with Artema Hybrid on Linux

Communicating with an Artema Hybrid CC Payment device is actually deceptively simple.

I’ve written an application what uses a webkit widget exclusively for the UI display, and so I hook into the Javascript to provide some extra functionality to the app, in this case, reading and writing to/from the Artema Hybrid device.

The documentation that I received was in German exclusively, so this took a bit of work to get going, but once you have it down it’s very easy. The device is connected via it’s POS connection Serial->RJ45 connection to a Serial->USB (FTDI chipset) converter that gets plugged into a usb port. You use the standard open, read, write and close functions.

The Artema Hybrid constantly communicates with your system, so you’ll need to create a QThread to run in the background reading from the device once every second. The Artema Hybrid will send you an ENQ (0x05) and you need to respond with either an ACK (0x06) or an STX (0x02).

With the way that I have it set up, the c++ code does the absolute minimum required which is it reads from the device and emits a dataRead() signal which is connected in Javascript. If I read ENQ, then I emit dataRead(“ENQ”). and in the Javascript function that is connected to the dataRead() signal, I see if the string passed up == ENQ.

In the javascript, I have an array of data to write to the device, if that array is empty, I just write back to the Device ACK, otherwise, I pop one entry off the message queue and send the data back to the c++ code, and it will write STX, then DATA, then ETX, then LRC (LRC being the xor of the DATA + ETX).

I can’t put the source code for this up directly, but I can give you some basic pseudo code. But considering that all of this is really straighforward and small, the pseudo code is actually very close to the real code.

class AHybrid
  void run
      descriptor = open(device node)
      if descriptor then
        running = true
      while running
        buffer = read(descriptor,1024)
        if buffer0 == 0x05 then
          emit dataRead("ENQ")
        elsif buffer0 == 0x02 then
          // parseData function just converts non
          // printing chars like STX/ETX etc to
          // readable markers so we can parse with
          // JavaScript Regex();
          emit dataRead(parseData(buffer))
      close(descriptor)
  void writeData(QString data)
      char * buffer = malloc data.length etc
      strcpy buffer data.toLatin1().data()
      char lrc
      each buffer do b
        lrc ^= b
      lrc ^= 0x03
      // it's possivle to combine the below 🙂
      write(descriptor,0x02)
      write(descriptor, buffer)
      write(descriptor, 0x03)
      write(descriptor, lrc)
      emit dataWritten(data)

The member variable running is just there so we can control the reading of data, and we can easily shutdown the thread by setting that to false, and it will exit gracefully.

It’s not much more complex than that.

The Javascript side just converts an Object to a string, so we have this struct, like so:

// This is for ordering the fields in the struct for when it gets converted to a string
var forder = ['sa',  'version', 'euro',  'ind', 'betrag', 'nummer', 'personal',    
                      'konto', 'ausnahme', 'ware', 'verzogerung', 'mmmm', 'handel'];
var struct = {
  sa: 'E',
  version: '1',
  euro: '1',
  ind: 'U',
  betrag: '00000900', // This changes with each total
  nummer: '2', // This can usually stay the same, as we are not
  // processing multiple sales on the same device at the same time
  personal: '00', // The cash register id goes here
  konto: '01', // This is a store conf variable
  ausnahme: '0',
  ware: '99',
  verzogerung: '000000',
  mmmm: '0000',
  handel: 'Jason' // not sure what this will be useful for...
}

function struct2string(struct) {
  var str = '';
  for (var i in forder) {
    if (struct[forder[i]]) {
      str = str + struct[forder[i]];
    }
  }
  return str;
}