/* ===== pfod Command for Menu_1 ==== pfodApp msg {.} --> {,<+7>~Led Control`0~V7|A<+4>`0~Led is ~~Off\On~|B<+4>~Voltage Plot} */ // Using Arduino Nano 33 IoT via WiFi // You need to modify the WLAN_SSID, WLAN_PASS settings below // to match your network settings /* Code generated by pfodDesignerV3 V3.0.3773 */ /* (c)2014-2020 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 provided this copyright is maintained. */ #include #include #define DEBUG // Install SafeString library from the Arduino IDE Library Manager // SafeString tutorial at https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html #include "SafeString.h" // Download pfodWiFiGenericBufferedClient library from http://www.forward.com.au/pfod/pfodParserLibraries/index.html // pfodWiFiGenericBufferedClient.zip contains pfodWiFiGenericBufferedClient and pfodWiFiGenericUtils #include #include // download the libraries from http://www.forward.com.au/pfod/pfodParserLibraries/index.html // pfodParser.zip V3.48+ contains pfodParser, pfodSecurity, pfodDelay, pfodBLEBufferedSerial, pfodSMS and pfodRadio #include int swap01(int); // method prototype for slider end swaps float getPlotVarScaling(long varMax, long varMin, float displayMax, float displayMin); pfodSecurity parser("V4"); // create a parser with menu version string to handle the pfod messages pfodWiFiGenericBufferedClient bufferedClient; #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! #define WLAN_PASS "myPassword" const int portNo = 4989; // What TCP port to listen on for connections. const char staticIP[] = ""; // set this the static IP you want, e.g. "10.1.1.200" or leave it as "" for DHCP. DHCP is not recommended. // add your pfod Password here for 128bit security // eg "b0Ux9akSiwKkwCtcnjTnpWp" but generate your own key, "" means no pfod password #define pfodSecurityCode "" // see http://www.forward.com.au/pfod/ArduinoWiFi_simple_pfodDevice/index.html for more information and an example // and QR image key generator. WiFiServer server(portNo); WiFiClient client; boolean alreadyConnected = false; // whether or not the client was connected previously // 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 'Led is' 0=Off 1=On const int cmd_A_pin = 13; // name the output pin for 'Led is' unsigned long plot_mSOffset = 0; // set by {@} response bool clearPlot = false; // set by the {@} response code // 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 pfodDelay plotDataTimer; // plot data timer unsigned long PLOT_DATA_INTERVAL = 1000;// mS == 1 sec, edit this to change the plot data interval // the setup routine runs once on reset: void setup() { cmd_A_var = 0; pinMode(cmd_A_pin, OUTPUT); // output for 'Led is' is initially LOW, digitalWrite(cmd_A_pin, cmd_A_var); // set output // calculate the plot vars scaling here once to reduce computation plot_1_scaling = getPlotVarScaling(1023, plot_1_varMin, 3.3, plot_1_varDisplayMin); #ifdef DEBUG Serial.begin(115200); for (int i = 10; i > 0; i--) { Serial.print(i); Serial.print(' '); delay(500); } Serial.println(); #endif // check for the WiFi module: if (WiFi.status() == WL_NO_MODULE) { #ifdef DEBUG Serial.println("Communication with WiFi module failed!"); #endif // don't continue while (true); } #ifdef DEBUG //parser.setDebugStream(&Serial); // enable connection debugging #endif #ifdef DEBUG createSafeString(fv, 10); fv = WiFi.firmwareVersion(); Serial.println(fv); Serial.println(WIFI_FIRMWARE_LATEST_VERSION); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println(F("Please upgrade the firmware")); while (true); } #endif if (*staticIP != '\0') { IPAddress ip(pfodWiFiGenericUtils::ipStrToNum(staticIP)); IPAddress gateway(ip[0], ip[1], ip[2], 1); // set gatway to ... 1 #ifdef DEBUG Serial.print(F("Setting gateway/dns to: ")); Serial.println(gateway); #endif IPAddress subnet(255, 255, 255, 0); WiFi.config(ip, gateway, gateway, subnet); } WiFi.begin(WLAN_SSID, WLAN_PASS); while (WiFi.status() != WL_CONNECTED) { delay(500); #ifdef DEBUG Serial.print("."); #endif } #ifdef DEBUG Serial.println(); Serial.println(F("WiFi connected")); #endif // Start the server server.begin(); #ifdef DEBUG Serial.println(F("Server started")); #endif // Print the IP address #ifdef DEBUG Serial.println(WiFi.localIP()); #endif // initialize client client = server.available(); // evaluates to false if no connection plotDataTimer.start(PLOT_DATA_INTERVAL); // start plot timer // <<<<<<<<< Your extra setup code goes here } // the loop routine runs over and over again forever: void loop() { if (!client) { // see if a client is available client = server.available(); // evaluates to false if no connection } else { // have client if (!client.connected()) { if (alreadyConnected) { // client closed so clean up closeConnection(parser.getPfodAppStream()); } } else { // have connected client if (!alreadyConnected) { parser.connect(bufferedClient.connect(&client), F(pfodSecurityCode)); // sets new io stream to read from and write to alreadyConnected = true; } 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 } // handle {@} request } else if ('@' == cmd) { // pfodApp requested 'current' time plot_mSOffset = millis(); // capture current millis as offset rawdata timestamps clearPlot = true; // clear plot on reconnect as have new plot_mSOffset parser.print(F("{@`0}")); // return `0 as 'current' raw data milliseconds // now handle commands returned from button/sliders } else if ('A' == cmd) { // user moved slider -- 'Led is' // in the main Menu of Menu_1 // set output based on slider 0=Off 1=On parser.parseLong(pfodFirstArg, &pfodLongRtn); // parse first arg as a long cmd_A_var = (int)pfodLongRtn; // set variable digitalWrite(cmd_A_pin, cmd_A_var); // set output sendMainMenuUpdate(); // always send back a pfod msg otherwise pfodApp will disconnect. } else if ('B' == cmd) { // user pressed -- 'Voltage Plot' // in the main Menu of Menu_1 // return plotting msg. parser.print(F("{=Voltage at A0~mm:ss")); if (clearPlot) { clearPlot = false; parser.print(F("~C")); } parser.print(F("|time (mm:ss)|A0~~~Volts||}")); } 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) { // add any special code here to force connection to be dropped pfod_MAYBE_UNUSED(io); // may not be used, just suppress warning parser.closeConnection(); // nulls io stream alreadyConnected = false; bufferedClient.stop(); // clears client reference client.stop(); // cleans up memory client = server.available(); // evaluates to false if no connection } void sendData() { if (plotDataTimer.justFinished()) { plotDataTimer.repeat(); // restart plot data timer, without drift // 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(millis() - plot_mSOffset); // time in milliseconds 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("<+7>~Led Control`0")); parser.sendVersion(); // send the menu version // send menu items parser.print(F("|A<+4>")); parser.print('`'); parser.print(cmd_A_var); // output the current state 0 Low or 1 High parser.print(F("~Led is ~~Off\\On~")); // Note the \\ inside the "'s to send \ ... parser.print(F("|B<+4>")); parser.print(F("~Voltage Plot")); 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 state 0 Low or 1 High parser.print(F("|B")); parser.print(F("}")); // close pfod message // ============ end of menu =========== } int swap01(int in) { return (in == 0) ? 1 : 0; } // ============= end generated code =========