Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
5.2 kB
10
Indexable
Never
#include <CmdMessenger.h>
#include "Mux.h"
CmdMessenger messenger(Serial);

typedef uint16_t ButtonState;

ButtonState directStateLast = 0;
ButtonState directStateCurrent = 0;

const String guid = "{33fd2917-ee36-4582-b96c-c84f0b58da5d}";
const String authkey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const uint8_t directPins[6] = { 4, 5, 8, 7, 11, 12};
const uint8_t ledPins[4] = { 3, 10, 6, 9};

bool isReady = false;
bool isStarted = false;

void led_anim()
{
  for(uint8_t i = 0; i < 4; i++)
  {
    digitalWrite(ledPins[i], HIGH);
    delay(56);
  }
  for(uint8_t i = 0; i < 4; i++)
  {
    digitalWrite(ledPins[i], LOW);
    delay(56);
  }
}


/* SPAD PROTOCOL IMPL */
void spad_id_request_isr()
{
  char *szRequest = messenger.readStringArg();

  if (strcmp(szRequest, "INIT") == 0)
    {
        messenger.sendCmdStart(0);
        messenger.sendCmdArg("SPAD");
        messenger.sendCmdArg(guid); // GUID  
        messenger.sendCmdArg("Engine Box"); // DEVICE DISPLAY NAME
        messenger.sendCmdArg(2); // SPAD SERIAL VERSION, DON'T CHANGE
        messenger.sendCmdArg("1"); // DEVICE VERSION NUMBER        
//        messenger.sendCmdArg("AUTHOR="+authkey); // AUTHOR ID - Edit the variable on top part of the code and remove // at the beginning of this line to activate your  auth code.     
        messenger.sendCmdEnd();
        return;
    }
    
  if (strcmp(szRequest, "SCANSTATE") == 0)
    {
        messenger.sendCmdStart(0);
        messenger.sendCmdArg("STATESCAN");
        messenger.sendCmdEnd();
        return;
    }

  if (strcmp(szRequest, "PING") == 0){
    messenger.sendCmdStart(0);
    messenger.sendCmdArg("PONG");
    messenger.sendCmdArg(messenger.readInt32Arg());
    messenger.sendCmdEnd();
    return;
  }

  if (strcmp(szRequest, "CONFIG") == 0)
  {
    messenger.sendCmdStart(0);
    messenger.sendCmdArg("OPTION");
    messenger.sendCmdArg("ISGENERIC=1");
    messenger.sendCmdArg("PAGESUPPORT=1");
    messenger.sendCmdArg("NO_DISPLAY_CLEAR=1");
    messenger.sendCmdEnd();

    for(uint8_t i = 0; i < 6; i++)
    {
      char str_buf[16];
      sprintf(str_buf, "BTN_%d", i+1);
      messenger.sendCmdStart(0);
      messenger.sendCmdArg("INPUT");
      messenger.sendCmdArg(i+1);
      messenger.sendCmdArg(str_buf);
      messenger.sendCmdArg("PUSHBUTTON");
      messenger.sendCmdArg("SPAD_PUSHBUTTON");
      messenger.sendCmdEnd();
    }

    for(uint8_t i = 0; i < 4; i++)
    {
        char str_buf[16];
        sprintf(str_buf, "LED_%d", i+1);
        messenger.sendCmdStart(0);
        messenger.sendCmdArg("OUTPUT");
        messenger.sendCmdArg(i+1);             // This is the LED ID 
        messenger.sendCmdArg(str_buf);    //SPAD GUI Display name
        messenger.sendCmdArg("LED");   // Type
        messenger.sendCmdArg("SPAD_LED");  // Behaviour
        messenger.sendCmdEnd();
        digitalWrite(ledPins[i], LOW);
    }
  }

  messenger.sendCmd(0, "CONFIG");
  led_anim();
  return;
}

void attachCommandCallbacks()
{
    messenger.sendCmd(3, "ATTACHING CALLBACKS!");
    messenger.attach(0, spad_id_request_isr); 
    messenger.attach(2, onSpadEvent);       
    messenger.attach(3, onUnknownCommand);
    messenger.attach(6, onDeviceLed);  
}

void onSpadEvent()
{
  char *szEvent = messenger.readStringArg();
  if (strcmp(szEvent, "START") == 0) { // SPAD tells device, it's ok to send input now
    isStarted = 1;
    return;
  }
  if (strcmp(szEvent, "END") == 0) { // SPAD tells device it will exit now
    isStarted = 0;
    return;
  }
}

void onUnknownCommand()
{
  messenger.sendCmd(3, "UNKNOWN COMMAND"); 
}

ButtonState read_direct()
{
  ButtonState retval = 0;
  for(uint8_t i = 0; i < 6; i++)
  {
    if(!digitalRead(directPins[i]))
    {
      retval |= 1;
    }
    
    if(i<5) retval <<= 1;
  }
  return retval;
}

void onDeviceLed(){ 
  int32_t ledID = messenger.readInt32Arg();       // Led ID
  int32_t ledVal = messenger.readInt32Arg();      // Led value
  
  (ledVal) ? (digitalWrite( ledPins[ledID-1], HIGH) ) : ( digitalWrite( ledPins[ledID-1], LOW) );
    
}

void setup() {
  Serial.begin(115200); while (!Serial); Serial.flush(); /* Waits for serial port to connect (needed for Leonardo only) */;

  for(uint8_t i = 0; i < 6; i++)
  {
    pinMode(directPins[i], INPUT_PULLUP);
  }
  
  for(uint8_t i = 0; i < 4; i++)
  {
    pinMode(ledPins[i], OUTPUT);
    digitalWrite(ledPins[i], LOW);
  }

  attachCommandCallbacks();
}

void loop() {

  directStateCurrent = read_direct();
  if(directStateCurrent != directStateLast)
  {
    for(uint8_t i = 0; i < 6; i++)
    {
      uint8_t btnCur = (directStateCurrent >> i) & 1;
      uint8_t btnLast = (directStateLast >> i) & 1;
      if(btnLast != btnCur)
      {
        messenger.sendCmdStart(8); // Channel no for sending input state to SPAD NEXT
        messenger.sendCmdArg(i+1); // Input ID
        messenger.sendCmdArg(btnCur); // Value for off state
        messenger.sendCmdEnd();
      }
    }
    directStateLast = directStateCurrent;
  }

  messenger.feedinSerialData();

}