lunes, 2 de enero de 2017

Driver UBA (JAVA/C++ [Qt]) ID003 Protocol

UBA (Universal Bill Acceptor) ID003 Protocol


Java (windowbuilder)
Simple Driver JAVA para control de billetero (ID003 Protocolo). Es un driver sencillo, solo que con GUI, aquí cuando el BA recibe un billete válido este lo mantiene en HOLD esperando que el usuario haga click en Accept o Return. Para el puerto serie estoy usando Java Communications API 3.0u1 . El proyecto está en Eclipse + windowbuilder se puede utilizar tanto en Linux como en Windows.
C++ (Qt Framework)
Básicamente lo mismo que el de JAVA solo que esta vez utilizando C++ con el Qt Framework. El proyecto está en qtcreator se puede utilizar (con mínimos cambios) tanto en Linux como en Windows.
Universal Bill Acceptor

JCM UBA, Billetero de propósito general utilizado en Banca&Finanzas (ATM), Juegos (Casinos), Kioskos Automatizados,etc.

El código no esta estructurado de una manera muy amigable, se debe a que generalmente (para no desperdiciar tiempo) tomé el código que ya tenia en C y lo migré a JAVA y C++, ademas es algo que personalmente no me sirve (no voy a utilizar) simplemente me dio curiosidad.

Para el driver en C ver entrada anterior:
JCM UBA-10-SS (ID003 Protocol) Simple Driver gcc (Raspberry Pi /Banana Pi/ PC Linux)

Código fuente Java

Código fuente C++ [Qt]

Disculpen si no respondí antes, password: "sydbernard", "sydbernard1", "maniacmansion" ,"maniacmanison1". Alguno ha de servir.

Algunos comandos del protocolo Id003:

#define  SYNC                    0xFC

#define  STATUS_REQUEST          0x11
#define  ENABLE_                 0x11
#define  IDLING                  0x11
#define  ACCEPTING               0x12
#define  ESCROW                  0x13
#define  STACKING                0x14
#define  VEND_VALID              0x15
#define  STACKED                 0x16
#define  REJECTING               0x17
#define  RETURNING               0x18
#define  HOLDING                 0x19
#define  DISABLE_                0x1A
#define  INHIBIT                 0x1A
#define  INITIALIZE              0x1B

Denominations:

#define  ONE                     0x61
#define  TWO                     0x62
#define  FIVE                    0x63
#define  TEN                     0x64
#define  TWENTY                  0x65
#define  FIFTY                   0x66
#define  ONEHUNDRED              0x67

POWER UP STATUS:

#define  POWER_UP                        0x40
#define  POWER_UP_WITH_BILL_IN_ACCEPTOR  0x41
#define  POWER_UP_WITH_BILL_IN_STACKER   0x42

ERROR STATUS:

#define  STACKER_FULL           0x43
#define  STACKER_OPEN           0x44
#define  JAM_IN_ACCEPTOR        0x45
#define  JAM_IN_STACKER         0x46
#define  PAUSE                  0x47
#define  CHEATED                0x48
#define  FAILURE                0x49 
#define  COMMUNICATION_ERROR    0x4A

RESPONSE TO VEND VALID AND RESPONSE TO OPERATION COMMAND:

#define  ACK                    0x50
#define  INVALID_COMMAND        0x4B

OPERATION COMMAND:

#define  RESET_                 0x40
#define  STACK1                 0x41
#define  STACK2                 0x42
#define  RETURN_                0x43
#define  HOLD                   0x44
#define  WAIT                   0x45

SETTING COMMAND AND RESPONSE TO SETTING COMMAND:

#define  CMD_EN_DIS_DENOMI      0xC0 
#define  CMD_SECURITY_DENOMI    0xC1
#define  CMD_MODE               0xC2    
#define  CMD_INHIBIT_ACCEPTOR   0xC3
#define  CMD_DIRECTION          0xC4
#define  CMD_OPTIONAL_FUNCTION  0xC5
#define  CMD_BARCODE            0xC6 
#define  CMD_BAR_INHIBIT        0xC7


Interface JAVA

Java Driver (Id003 Protocol) UBA
-

viernes, 25 de noviembre de 2016

GNSS (GPS / GLONASS) Logger L76 (Quectel)

GNSS Logger L76 (Quectel) (GPS / GLONASS)



GNSS (GPS + GLONASS)

Sistema global de navegación por satélite (GNSS) Son sistemas compuestos por satélites que transmiten señales utilizadas para el posicionamiento y localización en cualquier parte del globo terrestre. Estos permiten determinar las coordenadas geográficas, altitu,+d y otros datos de un punto dado como resultado de la recepción de señales provenientes de constelaciones de satélites artificiales de la Tierra para fines de navegación, transporte, geodésicos, militar, etc. Los más importantes son: GPS (EEUU), GLONASS (RUSIA), GALILEO (EU), BeiDou (CHINA). 

GNSS ( GPS / GLONASS )

En comparación con usar únicamente GPS, activar múltiples sistemas GNSS generalmente incrementa el número de satélites visibles, disminuye la dilución de precisión, reduce el tiempo de la primera posición válida e incrementa la confiabilidad de los datos; lo que también se traduce en precisión especialmente cuando se mueve sobre ambientes urbanos o de densa Vegetación.

Satélites en Vista


El L76 (Quectel) es un módulo GNSS ( GLONASS /GPS )
Este IC está disponible en varias versiones para soportar GPS, GLONASS, BEIDOU y GALILEO (Cuando esté disponible).

GPS (CDMA) / GLONASS (FDMA)

GPS L1 1575.42 MHz C/A Code
GLONASS L1 1598.0625~1605.375 C/A Code

NMEA Input/output, ASCII, 0183, 3.01
PMTK Input, MTK proprietary protocol

El protocolo NMEA tiene la forma:
$ | Talker ID | MSG ID | DATA | * | CHECKSUM | <CR><LF>

'$' Carácter de inicio. Toda trama inicia con el carácter '$'
Talker ID identifica el origen de la trama:
                     <GP> para el receptor GPS.

                     <GN> para el receptor GPS + GLONASS , GPS + GALILEO.
                     <BD> para el receptor GPS + BeiDou.
                     <P> mensaje propietario.
MSG ID identifica el tipo de trama. (RMC, GGA, GLL, etc.)
DATA información entregada por la respectiva trama.
'*' Carácter final campo de datos.
CHECKSUM XOR de todos los caracteres de la trama entre <$><*>
<CR><LF> todas las tramas finalizan con CR (0x0D), LF (0x0A).

Ejemplo de tramas NMEA:


$GPRMC,041139.000,A,3110.2908,N,12123.2348,E,0.44,128.49,300709,,,A*65
$GPGGA,041140.000,3110.2907,N,12123.2353,E,1,5,1.42,58.7,M,8.0,M,,*57

Más información sobre el protocolo NMEA 0183

Circuito GNSS Logger


GNSS logger con L76 (Quectel)




Antena GNSS ( GPS + GLONASS)
 
Datos almacenados mostrados en GMaps

Código Fuente


Disculpen si no respondí antes, password: "sydbernard", "sydbernard1", "maniacmansion" ,"maniacmanison1". Alguno ha de servir.
 
Otras Pruebas realizadas usando módulos GPS PMB-688 y L10 (Quectel)

Módulo GPS PMB-688

Antena GPS


Módulo GPS L10 (Quectel)

domingo, 25 de septiembre de 2016

PHP, JavaScript/AJAX, Gmaps & SIM900 GPRS

SIM900 GPRS, PHP, JS/AJAX, Gmaps
SIM900 GSM/GPRS

Este ejemplo básico consiste en enviar mediante GPRS del SIM900 datos a un sitio web para ser presentados adecuadamente, en nuestro caso los datos a enviar son: Latitud, Longitud, Fecha de adquisición, Hora de adquisición. Por lo tanto necesitamos de GMAPS para visualizar los datos correctamente.

Mediante la página web presentamos los datos de "geo-localización" los cuales son enviados por el SIM900 o cualquier otro módulo GPRS. La interfaz de visualización consiste en un sitio usando PHP, JavaScript/AJAX, Gmaps, MySQL, etc.

En el mapa del sitio se puede observar un marcador. Este marcador corresponde al último dato que ha recibido el servidor de parte del dispositivo AVL, es decir el último dato almacenado en la base de datos MySQL. Además el sitio nos permite ver la hora y fecha de adquisición del último dato mostrado. Todo dato enviado por el SIM900 al servidor será automáticamente marcado en el mapa y podremos observar cómo se va marcando la trayectoria del dispositivo.

La actualización del mapa con el último dato en servidor se realiza mediante AJAX, con ayuda de este preguntamos frecuentemente al servidor por el último dato recibido del dispositivo, y si el dato es el mismo no lo marca más. En caso de que un nuevo dato ha sido recibido por el servidor pero su valor corresponde al mismo punto marcado anteriormente entonces el sitio solo actualiza la fecha y hora del dato.

Este es un ejemplo básico, obviamente sería necesario un formulario para validar usuarios, cookies, ademas de control y protección de los scripts, keys, etc.


Sistema


último dato en MySQL DB -> Gmaps

Conexión
-
GET, GPRS SIM900

MySQL database/table

CREATE TABLE gprs.samples (
   sampleId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   sampleDate DATE NOT NULL,
   sampleTime TIME NOT NULL,
   sampleLat VARCHAR(20) NOT NULL,
   sampleLon VARCHAR(20)NOT NULL
)default character set utf8;

INSERT INTO gprs.samples(sampleDate, sampleTime, sampleLat, sampleLon)
VALUES ("2016-02-02", "14:35:43", "12.1006", "-86.2435");

Insertar datos (GET):
localhost/site/scripts/update.php?date=2016-12-12&time=01:41:40&lat=12.1006&lon=-86.2435

Comandos AT (SIM900):

Recordar que [CR] = 0x0D, [LF] = 0x0A, [SUB] = 0x1A, (26), <ctrl+z>

AT [CR][LF]
AT+CPIN? [CR][LF]
AT+CSQ [CR][LF]
AT+CREG? [CR][LF]
AT+CGATT? [CR][LF]
AT+CGATT=1 [CR][LF]

AT+CSTT [CR][LF]
AT+CIICR [CR][LF]
AT+CIFSR [CR][LF]

AT+CIPSTATUS [CR][LF]

AT+CIPSTART="TCP","website.com",80 [CR][LF]
AT+CIPSEND [CR][LF]

GET /scripts/update.php?date=2016-12-12&time=01:41:40&lat=12.1006&lon=-86.2435 HTTP/1.0 [CR][LF]
Host: website.com [CR][LF]
Connection: close [CR][LF]
[CR][LF]
[SUB] 

Terminal:

Para este ejemplo he usado una simple terminal que he programado en QT5 framework C++, pero tu puedes usar cualquier terminal disponible Putty, TeraTerm, minicom, moserial, etc.

sydbernard terminal (QT5 C++)

Descargar Código fuente
Disculpen si no respondí antes, password: "sydbernard", "sydbernard1", "maniacmansion" ,"maniacmanison1". Alguno ha de servir.



SIM900 GPRS

GET (mysql,php)


sábado, 17 de septiembre de 2016

SD card, BMP file & TFT [PIC24/dsPIC33]


Leer un archivo BMP almacenado en una SDC mediante la librería ELM-Chan y posteriormente presentar la imagen en un Display (320x240) TFT 2.8 (ILI9325) usando una librería de SEEED studio. La librería incluye funciones para dibujar círculos, cuadros, caracteres, strings, etc.

En el caso de la librería ElM-Chan está en capacidad de leer y escribir archivos en la SDC.

Más información sobre el formato BMP.

Microcontrolador (16 bits)
dsPIC33FJ64GP202
PIC24HJ64GP802

dsPIC33FJ
schmtcs


Descargar Código fuente  (C Code)



SD Card, ElM-Chan Lib






miércoles, 7 de septiembre de 2016

MPL3115A2 sensor (GCC), Linux MySQL/postgreSQL

MPL3115A2 (Language C) Linux MySQL (Banana Pi/Raspberry Pi)

The MPL3115A2 is a compact piezoresistive absolute pressure sensor with an I2C interface. MPL3115A2 has a wide operating range of 20 kPa to 110 kPa, a range that covers all surface elevations on earth. The fully internally compensated MEMS in conjunction with an embedded high resolution 24-bit equivalent ADC provide accurate pressure (Pascals)/altitude (meters) and temperature (°C) data.(see DataSheet, AN4481, AN4519)

Direct reading:

Pressure: 20-bit measurement (Pascals)
Altitude: 20-bit measurement (meters)
Temperature: 12-bit measurement (°C)

MPL3115A2
Simple test MPL3115A2 with a BananaPi. Using the I2C library functions (WiringPi), we communicate with the sensor, then the data is stored in MySQL/postgreSQL database.


CREATE DATABASE sensor;


CREATE TABLE sensor.samples(
 sampleId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 sampleDate DATE,
 sampleTime TIME,
 sampleTemperature DOUBLE,
 sampleAltitude DOUBLE,
 samplePressure DOUBLE) default character  set utf8;

Download source code


   MYSQL *conn;
   MYSQL_RES *res;
   //MYSQL_ROW fila;

   char *server = "localhost";
   char *user = "sydbernard";
   char *password = "secreto";
   char *database = "sensor";
   
   conn = mysql_init(NULL);
   
   // Connect to database //
   if (!mysql_real_connect(conn, server,
         user, password, database, 0, NULL, 0)) {
      fprintf(stderr, "%s\n", mysql_error(conn));
      exit(1);
   }

   ...

   /* send SQL query */
   if (mysql_query(conn, buffer)) {
       fprintf(stderr, "%s\n", mysql_error(conn));
       exit(1);
   }
    

To Compile:

$ gcc -Wall -c main.c MPL3115A2.c
$ gcc -Wall -o mpl main.o MPL3115A2.o -l wiringPi -lmysqlclient

wiringBPi



Table MySQL


MySQL

PostgreSQL

PostgreSQL is an object-relational SQL database management system.

Header files and static library for compiling C programs to link with the libpq library in order to communicate with a PostgreSQL database backend.

sudo apt-get install libpq-dev
____________________________

create table samples(
 sampleId SERIAL PRIMARY KEY,
 sampleTemperature DOUBLE precision,
 sampleAltitude DOUBLE precision,
 samplePressure DOUBLE precision
);

PGresult *res;
PGconn *pgConn = PQconnectdb("dbname=sensor hostaddr=127.0.0.1 \
                               user=sydbernard password=snoopy");
if (PQstatus(pgConn) != CONNECTION_OK)
{
   fprintf(stderr, "Connection to database failed: %s",
   PQerrorMessage(pgConn));
}

...

sprintf(buffer,"INSERT INTO samples (sampleTemperature,sampleAltitude,samplePressure) \
VALUES (%.2f, %.2f, %.2f);",temperature, altitude, pressure);

/* send SQL query */
res = PQexec(pgConn, buffer);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
 fprintf(stderr, ">%s", PQerrorMessage(pgConn));
 PQclear(res);
       
}
 
Source Code Download
 
postgreSQL

jueves, 14 de julio de 2016

JCM UBA-10-SS (ID003 Protocol) Simple Driver gcc (Raspberry Pi /Banana Pi/ PC Linux)


Simple Driver JCM UBA-10-SS (ID003 Protocol)

 JCM UBA-10-SS (ID003 Protocol)

Simple driver (gcc) para un billetero JCM UBA-10-SS usando el protocolo ID003.

Las tramas del protocolo ID003 tienen la forma:

| SYNC | Length | CMD | Data Fields | Checksum |

SYNC (1byte): 0xFC
Length (1byte): Longitud total del string (todos los bytes)
CMD (1byte) (instrucción, tipo de orden)
Data (variable)( datos, opcional)
CRC (2byte)( CRC-Kermit)

Para mayor comprensión del CRC-Kermit probar la librería de Lammert Bies, la cual se puede compilar en gcc. Las funciones para el crc-kermit en este driver han salido de aquí.
----------------------------------------------------------------.
crc: tst_crc.o lib_crc.o
    gcc -o crc tst_crc.o lib_crc.o

lib_crc.o: lib_crc.c
    gcc -Wall -c lib_crc.c

tst_crc.o: tst_crc.c
    gcc -Wall -c tst_crc.c

clean:
    rm tst_crc.o lib_crc.o
----------------------------------------------------------------.

 Crc kermit


 
Communication settings:

BaudRate: 9600 (variable)
DataBits: 8 Bits
StopBits: 1 Bit
▪ Paridad: EVEN

Ejemplos de tramas ID003:
FC 05 11 27 56 (STATUS REQUEST)
FC 05 88 6F 5F (VERSION REQUEST)
FC 06 13 62 2B C9 (ESCROW)

Las denominaciones en el id003:

0x61 = 1st
0x62 = 2nd
0x63 = 3rd
0x64 = 4th
0x65 = 5th
0x66 = 6th
 ______________________________________________________________

 uba: main.o wiringSerial.o id003.o crc_kermit.o
    gcc -o uba main.o wiringSerial.o id003.o crc_kermit.o -l pthread

wiringSerial.o: wiringSerial.c
    gcc -Wall -c wiringSerial.c

main.o: main.c
    gcc -Wall -c main.c

id003.o: id003.c
    gcc -Wall -c id003.c

crc_kermit.o: crc_kermit.c
    gcc -Wall -c crc_kermit.c

clean:
    rm main.o wiringSerial.o id003.o crc_kermit.o
 ______________________________________________________________

Descargar Código fuente (Simple Driver JCM UBA)

Descargar herramienta para comprender Id003 by igrotechnics

Driver UBA (JAVA/C++ [Qt]) ID003 Protocol

Disculpen si no respondí antes, password: "sydbernard", "sydbernard1", "maniacmansion" ,"maniacmanison1". Alguno ha de servir.

Código fuente (Simple Driver JCM UBA)



miércoles, 13 de julio de 2016

Bill Acceptors Apex 5000/7000 Simple Driver gcc (Raspberry Pi /Banana Pi/ PC Linux)


Apex 5000/7000 Simple Driver (gcc) 

 Bill Acceptor Apex 7000
 
Aquí se ha usado de la librería WiringPI los archivos wiringSerial.c, wiringSerial.h ademas de la función Delay(), pero el código funciona en ambos (Raspberry Pi / Banana Pi/ PC Linux).

En el caso de la librería wiringSerial, esta debería trabajar para 7 bits de datos, 1 bit de paridad EVEN.
Por lo que se ha modificado la función serialOpen ;


options.c_cflag |= PARENB; // Paridad activada.
options.c_cflag &= ~PARODD; // Paridad EVEN.
options.c_cflag |= CS7; // 7 bits de datos.

Este simple driver consta de 5 archivos; main.c, apex.c, apex.h, wiringSerial.c, wiringSerial.h. Para compilarlos;
---------------------------------------------------------+
 Descargar Código Fuente

Disculpen si no respondí antes, password: "sydbernard", "sydbernard1", "maniacmansion" ,"maniacmanison1". Alguno ha de servir.
---------------------------------------------------------+
$ gcc -Wall -c main.c wiringSerial.c apex.c
$ gcc -o apex main.o wiringSerial.o apex.o -l pthread
$ rm main.o wiringSerial.o apex.o
---------------------------------------------------------+
 
makefile;

apex: main.o wiringSerial.o apex.o
gcc -o apex main.o wiringSerial.o apex.o -l pthread

wiringSerial.o: wiringSerial.c
gcc -Wall -c wiringSerial.c

main.o: main.c
gcc -Wall -c main.c

apex.o: apex.c
gcc -Wall -c apex.c

clean:
rm main.o wiringSerial.o apex.o
----------------------------------------------------------+
  
Para este ejemplo en la función loop_apex se indica que cuando haya un billete valido, este sea aceptado automáticamente, una vez almacenado el billete se envia el mensaje: Accept bill: #billete
Ademas de los BYTE 0, BYTE1, BYTE2 enviados por el billetero.

Simple driver Apex bill acceptor (Linux Mint, x86)

Raspberry Pi
 
Conexión Rpi - Apex (conector 18 pin)

conector 18 pin (verde-Tx, rojo/blanco-Rx)

Pyramid Bill Acceptors Apex 5000/7000

Los billeteros (Bill Acceptors) Pyramid APEX 5000/7000 :

Comunicación:
Baud rate- 9600
1 start and 1 stop bit
7 data bits (bit 0 = sent first (LSB))
1 parity bit ( even parity)

Inactive Timing – Si el Bill Acceptor no detecta comunicación con el Host dentro de un lapso de 5 segundos, iniciando desde la última comunicación enviada por el host, el bill acceptor:

 
1 – rechazara cualquier billete mantenido en escrow.
2 – Dejará de aceptar billetes hasta que el master inicie la comunicación nuevamente.


Formato común para la transmisión:

| STX | Length | MSG Type and Ack Number | Data Fields | ETX | Checksum |

STX- 0x02 El inicio del mensaje es indicado por 1 byte.

Length- Número de bytes en cada mensaje (binary), incluyendo STX, ETX y Checksum.

Tipo de MSG y número Ack – Un byte de dato.

Tipo de MSG - (Bits 4, 5 y 6 de este byte)

1- Mensajes De Maestro a esclavo (Bill Acceptor).
2- Mensajes de esclavo (Bill Acceptor) a Maestro.

Número ACK - 0 ó 1 (bits 0-3) (Revisar RS-232 Serial Interface Specification

ApexSeries Acceptors para mayor información.

Data- Porción de mensaje, el data consiste de múltiple campos;
Data Fields para los mensajes enviados por el Master. (Byte 0 es enviado primero)
ETX- 03H Byte Fin del mensaje.
Checksum- (1 byte checksum). El cheksum es calculado con todos los bytes (except: STX, ETX y
el checksum mismo). Haciendo (XOR) a todos los bytes.

/* ***************************************************************** */


Campo de datos para el mensaje enviado por el Master

BYTE 0
BIT 0- $1 Accept Enable (Set to a “1” to accept a bill)
BIT 1- $2 Accept Enable (Not used on Apex series acceptors)
BIT 2- $5 Accept Enable
BIT 3- $10 Accept Enable
BIT 4- $20 Accept Enable
BIT 5- $50 Accept Enable
BIT 6- $100 Accept Enable

BYTE 1
BIT 0- Reserved for future use. (Set to 0)
BIT 1- SECURITY (Reserved for future use.)
BIT 2- ORIENTATION (Reserved for future use.)
BIT 3- ORIENTATION (Reserved for future use.)
BIT 4- Escrow (Set = 1 to enable escrow)
BIT 5- Stack (Set = 1 causes bill to be stacked)
BIT 6- Return (Set = 1 causes bill to be returned)

BYTE 2
BIT 0- 6 - Reserved for future use.



Ejemplo (-->):  
02 08 11 7F 00 00 03 66 (Todas las denominaciones activadas)
02 08 10 7F 00 00 03 67 (Todas las denominaciones activadas)




 
Campo de dato enviado por el Slave (Bill Acceptor)

BYTE 0
Bit 0- Idling (Set = 1 if acceptor is in idle state)
Bit 1- Accepting (Set = 1 if accepting a bill)
Bit 2- Escrowed (Set =1 if a bill is in escrow)
Bit 3- Stacking (Set = 1 if a bill is being stacked)
Bit 4- Stacked (Set = 1 if a bill was stacked, Idle (Bit 0) also set during this state)
Bit 5- Returning (= 1 if a bill is being returned)
Bit 6- Returned (Set = 1 if the bill has been returned, Idle (Bit 0) also set during this state)

BYTE 1
Bit 0- Cheated (Set = 1 if acceptor suspects cheating)
Bit 1- Bill rejected (Set = 1 if a bill was rejected)
Bit 2- Bill jammed (Set = 1 if a bill is jammed)
Bit 3- Stacker full (Set = 1 if the stacker is full)
Bit 4- Bill cassette present (Set = 1 if cassette is present)
Bit 5- Reserved for future use (Set to 0)
Bit 6- Reserved for future use (Set to 0)

BYTE 2
Bit 0- Power up (Set = 1 if acceptor is initializing)
Bit 1- Invalid command (Set = 1 if an invalid command was received)
Bit 2- Failure (Set = 1 if acceptor has failed)
Bit 3-5 Bill value field
000 = None/unknown bill or note
001 = $1 or 1 st note type
010 = $2 or 2 nd note type
011 = $5 or 3 rd note type
100 = $10 or 4 th note type
101 = $20 or 5 th note type
110 = $50 or 6 th note type
111 = $100 or 7 th note type
Bit 6- Reserved for future use.

BYTE 3
Reserved for future use.
BYTE 4
Model number (00-7FH)
BYTE 5
Revision of firmware (00-7FH)


Ejemplo (<--):  
02 0B 21 01 10 00 00 14 07 03 28 (Idling, Stacker Presente)
02 0B 20 01 10 00 00 14 07 03 29 (Idling, Stacker Presente)


/* ****************************************************************** */
BYTE 0
typedef union {
    uint8_t byte;
    struct {
        uint8_t idling:1;
        uint8_t accepting:1;
        uint8_t escrowed:1;
        uint8_t stacking:1;
        uint8_t stacked:1;
        uint8_t returning:1;
        uint8_t returned:1;
    };
} rxbyte0;

BYTE 1
typedef union {
    uint8_t byte;
    struct {
        uint8_t cheated:1;
        uint8_t bill_rejected:1;
        uint8_t bill_jammed:1;
        uint8_t stacker_full:1;
        uint8_t bill_cassette_present:1;
    };
} rxbyte1;

BYTE 2
typedef union {
    uint8_t byte;
    struct {
        uint8_t power_up:1;
        uint8_t invalid_command:1;
        uint8_t failure:1;
        uint8_t bill_value_field:3;
    };
} rxbyte2;

Simple Driver Apex 7000(LinuxMint x86)