/* Android Controlled Front Lights Customized names for the switches and only using 3 pfodDevice for Arduino Control 4 relay switches see www.pfod.com.au for more details. (c)2012 Forward Computing and Control Pty. Ltd. This code may be freely used for both private and commerical use. Provide this copyright is maintained. */ // ====================== // this is the pfodParser.h file with the class renamed pfodParser_codeGenerated and with comments, constants and un-used methods removed class pfodParser_codeGenerated: public Print { public: pfodParser_codeGenerated(); void connect(Stream* ioPtr); void closeConnection(); byte parse(); byte* getCmd(); byte* getFirstArg(); byte getArgsCount(); byte* parseLong(byte* idxPtr, long *result); size_t write(uint8_t c); void flush(); void init(); byte parse(byte in); Stream* getPfodAppStream(); private: Stream* io; byte argsCount; byte argsIdx; byte parserState; byte args[255]; }; //============= end of pfodParser_codeGenerated.h pfodParser_codeGenerated parser; // create a parser to handle the pfod messages // customise display text and names here // to remove a switch from the mobile's display comment out the line in // sendSwitchMenu() const char* MainMenuText = "Press to switch on/off"; const char* Switch_1_Name = "Switch 1"; const char* Switch_2_Name = "Front Light"; const char* Switch_3_Name = "Garage Light"; const char* Switch_4_Name = "Hall Light"; const char Switch_1_cmd = '1'; const char Switch_2_cmd = '2'; const char Switch_3_cmd = '3'; const char Switch_4_cmd = '4'; boolean Switch_1_on = false; boolean Switch_2_on = false; boolean Switch_3_on = false; boolean Switch_4_on = false; // can comment out any switch not used void sendSwitchMenu() { //writeSwitchState(Switch_1_cmd, Switch_1_Name, Switch_1_on); // switch 1 not used writeSwitchState(Switch_2_cmd, Switch_2_Name, Switch_2_on); writeSwitchState(Switch_3_cmd, Switch_3_Name, Switch_3_on); writeSwitchState(Switch_4_cmd, Switch_4_Name, Switch_4_on); } // set pins for controlling switchs 1 to 4 const int Switch_1_Pin = 7; const int Switch_2_Pin = 6; const int Switch_3_Pin = 5; const int Switch_4_Pin = 4; void setup() { Serial.begin(9600); for (int i = 3; i > 0; i--) { // wait a few secs to see if we are being programmed delay(1000); } parser.connect(&Serial); // connect the parser to the i/o stream parser.println("Front Lights (9600baud)"); } void loop() { byte cmd = 0; byte in = 0; cmd = parser.parse(); if (cmd != 0) { parser.print("Cmd:"); parser.write(cmd); parser.println(); if (cmd == ((byte)'1')) { toggle_Switch_1(); sendUpdateMenu(); } else if (cmd == ((byte)'2')) { toggle_Switch_2(); sendUpdateMenu(); } else if (cmd == ((byte)'3')) { toggle_Switch_3(); sendUpdateMenu(); } else if (cmd == ((byte)'4')) { toggle_Switch_4(); sendUpdateMenu(); } else if (cmd == (byte)'.') { // send main menu sendMainMenu(); } else if ('!' == cmd) { // CloseConnection command closeConnection(parser.getPfodAppStream()); } else { // this should never happen parser.println("Unknown cmd"); parser.println("{}"); } // so clear it cmd = 0; // have processed this cmd now // so clear it and wait for next one } // else keep looping } void toggle_Switch_1() { Switch_1_on = !Switch_1_on; setSwitch(Switch_1_Pin, Switch_1_on); } void toggle_Switch_2() { Switch_2_on = !Switch_2_on; setSwitch(Switch_2_Pin, Switch_2_on); } void toggle_Switch_3() { Switch_3_on = !Switch_3_on; setSwitch(Switch_3_Pin, Switch_3_on); } void toggle_Switch_4() { Switch_4_on = !Switch_4_on; setSwitch(Switch_4_Pin, Switch_4_on); } void setSwitch(int pin, boolean on) { if (on) { digitalWrite(pin, HIGH); } else { digitalWrite(pin, LOW); } } void closeConnection(Stream *io) { // add any special code here to force connection to be dropped } void sendMainMenu() { parser.print("{."); parser.print(MainMenuText); sendSwitchMenu(); parser.println("}"); } void sendUpdateMenu() { parser.print("{:"); sendSwitchMenu(); parser.println("}"); } void writeSwitchState(const char cmd, const char *name, boolean on) { parser.print("|"); parser.print(cmd); parser.print("~"); parser.println(name); parser.print("is "); if (on) { parser.print("ON"); } else { parser.print("OFF"); } } void setupSwitches() { // set the digital pins as output and write the initial state // initial state set at top of the file pinMode(Switch_1_Pin, OUTPUT); setSwitch(Switch_1_Pin, Switch_1_on); pinMode(Switch_2_Pin, OUTPUT); setSwitch(Switch_2_Pin, Switch_2_on); pinMode(Switch_3_Pin, OUTPUT); setSwitch(Switch_3_Pin, Switch_3_on); pinMode(Switch_4_Pin, OUTPUT); setSwitch(Switch_4_Pin, Switch_4_on); } //========================================================================= /* You can remove from here on if you have the pfodParser library installed * and add #include #include * at the top of this file * and replace the line pfodParser_codeGenerated parser; // create a parser to handle the pfod messages * with pfodParser parser; */ // this is the pfodParser.cpp file with the class renamed pfodParser_codeGenerated and with comments, constants and un-used methods removed pfodParser_codeGenerated::pfodParser_codeGenerated() { io = NULL; init(); } void pfodParser_codeGenerated::init() { argsCount = 0; argsIdx = 0; args[0] = 0; args[1] = 0; parserState = ((byte)0xff); } void pfodParser_codeGenerated::connect(Stream* ioPtr) { init(); io = ioPtr; } void pfodParser_codeGenerated::closeConnection() { init(); } Stream* pfodParser_codeGenerated::getPfodAppStream() { return io; } size_t pfodParser_codeGenerated::write(uint8_t c) { if (!io) { return 1; // cannot write if io null but just pretend to } return io->write(c); } void pfodParser_codeGenerated::flush() { if (!io) { return ; // cannot write if io null but just pretend to } io->flush(); } byte* pfodParser_codeGenerated::getCmd() { return args; } byte* pfodParser_codeGenerated::getFirstArg() { byte* idxPtr = args; while ( *idxPtr != 0) { ++idxPtr; } if (argsCount > 0) { ++idxPtr; } return idxPtr; } byte pfodParser_codeGenerated::getArgsCount() { return argsCount; } byte pfodParser_codeGenerated::parse() { byte rtn = 0; if (!io) { return rtn; } while (io->available()) { int in = io->read(); rtn = parse((byte)in); if (rtn != 0) { // found msg if (rtn == '!') { closeConnection(); } return rtn; } } return rtn; } byte pfodParser_codeGenerated::parse(byte in) { if ((parserState == ((byte)0xff)) || (parserState == ((byte)'}'))) { parserState = ((byte)0xff); if (in == ((byte)'{')) { init(); parserState = ((byte)'{'); } return 0; } if ((argsIdx >= (255 - 2)) && (in != ((byte)'}'))) { init(); return 0; } if (parserState == ((byte)'{')) { parserState = ((byte)0); } if ((in == ((byte)'}')) || (in == ((byte)'|')) || (in == ((byte)'~')) || (in == ((byte)'`'))) { args[argsIdx++] = 0; if (parserState == ((byte)0xfe)) { argsCount++; } if (in == ((byte)'}')) { parserState = ((byte)'}'); // reset state return args[0]; } else { parserState = ((byte)0xfe); } return 0; } args[argsIdx++] = in; return 0; } byte* pfodParser_codeGenerated::parseLong(byte* idxPtr, long *result) { long rtn = 0; boolean neg = false; while ( *idxPtr != 0) { if (*idxPtr == '-') { neg = true; } else { rtn = (rtn << 3) + (rtn << 1); rtn = rtn + (*idxPtr - '0'); } ++idxPtr; } if (neg) { rtn = -rtn; } *result = rtn; return ++idxPtr; } // ============= end generated code =========