Examples - Bluetooth Server (NX32L)

Top  Previous  Next

//-----------------------------------------------------------------------------
// bt_server.vpl, created 2018-03-15 11:01
//
//-----------------------------------------------------------------------------
INCLUDE rtcu.inc
// Uncomment math.inc to add math library support.
//INCLUDE math.inc
 
 
#DEFINE STATE_NOT_CONNECTED   0
#DEFINE STATE_CONNECTING     1
#DEFINE STATE_CONNECTED       2
 
//  Input variables that can be configured via the configuration dialog (These are global)
VAR_INPUT
  in      : ARRAY [1..4] OF BOOL; | Input signals to show to the user
  visible : BOOL;                 | Device is visible while this signal is active
END_VAR;
 
//  Output variables that can be configured via the configuration dialog (These are global)
VAR_OUTPUT
  out     : ARRAY [1..4] OF BOOL; | Output signals that are controllable by the user
END_VAR;
 
//  These are the global variables of the program
VAR
  connection_state : INT := STATE_NOT_CONNECTED;
  port: SINT;
END_VAR;
 
 
 
THREAD_BLOCK btThread
VAR
  rc      : INT;
  address : STRING;
  ch      : SINT;
  pass    : DINT;
END_VAR;
  WHILE TRUE DO
     //
    rc := btWaitEvent(timeout:=10000, dev := address);
    IF rc <> _BT_ERR_TIMEOUT THEN
        DebugFmt(message:="event \1: "+address, v1:=rc);
        CASE rc OF
        _BT_EVENT_INCOMING:
          rc := btHandleSerialPortIncomingConnection(ch := ch, port := port);
          DebugFmt(message:="btHandleSerialPortIncomingConnection(\2) : \1, \3", v1:=rc, v2:=ch, v3:=port);
          IF(ch = 6) THEN
              IF connection_state <> STATE_NOT_CONNECTED THEN
                 // Close old port if it is open
                serClose(port:=port);
              END_IF;
 
              // Open new port
              rc := serOpen(port:=port);
              DebugFmt(message:="serOpen(\2) : \1", v1:=rc, v2:=port);
              IF rc = 0 THEN
                connection_state := STATE_CONNECTING;
              END_IF;
 
          END_IF;
        _BT_EVENT_DEV_FOUND:
          DebugFmt(message:="Found "+address);
        _BT_EVENT_DEV_LOST:
          DebugFmt(message:="Lost "+address);
        _BT_EVENT_PAIR_REQ:
          DebugFmt(message:="Requested confirm for "+address);
          rc := btHandlePairRequest(passkey:=pass);
          DebugFmt(message:="Pass: \4, \1", v1:=rc, v4:=pass);
          rc := guiShowMessage(message:="Is the pairing code "+dintToStr(v:=pass)+" correct?", type := 2, timeout := 20);
          DebugFmt(message:="guiShowMessage: \1", v1:=rc);
           // Accept if "Yes" was pressed
          rc := btSendPairResponse(accept:=(rc = 3));
          DebugFmt(message:="btSendPairResponse: \1", v1:=rc);
        ELSE
          DebugFmt(message:="unknown event: \1", v1:=rc);
        END_CASE;
        btEventDone();
    END_IF;
 
  END_WHILE;
END_THREAD_BLOCK;
 
 
 
 
PROGRAM bt_server;
// These are the local variables of the program block
VAR
  old_visible : BOOL;
  rc          : INT;
  thEvent     : btThread;  
  RX          : serFrameReceiver;
  rxbuffer    : SINT; // Declare a buffer for receiving frames from the serial port
 
END_VAR;
 
// The next code will only be executed once after the program starts
 
  // Turn on the display for use when pairing
  displayPower(power := ON);
 
  // Turn on power
  rc := btPower();
  DebugFmt(message:="btPower: \1", v1:=rc);
 
 
  thEvent();
 
  // Enable serial port connections
  rc := btSerialPortProfileEnable(ch:=6, max_con := 1);
  DebugFmt(message:="btSerialPortProfileEnable: \1", v1:=rc);
 
  // Make sure discoverable will be set immediately.
  old_visible := NOT visible;
 
BEGIN
// Code from this point until END will be executed repeatedly
 
  IF old_visible <> visible THEN
    rc := btMakeDiscoverable(discoverable := visible, timeout := 0);
    DebugFmt(message:="btMakeDiscoverable(\2): \1", v1:=rc, v2:= INT(visible));
    old_visible := visible;
  END_IF;
 
  IF connection_state = STATE_CONNECTING THEN
    RX(port:=port, enable:=TRUE, frame:=ADDR(rxbuffer), maxSize:=1);
    connection_state := STATE_CONNECTED;
     // Send instructions
    serSendString(port:=port, str:="Send r to read values, 1-4 to toggle output$N");
    serSendString(port:=port, str:="Send A-D to set output high, a-b to set output low$N");
 
  END_IF;
 
  IF connection_state = STATE_CONNECTED THEN
    RX();
    IF RX.ready THEN
        // Indicate a frame has been received, data is available in 'rxbuffer', length in 'RX.size'
        DebugFmt(message:="CMD: \1", v1:=rxbuffer);
        IF rxbuffer = 16#72 THEN
           // "r"
          serSendString(port:=port, str:=strFormat(format:="IN: \1,\2,\3,\4$N",v1:=INT(in[1]),v2:=INT(in[2]),v3:=INT(in[3]),v4:=INT(in[4])));
 
        END_IF;
        IF rxbuffer >= 16#31 AND rxbuffer<= 16#34 THEN
           // "1"-"4"
           // Toggle output
          out[rxbuffer-16#30]:=NOT out[rxbuffer-16#30];
        END_IF;
        IF rxbuffer >= 16#41 AND rxbuffer<= 16#44 THEN
           // "A"-"D"
           // Set output high
          out[rxbuffer-16#40]:= ON;
        END_IF;
        IF rxbuffer >= 16#61 AND rxbuffer<= 16#64 THEN
           // "a"-"d"
           // Set output low
          out[rxbuffer-16#60]:= OFF;
        END_IF;
        // Release the buffer for the receiver as we are now finished with the received data
        serFrameReceiveDone(port:=port);
    END_IF;
  END_IF;
END;
 
END_PROGRAM;