Configuración del puerto Serial
| Puerto Serial | Parametro |
|---|---|
| Windows/Linux | COM/ttyUSB |
| Baudrate | 115200 |
| Bit | 8 |
| Controlflow | none |
| Stop bit | 1 |
Descripción del protocolo
El protocolo de comunicación entre la BoardDroid y la PC Host con puerto serial se compone de un inicio de mensaje STX y un final de mensaje ETX, así como de una verificación de trama de datos CRC.
El frame de datos para el protocolo de comunicación:
Frame de datos que envia la BoardDroid

Frame de datos que envía la PC (AppLinker)

CRC: Se realiza una verificación del frame de datos con un Checksum, se aplica una operación tipo suma a cada byte segun corresponda.
Pila de comandos
Los comandos disponibles para esta aplicación se muestran a continuación

Descripción de comandos
1. Hardware verification: Este comando se utiliza para verificar si el hardware esta presente en el sistema, permite a la pliación conocer el estatus del hardware (desconectado o conectado)
2. Disable cash and card: Este comando deshabilita todos los dispositivos conectados al bus de datos MDB (Multi Drop Bus).
3. Enable cash: Permite habilitar monedero y/o billetero para aceptar el efectivo depositado por los usuarios.
4. Insert cash: Este comando es envíado por la tarjeta cada vez que detecta efectivo depositado, este datos es envía en una cadena de valores ASCII como se muestra a continuación.

El valor de divide entre 10 para tener el punto decial en las monedas de 50 centavos Mexicanas. La tarjeta siempre mandara el acumulado de lo ingresado en efectivo, cuando de deshabilita los dispositivos se reinicia el contador a $0.00 pesos. El monto máximo que puede aceptar es de $999.50 pesos Mexicanos.
5. Exchange operation: Este comando es enviado por la aplicación de escritorio y permite ordenarle a la tarjeta BoardDroid que le indique a los dispositivos de cobro un monto en efectivo para ser entregado.

6. Card operation: Este comando permite a la aplicación de escritorio enviar la orden de cobro con tarjeta, el dispositivo campatible es Nayax, nayax requiere de un identificaro que puede ser de 0 a 255 y el precio de venta.

Es importante que la aplicación quede en modo escucha (se puede desplegar una pantalla que indique al usuario que inserte su tarjeta), ya que la tarjeta BoardDroid enviara los datos correspondiente siempre y cuando se cobre o se termine el tiempo para cobro asignado por la aplicación Host. Cuando el cobro es lanzado se debe de escuchar la respuesta de la tarjeta electrónica, tal como se muestra a continuación:

Ejemplo de implementación
A continuación se muestra secciones de codigo en lenguage Basic y C#, la finalidad de esta documentación es proporcionar una guia en estos lenguages para poder implementar el protocolo de comunicación,

A continuación se describen algunos metodos y funciones en Visual Basic y C#
VB Setting port
Public WithEvents SerialPort1 As New IO.Ports.SerialPort
SerialPort1.PortName = NamePortArray(PointerNamePort2)
SerialPort1.DataBits = 8
SerialPort1.BaudRate = 115200
SerialPort1.Parity = Parity.None
SerialPort1.StopBits = StopBits.One
SerialPort1.Open()
SendCMDtoVM(CMD_CHECK_BOARD)
C# Setting port
private void InicializarPuerto()
{
try
{
SerialPort1.PortName = "COM3";
SerialPort1.BaudRate = 115200;
SerialPort1.DataBits = 8;
SerialPort1.StopBits = StopBits.One;
SerialPort1.Parity = Parity.None;
SerialPort1.ReadTimeout = 1000;
SerialPort1.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
VB Data recive
Dim RX_DATA As Integer
RX_DATA = SerialPort1.BytesToRead
If RX_DATA = 9 Then
Dim RS232_Buff As Byte() = New Byte(RX_DATA - 1) {}
SerialPort1.Read(RS232_Buff, 0, RX_DATA)
Me.Invoke(New DisplayDelegate(AddressOf Processing_RX_Buffer), New Object() {BytetoHex(RS232_Buff)})
End If
End Sub
C# Data recive
private void SerialPort1_DataReceived(object s, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[SerialPort1.BytesToRead];
SerialPort1.Read(data, 0, data.Length);
if(data.Length == 9)
Processing_RX_Buffer(BytetoHex(data));
}
VB processing data recive
Private Sub Processing_RX_Buffer(ByVal displayChar As String)
Dim chars As Char() = displayChar.ToCharArray()
Dim Buffer_uC_RX((chars.Length / 2) - 1) As String
Dim OneChar As String
Dim Cheksum As Integer = 0
Dim FLagSTX As Boolean = False
Dim PointCMD As Integer = 0
Dim PointCHKSUM As Integer = 0
Dim FLagETX As Boolean = False
Dim PointETX As Integer = 0
'AGRUPANDO DATOS
For i = 0 To (chars.Length / 2) - 1
Try
OneChar = (chars(i * 2) + chars((i * 2) + 1))
Buffer_uC_RX(i) = OneChar
Catch ex As Exception
End Try
Next
'Se localiza si existe ETX = F2 y STX = F3
If Buffer_uC_RX(0) = "F2" Then
FLagSTX = True
PointCMD = 1
End If
If Buffer_uC_RX(7) = "F3" Then
FLagETX = True
PointETX = 7
End If
If (FLagSTX = True) And (FLagETX = True) And (Buffer_uC_RX.Length - 1 = 8) Then
For i = PointCMD To PointETX
Cheksum += Convert.ToInt32(Buffer_uC_RX(i), 16)
Next
Cheksum = Cheksum And 255
PointCHKSUM = 8
If Buffer_uC_RX(PointCMD) = "A1" And Convert.ToInt32(Buffer_uC_RX(PointCHKSUM), 16) = Cheksum Then 'Recivir Dinero Depositado
'BOARDROID
DataCash.MoneyIn = 0
DataCash.MoneyIn += (Convert.ToInt32(Buffer_uC_RX(2), 16) - 48) * 1000
DataCash.MoneyIn += (Convert.ToInt32(Buffer_uC_RX(3), 16) - 48) * 100
DataCash.MoneyIn += (Convert.ToInt32(Buffer_uC_RX(4), 16) - 48) * 10
DataCash.MoneyIn += (Convert.ToInt32(Buffer_uC_RX(5), 16) - 48)
DataCash.MoneyIn /= 10
ElseIf Buffer_uC_RX(PointCMD) = "A2" And Convert.ToInt32(Buffer_uC_RX(PointCHKSUM), 16) = Cheksum Then 'Recibir Dinero Dispensado
DataCash.RETUNR10P = (Convert.ToInt32(Buffer_uC_RX(2), 16)) '10
DataCash.RETUNR5P = (Convert.ToInt32(Buffer_uC_RX(3), 16)) '5
DataCash.RETUNR2P = (Convert.ToInt32(Buffer_uC_RX(4), 16)) '2
DataCash.RETUNR1P = (Convert.ToInt32(Buffer_uC_RX(5), 16)) '1
DataCash.RETUNR50cP = (Convert.ToInt32(Buffer_uC_RX(6), 16)) '.50c
DataCash.Cambio_No_Dev += DataCash.Money_Out - DataCash.Money_dispensed
ElseIf Buffer_uC_RX(PointCMD) = "B0" And Convert.ToInt32(Buffer_uC_RX(PointCHKSUM), 16) = Cheksum Then 'uC master Responde OK
'###SE CONFIRMA CONEXIÓN CON EL HARDWARE###
TmrPortFound.Stop() 'SE DETIENE TIMER PARA BUSQUEDA DE HARDWARE
TmrUSBDisct.Start() 'SE INICIA TIMER PARA DETECTAR DESCONEXIONES
End If
End If
End Sub
C# processing data recive
private void Processing_RX_Buffer(string displayChar)
{
char[] chars = displayChar.ToCharArray();
string[] Buffer_uC_RX = new string[(chars.Length / 2)];
string OneChar = null;
int Cheksum = 0;
bool FLagSTX = false;
int PointCMD = 0;
int PointCHKSUM = 0;
bool FLagETX = false;
int PointETX = 0;
for (int i = 0; i <= (chars.Length / 2) - 1; i++)
{
try
{
OneChar = (chars[i * 2].ToString() + chars[(i * 2) + 1]).ToString();
Buffer_uC_RX[i] = OneChar;
}
catch (Exception)
{
}
}
for (int i = 0; i <= Buffer_uC_RX.Length - 1; i++)
{
if (Buffer_uC_RX[i] == "F2")
{
FLagSTX = true;
PointCMD = i + 1;
}
else if (Buffer_uC_RX[i] == "F3")
{
FLagETX = true;
PointETX = i;
break;
}
}
if (FLagSTX & FLagETX & (Buffer_uC_RX.Length - 1 == 8))
{
for (int i = PointCMD; i <= PointETX; i++)
{
Cheksum += Convert.ToInt32(Buffer_uC_RX[i], 16);
}
Cheksum = Cheksum & 255;
PointCHKSUM = PointETX + 1;
/*Recibir Dinero Depositado*/
if (Buffer_uC_RX[PointCMD] == "A1" & Convert.ToInt32(Buffer_uC_RX[PointCHKSUM], 16) == Cheksum)
{
MoneyIn = 0;
MoneyIn += (Convert.ToInt32(Buffer_uC_RX[2], 16) - 48) * 100;
MoneyIn += (Convert.ToInt32(Buffer_uC_RX[3], 16) - 48) * 10;
MoneyIn += (Convert.ToInt32(Buffer_uC_RX[4], 16) - 48) * 1;
MoneyIn += (Convert.ToInt32(Buffer_uC_RX[5], 16)) * 0.5;
/*Recibir Dinero Dispensado*/
}
else if (Buffer_uC_RX[PointCMD] == "A2" & Convert.ToInt32(Buffer_uC_RX[PointCHKSUM], 16) == Cheksum)
{
Money_dispensed = 0;
Money_dispensed += Convert.ToInt32(Buffer_uC_RX[2], 16) * 10;
Money_dispensed += Convert.ToInt32(Buffer_uC_RX[3], 16) * 5;
Money_dispensed += Convert.ToInt32(Buffer_uC_RX[4], 16) * 2;
Money_dispensed += Convert.ToInt32(Buffer_uC_RX[5], 16) * 1;
Money_dispensed += Convert.ToInt32(Buffer_uC_RX[6], 16) * 0.5;
Cambio_No_Dev = Money_Out - Money_dispensed;
RETUNR10P = (Convert.ToInt32(Buffer_uC_RX[2], 16));//10
RETUNR5P = (Convert.ToInt32(Buffer_uC_RX[3], 16));//5
RETUNR2P = (Convert.ToInt32(Buffer_uC_RX[4], 16));//2
RETUNR1P = (Convert.ToInt32(Buffer_uC_RX[5], 16));//1
RETUNR50cP = (Convert.ToInt32(Buffer_uC_RX[6], 16));//.50c
/*uC master Responde OK*/
}
else if (Buffer_uC_RX[PointCMD] == "B0" & Convert.ToInt32(Buffer_uC_RX[PointCHKSUM], 16) == Cheksum)
{
Status_CMD = true;
}
}
else
{
System.Threading.Thread.Sleep(400);
SerialPort1.Write(CMD_ENQ_CMD, 0, CMD_ENQ_CMD.Length);
}
}