PMDGtest.ino

Arduino test program.

This is an example program for the Arduino using the PMDGDataEventServer.

At startup the program wil register some PMDG variables to receive values, when these values change. When values are recieved they will be displayed on a LCD screen.

Every second the program will toggel the Taxi Light switch.

#include <LiquidCrystal.h>
#include "PMDGEvents.h"
#include "PMDGData.h"

// Prototypes
void HandleInput();
void HandleVaiableReceived();
void RegisterVariables();


char line[64];
int Event = 0;
unsigned long previousMillis = 0;
const long interval = 1000;
//
//
// Serial Input buffer
const byte InputBufferSize = 32;
char InputBuffer[InputBufferSize];
//
// Variable
int ivar = 0;
long lvalue = 0;

int a = 0;

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
// Pins for LCD: RS , RW , E , D4 , D5, D6 ,D7

void setup()
{
 lcd.begin(16, 2);

Serial.begin(9600);
 //
 // Register the variables we need with DataEventServer
 RegisterVariables();
 pinMode (A0, OUTPUT);

// Put something on the screen until connection is made
 lcd.print("DataEventServer");
 lcd.setCursor(0,1);
 lcd.print("Test PHPJJ");
}

void loop()
{
 //
 char rc;
 static byte ndx;
 //
 // Handle Serial Input NON-BLocking.
 // Continue receiving characters until '\n' (linefeed) is received.
 // Start the handling of the line (command) received in HandleInput.

if (Serial.available() > 0)
 {
 rc = Serial.read();
 InputBuffer[ndx++] = rc; // Character just received to input buffer
 if (rc == '\n')
 {
 HandleInput();
 ndx = 0; // As this code is not multy thread we can safely reset the serial input pointer to begin
 // of buffer. As no further characters can be received while we are handling the input
 }
 if (ndx > InputBufferSize) ndx = InputBufferSize; // Avoid buffer overflow
 }

// If input is was parced by 'HandleInput' and a variable was received we find ivar non zero
 if (ivar != 0)
 {
 HandleVaiableReceived();
 // the handling routine will clear ivar to indicate handling done.
 }
 //********************************************************Every Second ********
 // Next code part only runs once a second
 unsigned long currentMillis = millis();
 if ((currentMillis - previousMillis) >= interval)
 {
 // Demonstration of sending event to PMDG
 Event = EVT_OH_LIGHTS_TAXI;
 sprintf(line, "%d=%d", Event, MOUSE_FLAG_LEFTSINGLE);
 Serial.println(line);
 digitalWrite(A0, a);

a = !a;
 //
 // this ends the once-per-second part
 previousMillis = currentMillis;
 }
}


void HandleInput()
{
 // This function parces the input line that has the format of "nnn=nnn\n"
 // the result is left in:
 // ivar and lvalue

char var[8];
 byte varIndex = 0; // Index pointer to temp var string
 char digit;
 byte index = 0; // Index pointer to input chars

// PMDGDataEventServer will send "Ready" if the serial port is opened.
 //
 if (InputBuffer[0] == 'R')
 {
 // We assume 'Ready' is received
 RegisterVariables(); // Always (re)register variables 
 return;
 }
 
 if (InputBuffer[0] == 'C')
 {
 // We assume 'Closed' is received
 lcd.begin(16, 2);
 lcd.print("PMDG Closed"); // Clear the LCD and display Closed
 return;
 }
 //
 // If this line was not "Ready" or "Closed" it must be a variable
 //
 // The format be: nnn=Value\n (nnn=variablenumber)
 // 
 // Get the first number (variable number)
 do
 {
 // Everything before the '=' sign
 var[varIndex++] = InputBuffer[index++];
 if (index > InputBufferSize) return; // To avoid crash if input is wrong
 } while (InputBuffer[index] != '=');
 var[varIndex] = 0; // Terminate string with 0
 //
 index++; // skip = sign

ivar = atoi(var); // Convert to integer

// Get the second number, the value
 varIndex = 0;
 
 do
 { // Collect the digits behind the '=' sign
 var[varIndex++] = InputBuffer[index++];
 if (index > InputBufferSize) return; // To avoid crash if input is wrong
 } while (InputBuffer[index] != '\n'); // loop until we hit new line

var[varIndex] = 0; // terminate string with 0
 lvalue = atol(var); // Convert to long (4 byte value)
}

void HandleVaiableReceived()
/* ivar !=0 means there is a variable received.
 * the variable value is in lvalue and var.
 * After we handled the variable we need to clear ivar 
 */
{
 switch (ivar)
 {
 case MCP_Course_0:
 lcd.setCursor(0, 0); // COURSE
 sprintf(line, "%03ld", lvalue); // Format with leading 0
 lcd.print(line);
 break;

case MCP_IASMach:
 lcd.setCursor(6 , 0); // IAS/MACH
 sprintf(line, "%3ld", lvalue); // Format with leading blank
 lcd.print(line);
 break;

case MCP_Heading:
 lcd.setCursor(12 , 0); // HEADING
 sprintf(line, "%03ld", lvalue); // Format with leading 0
 lcd.print(line);
 break;

case MCP_Altitude:
 lcd.setCursor(0 , 1); // HEADING
 sprintf(line, "%5ld", lvalue); // Format with leading blank
 lcd.print(line);
 break;

case MAIN_TEFlapsNeedle_0:
 lcd.setCursor(6, 1);
 sprintf(line, "F:%4ld", lvalue);
 lcd.print(line);
 break;
 
 default:
 break;
 }
 ivar = 0; // Clear ivar to indicate to main look we handled the variable
}

void RegisterVariables()
{
 /* This function:
 - Sends ID of this Arduino/Panel to the server to be displayed
 - Sends the index numbers of the variables we are interested in to the Server.
 The function will be called by startuo and when a "ready" message from the server is received.
 Registration messages can be sent at any time. Registrations do not need to be in order of in
 single message.

Register MCP_Cource_0 , MCP_IASMach , MCP_Heading , MCP_Altitude, FlapsNeedle

The flaps needle parameter is followed by * to indicate we need degrees * 100 (Data server only sends integer) 
 to allow more precise needle movement. Otherwise we would not be able to gradualy move from 0-1 
 */
 // We send ID to DataEventServer. This ID is displayed in main window.
 Serial.println("ID:PMDGtest"); // Identify this code (max 12 char)
 //
 lcd.clear(); // Clear the LCD as soon as connection is made
 //
 sprintf(line, "Reg:%d:%d:%d:%d:%d*", MCP_Course_0 , MCP_IASMach , MCP_Heading , MCP_Altitude, MAIN_TEFlapsNeedle_0);
 // line wille be :"Reg:234:236:240:241"
 Serial.println(line);
 //
 lcd.clear(); // This is debug code to signal that registration has been sent on "Ready" message from server.
}