// ESP32_Led_Multi.ino /* ===== pfod Command for Menu_1 ==== pfodApp msg {.} --> {,<+5>~ESP32 Led`5000~V8|A`0~Led ~%`255`0~100~0~} */ // Using ESP32 based board programmed via Arduino IDE // follow the steps given on http://www.forward.com.au/pfod/ESP32/index.html to install ESP32 support for Arduino IDE // NOTE: The latest versions of the ESP32 V2.0.0 - V2.0.5 Arduino board support have problems with WiFi connections // for the ESP32 chip (e.g. Sparkfun ESP32 Thing, tec). // It may take 3 or more re-connections to get a stable connection after reboot or reprogramming. // ESP32 BLE and Bluetoot are OK on V2.0.4 as is ESP32C3 WiFi (different chip). // For ESP8266 V3.0.2 works. // You need to modify the WLAN_SSID, WLAN_PASS settings below // to match your network settings /* Code generated by pfodDesignerV3 V3.0.4181 */ /* * (c)2014-2021 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 // Download pfodESP32BufferedClient library from http://www.forward.com.au/pfod/pfodParserLibraries/index.html // pfodESP32BufferedClient.zip contains pfodESP32BufferedClient and pfodESP32Utils #include #include // download the libraries from http://www.forward.com.au/pfod/pfodParserLibraries/index.html #include int swap01(int); // method prototype for slider end swaps pfodParser parser("V9"); // create a parser with menu version string to handle the pfod messages pfodESP32BufferedClient bufferedClient; #define WLAN_SSID "ssid" // cannot be longer than 32 characters! #define WLAN_PASS "password" const int portNo = 4989; // What TCP port to listen on for connections. const char staticIP[] = "10.1.1.56"; // 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; WiFiClient* clientPtr; // non-null if have connected client const uint8_t MAX_CLIENTS = 4; // the default WiFiClient clients[MAX_CLIENTS]; // hold the currently open clients pfodParser *parserPtrs[MAX_CLIENTS]; // hold the parsers for each client pfodESP32BufferedClient *bufferedClientPtrs[MAX_CLIENTS]; // hold the parsers for each client bool validClient(WiFiClient &client) { return (client.connected()); } // 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' const int cmd_A_pin = 5; // name the output pin for 'Led' const int cmd_A_channel = 0; // channel to use for this PWM output unsigned long plot_msOffset = 0; // set by {@} response bool clearPlot = false; // set by the {@} response code // the setup routine runs once on reset: void setup() { // always have at least one parserPtrs[0] = &parser; bufferedClientPtrs[0] = &bufferedClient; // fill in the rest for (size_t i = 1; i < MAX_CLIENTS; i++) { parserPtrs[i] = new pfodParser(parser.getVersion()); bufferedClientPtrs[i] = new pfodESP32BufferedClient(); } // Explicitly set the ESP32 to be a WiFi-client, otherwise, it by default, // would try to act as both a client and an access-point and could cause // network-issues with your other WiFi-devices on your WiFi-network. // WiFi.mode(WIFI_STA); // EEPROM.begin(512); // only use 20bytes for pfodSecurity but reserve 512 (pfodWifiConfig uses more) cmd_A_var = 0; ledcAttachPin(cmd_A_pin,cmd_A_channel); // assign pin to channel ledcSetup(cmd_A_channel, 490, 8); // 490hz PWM, 8-bit resolution to match Arduino Uno pfodESP32Utils::analogWrite(cmd_A_channel,cmd_A_var); // set PWM output #ifdef DEBUG Serial.begin(115200); Serial.println(); #endif /* Initialise wifi module */ if (*staticIP != '\0') { IPAddress ip(pfodESP32Utils::ipStrToNum(staticIP)); IPAddress gateway(ip[0], ip[1], ip[2], 1); // set gatway to ... 1 #ifdef DEBUG Serial.print(F("Setting gateway to: ")); Serial.println(gateway); #endif IPAddress subnet(255, 255, 255, 0); WiFi.config(ip, 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("WiFi connected"); #endif // Start the server server.begin(); #ifdef DEBUG Serial.println("Server started"); #endif // Print the IP address #ifdef DEBUG Serial.println(WiFi.localIP()); #endif // <<<<<<<<< Your extra setup code goes here } void handle_pfodParser(pfodParser &parser) { 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(parser); // send back the menu designed } else { sendMainMenuUpdate(parser); // 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 PWM slider -- '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 pfodESP32Utils::analogWrite(cmd_A_channel,cmd_A_var); // set PWM output sendMainMenuUpdate(parser); // always send back a pfod msg otherwise pfodApp will disconnect. } else if ('!' == cmd) { // CloseConnection command closeConnection(parser.getPfodAppStream()); } else { // unknown command parser.print(F("{}")); // always send back a pfod msg otherwise pfodApp will disconnect. } } } void loop() { if (server.hasClient()) { // new connection #ifdef DEBUG Serial.print("new client:"); #endif bool foundSlot = false; size_t i = 0; for (; i < MAX_CLIENTS; i++) { if (!validClient(clients[i])) { // this space if free foundSlot = true; clients[i] = server.available(); parserPtrs[i]->connect(bufferedClientPtrs[i]->connect(&(clients[i]))); // sets new io stream to read from and write to break; } } if (!foundSlot) { WiFiClient newClient = server.available(); // get any new client and close it newClient.stop(); #ifdef DEBUG Serial.println(" NO Slots available"); #endif } else { #ifdef DEBUG Serial.println(i); #endif } } for (size_t i = 0; i < MAX_CLIENTS; i++) { if (validClient(clients[i])) { handle_pfodParser(*parserPtrs[i]); } } } void closeConnection(Stream *io) { if (!io) { #ifdef DEBUG Serial.println("closeConnection: Connection stream NULL"); #endif return; } #ifdef DEBUG Serial.print("closeConnection:"); #endif bool foundSlot = false; size_t i = 0; for (; i < MAX_CLIENTS; i++) { if ((parserPtrs[i]->getPfodAppStream() == io) && validClient(clients[i])) { foundSlot = true; break; } } if (foundSlot) { #ifdef DEBUG Serial.println(i); #endif // found match parserPtrs[i]->closeConnection(); // nulls io stream bufferedClientPtrs[i]->stop(); // clears client reference clients[i].stop(); } else { #ifdef DEBUG Serial.println(" Connection stream NOT found"); #endif } } void sendMainMenu(pfodParser &parser) { // !! 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("<+5>~ESP32 Led`5000")); parser.sendVersion(); // send the menu version // send menu items parser.print(F("|A")); parser.print('`'); parser.print(cmd_A_var); // output the current PWM setting parser.print(F("~Led ~%`255`0~100~0~")); parser.print(F("}")); // close pfod message } void sendMainMenuUpdate(pfodParser &parser) { 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("}")); // close pfod message // ============ end of menu =========== } int swap01(int in) { return (in==0)?1:0; } // ============= end generated code =========