/* ===== pfod Command for Menu_1 ==== pfodApp msg {.} --> {,<+6>~Feather52`0~V9|A<+5>`0~RED led ~%`255`0~100~0~|B~Chart|+C~z} */ // Using Adafruit nRF52 Feather BLE /* Code generated by pfodDesignerV3 V3.0.3760 */ /* * (c)2014-2017 Forward Computing and Control Pty. Ltd. * NSW Australia, www.forward.com.au * This code is not warranted to be fit for any purpose. You may only use it at your own risk. * This generated code may be freely used for both private and commercial use * provide this copyright is maintained. */ // download the libraries from http://www.forward.com.au/pfod/pfodParserLibraries/index.html // pfodParser V3.16+, pfodDwgControls V1.2+ #include #include // pfodDwgControls.h includes DesignerSwitch.h #include const char* deviceName = "pfod bluefruit52"; // 30 chars or less in name // BLE Service BLEDis bledis; BLEUart bleuart; pfodParser parser("V10"); // create a parser to handle the pfod messages pfodDwgs dwgs(&parser); // drawing support int swap01(int); // method prototype for slider end swaps float getPlotVarScaling(long varMax, long varMin, float displayMax, float displayMin); // give the board pins names, if you change the pin number here you will change the pin controlled int cmd_A_var; // name the variable for 'RED led' const int cmd_A_pin = LED_RED; // name the output RED LED for 'RED led' // plotting data variables int plot_1_varMin = 0; int plot_1_var = plot_1_varMin; float plot_1_scaling; float plot_1_varDisplayMin = 0.0; // plot 2 is hidden // plot 3 is hidden unsigned long plotDataTimer = 0; // plot data timer unsigned long PLOT_DATA_INTERVAL = 1000;// mS == 1 sec, edit this to change the plot data interval DesignerSwitch switch_z('a',&dwgs); // an example switch for drawing z // Commands for drawing controls only need to unique per drawing, you can re-use cmd 'a' in another drawing. // the setup routine runs once on reset: void setup() { cmd_A_var = 0; analogWrite(cmd_A_pin,cmd_A_var); // set output // set up for Chart // set pinMode for plot pins // calculate the plot vars scaling here once to reduce computation plot_1_scaling = getPlotVarScaling(1023,plot_1_varMin,3.6,plot_1_varDisplayMin); parser.connect(&bleuart); Bluefruit.autoConnLed(true); // use Bluefruit.autoConnLed(false); to save power or to control BLUE Led manually via Pin 19 Bluefruit.begin(); // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 Bluefruit.setTxPower(4); Bluefruit.setName(deviceName); // 30 chars or less in name Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); // Configure and Start Device Information Service bledis.setManufacturer("Adafruit Industries"); bledis.setModel("Bluefruit Feather52"); bledis.begin(); // Configure and Start BLE Uart Service bleuart.begin(); // Set up and start advertising startAdv(); // <<<<<<<<< Your extra setup code goes here switch_z.setLabel(F("Label")); } // the loop routine runs over and over again forever: void loop() { uint8_t cmd = parser.parse(); // parse incoming data from connection // parser returns non-zero when a pfod command is fully parsed if (cmd != 0) { // have parsed a complete msg { to } uint8_t* pfodFirstArg = parser.getFirstArg(); // may point to \0 if no arguments in this msg. pfod_MAYBE_UNUSED(pfodFirstArg); // may not be used, just suppress warning long pfodLongRtn; // used for parsing long return arguments, if any pfod_MAYBE_UNUSED(pfodLongRtn); // may not be used, just suppress warning if ('.' == cmd) { // pfodApp has connected and sent {.} , it is asking for the main menu if (!parser.isRefresh()) { sendMainMenu(); // send back the menu designed } else { sendMainMenuUpdate(); // menu is cached just send update } // now handle commands returned from button/sliders } else if('A'==cmd) { // user moved PWM slider -- 'RED led' // in the main Menu of Menu_1 parser.parseLong(pfodFirstArg,&pfodLongRtn); // parse first arg as a long cmd_A_var = (int)pfodLongRtn; // set variable analogWrite(cmd_A_pin,cmd_A_var); // set PWM output sendMainMenuUpdate(); // always send back a pfod msg otherwise pfodApp will disconnect. } else if('B'==cmd) { // user pressed -- 'Chart' // in the main Menu of Menu_1 // return plotting msg. parser.print(F("{=Chart Label|time (secs)|A0~3.6~0.0~volts||}")); } else if('C'==cmd) { // user pressed menu item that loaded drawing with load cmd 'z' // in the main Menu of Menu_1 byte dwgCmd = parser.parseDwgCmd(); // parse rest of dwgCmd, return first char of active cmd // can be \0 if no dwg or no active areas defined // << Modify this code for your own controls if (switch_z.getCmd() == dwgCmd) { // check drawing control cmd to see what the user pressed in this drawing switch_z.setValue(!switch_z.getValue()); // modify this to take action based on this control sendDrawingUpdates_z(); // update the drawing } else { // no change parser.print(F("{}")); // always send back a pfod msg otherwise pfodApp will disconnect. } } else if ('z' == cmd) { // pfodApp is asking to load dwg 'z' if (!parser.isRefresh()) { // not refresh, send whole dwg parser.parseLong(pfodFirstArg,&pfodLongRtn); // parse first arg as a long sendDrawing_z(pfodLongRtn); } else { // refresh just update drawing state sendDrawingUpdates_z(); } } else if ('!' == cmd) { // CloseConnection command closeConnection(parser.getPfodAppStream()); } else { // unknown command parser.print(F("{}")); // always send back a pfod msg otherwise pfodApp will disconnect. } } sendData(); // <<<<<<<<<<< Your other loop() code goes here } void closeConnection(Stream *io) { // nothing special here } void startAdv(void) { // Advertising packet Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); Bluefruit.Advertising.addTxPower(); // Include bleuart 128-bit uuid Bluefruit.Advertising.addService(bleuart); Bluefruit.ScanResponse.addName(); Bluefruit.Advertising.restartOnDisconnect(true); Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds } void connect_callback(uint16_t conn_handle) { } void disconnect_callback(uint16_t conn_handle, uint8_t reason) { // clear parser with -1 and insert {!} incase connection just lost parser.parse((byte) - 1); // eof parser.parse((byte)'{'); // parser.parse((byte)'!'); // close connection parser.parse((byte)'}'); // } void sendData() { if ((millis() - plotDataTimer) > PLOT_DATA_INTERVAL) { plotDataTimer = millis(); // restart plot data timer // assign values to plot variables from your loop variables or read ADC inputs plot_1_var = analogRead(A0); // read input to plot // plot_2_var plot Hidden so no data assigned here // plot_3_var plot Hidden so no data assigned here // send plot data in CSV format parser.print(((float)plotDataTimer)/1000.0); // time in secs parser.print(','); parser.print(((float)(plot_1_var-plot_1_varMin)) * plot_1_scaling + plot_1_varDisplayMin); parser.print(','); // Plot 2 is hidden. No data sent. parser.print(','); // Plot 3 is hidden. No data sent. parser.println(); // end of CSV data record } } float getPlotVarScaling(long varMax, long varMin, float displayMax, float displayMin) { long varRange = varMax-varMin; if (varRange == 0) { varRange = 1; } // prevent divide by zero return (displayMax-displayMin)/((float)varRange); } void sendMainMenu() { // !! Remember to change the parser version string // every time you edit this method parser.print(F("{,")); // start a Menu screen pfod message // send menu background, format, prompt, refresh and version parser.print(F("<+6>~Feather52`0")); parser.sendVersion(); // send the menu version // send menu items parser.print(F("|A<+5>")); parser.print('`'); parser.print(cmd_A_var); // output the current PWM setting parser.print(F("~RED led ~%`255`0~100~0~")); parser.print(F("|B")); parser.print(F("~Chart")); parser.print(F("|+C~z")); parser.print(F("}")); // close pfod message } void sendMainMenuUpdate() { parser.print(F("{;")); // start an Update Menu pfod message // send menu items parser.print(F("|A")); parser.print('`'); parser.print(cmd_A_var); // output the current PWM setting parser.print(F("|C")); parser.print(F("}")); // close pfod message // ============ end of menu =========== } void sendDrawing_z(long dwgIdx) { if (dwgIdx == 0) { sendDrawing_z0(); } else if (dwgIdx == 1) { sendDrawing_z1(); // add more parts of the dwg here if needed } else { parser.print(F("{}")); // always return somthing } } void sendDrawing_z0() { dwgs.start(50, 30, dwgs.WHITE,true); //true means more to come, background defaults to WHITE if omitted i.e. dwgs.start(50,30); parser.sendVersion(); // send the parser version to cache this image dwgs.pushZero(10, 15, 1.0f); // scale by 1.0f, scale defaults to 1.0f if omitted, i.e. pushZero(10,15); switch_z.draw(); // button drawn dwgs.popZero(); dwgs.end(); } void sendDrawing_z1() { dwgs.startUpdate(true); //true means more to come, // empty date so pfodApp will not ask for more dwgs.end(); } void sendDrawingUpdates_z() { dwgs.startUpdate(); // dwg refresh updates must be <1024 bytes, i.e. can only be 1 msg switch_z.update(); // update existing button with current state dwgs.end(); } int swap01(int in) { return (in==0)?1:0; } // ============= end generated code =========