|
| 1 | +/******************************************************************* |
| 2 | +Example for controlling an LED from a Telegram Bot |
| 3 | +
|
| 4 | +You must have a Telegram Bot for this example to work. To make one, |
| 5 | +1. Open Telegram (on mobile, web, or desktop) |
| 6 | +2. Start a chat with BotFather (@BotFather) |
| 7 | +3. Send /start to BotFather, followed by /newbot |
| 8 | +4. Send a friendly name for your bot (this isn't the username of bot) |
| 9 | +5. Type in and send the username for your bot (ending in bot) |
| 10 | +6. Copy the token provided by BotFather and paste it at BOTtoken below |
| 11 | +
|
| 12 | +Telegram Bot API documentation available at https://core.telegram.org/bots/api |
| 13 | +
|
| 14 | +Note: As of 3rd Jan. 2018, it is necessary to use espressif32_stage |
| 15 | +platform for PlatformIO |
| 16 | +
|
| 17 | +written by Giacarlo Bacchio (Gianbacchio on Github) |
| 18 | +adapted by Brian Lough ( witnessmenow ) for UniversalTelegramBot library |
| 19 | +adapted by Pranav Sharma ( PRO2XY ) for ESP32 on PlatformIO |
| 20 | +Library related discussions on https://t.me/arduino_telegram_library |
| 21 | +
|
| 22 | +*******************************************************************/ |
| 23 | +#include <Arduino.h> |
| 24 | +#include <WiFi.h> |
| 25 | +#include <WiFiClientSecure.h> |
| 26 | +#include <UniversalTelegramBot.h> |
| 27 | + |
| 28 | + |
| 29 | +// WiFi parameters |
| 30 | +const char *ssid = "SSID"; // your network SSID (name) |
| 31 | +const char *password = "PASS"; // your network key |
| 32 | + |
| 33 | +// Bot parameters |
| 34 | +#define BOTtoken "xxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxx" // your Bot Token (Get from Botfather) |
| 35 | +int Bot_mtbs = 1000; //mean time between scan messages |
| 36 | +long Bot_lasttime; //last time messages' scan has been done |
| 37 | + |
| 38 | +// LED parameters |
| 39 | +const int ledPin = 16; // Internal Red LED on Karyni (2 on NodeMCU-32S) |
| 40 | +enum ledModes {ON = 0, OFF, BLINK, PWM}; // define modes of operation for LED (inverse polarity) |
| 41 | +enum ledModes ledmode = OFF; // Start with off |
| 42 | + |
| 43 | +WiFiClientSecure client; |
| 44 | +UniversalTelegramBot bot(BOTtoken, client); |
| 45 | + |
| 46 | +// Function prototypes (PlatformIO doesn't make these for you automatically) |
| 47 | +void handleNewMessages(int numNewMessages); // parses new messages and sends them to msgInterpretation |
| 48 | +void msgInterpretation(String from_name, String text, String chat_id, String message_type); |
| 49 | + |
| 50 | + |
| 51 | +void setup() { |
| 52 | + Serial.begin(115200); |
| 53 | + //bot._debug=true; // uncomment to see debug messages from bot library |
| 54 | + |
| 55 | + // attempt to connect to Wifi network: |
| 56 | + Serial.print("Connecting Wifi: "); |
| 57 | + Serial.println(ssid); |
| 58 | + // Start WiFi in Station mode |
| 59 | + WiFi.mode(WIFI_STA); |
| 60 | + WiFi.begin(ssid, password); |
| 61 | + |
| 62 | + // Wait for WiFi to connect |
| 63 | + while (WiFi.status() != WL_CONNECTED) { |
| 64 | + Serial.print('.'); |
| 65 | + delay(500); |
| 66 | + } |
| 67 | + |
| 68 | + Serial.println("\r\nConnected!"); |
| 69 | + Serial.print("IP address: "); |
| 70 | + Serial.println(WiFi.localIP()); |
| 71 | + |
| 72 | + pinMode(ledPin, OUTPUT); // initialize ledPin as an output. |
| 73 | + digitalWrite(ledPin, HIGH); // initialize pin as high (LED Off) |
| 74 | +} |
| 75 | + |
| 76 | +void loop() { |
| 77 | + // Every "Bot_mtbs" the bot checks if any messages have arrived |
| 78 | + if (millis() > Bot_lasttime + Bot_mtbs) { |
| 79 | + Bot_lasttime = millis(); |
| 80 | + Serial.print(F("Checking for messages.. ")); |
| 81 | + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); |
| 82 | + Serial.print(numNewMessages); Serial.println(" new messages"); |
| 83 | + |
| 84 | + if(numNewMessages > 0){ |
| 85 | + handleNewMessages(numNewMessages); |
| 86 | + } |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +// Parse new messages and send them for interpretation |
| 91 | +void handleNewMessages(int numNewMessages) { |
| 92 | + // Extract info from the message |
| 93 | + for (int i = 0; i < numNewMessages; i++) { |
| 94 | + Serial.print(F("Handling message ")); Serial.println(i+1); |
| 95 | + String chat_id = String(bot.messages[i].chat_id); |
| 96 | + String text = bot.messages[i].text; |
| 97 | + |
| 98 | + String from_name = bot.messages[i].from_name; |
| 99 | + if (from_name == "") from_name = "Guest"; |
| 100 | + // Call the function for understand the message |
| 101 | + msgInterpretation(from_name, text, chat_id, bot.messages[i].type); |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +void msgInterpretation(String from_name, String text, String chat_id, String message_type) { |
| 106 | + Serial.print(F("Interpreting message: ")); Serial.println(text); |
| 107 | + Serial.print(F("Type: ")); Serial.println(message_type); |
| 108 | + Serial.print(F("From: ")); Serial.println(from_name); |
| 109 | + |
| 110 | + if (text == "/start") { // First interaction of user |
| 111 | + String welcome = "Hi " + from_name + "!\n"; |
| 112 | + welcome += "I am your Telegram Bot running on ESP32.\n\n"; |
| 113 | + welcome += "Select one of the /options below!\n\n"; |
| 114 | + String keyboardJson = "[[\"/ledon\", \"/ledoff\"],[\"/blink\", \"/PWM\"],[\"/status\"]]"; |
| 115 | + bot.sendMessageWithReplyKeyboard(chat_id, welcome, "Markdown", keyboardJson, true); |
| 116 | + } |
| 117 | + |
| 118 | + if (text == "/options") { // List out the custom keyboard |
| 119 | + String keyboardJson = "[[\"/ledon\", \"/ledoff\"],[\"/blink\", \"/PWM\"],[\"/status\"]]"; |
| 120 | + bot.sendMessageWithReplyKeyboard(chat_id, "Choose from one of the following options", "", keyboardJson, true); |
| 121 | + } |
| 122 | + |
| 123 | + if (text == "/status") { // Report present ledmode to user |
| 124 | + String response = "LED is "; |
| 125 | + switch (ledmode){ |
| 126 | + case ON: |
| 127 | + response += "on"; |
| 128 | + break; |
| 129 | + case OFF: |
| 130 | + response += "off"; |
| 131 | + break; |
| 132 | + case BLINK: |
| 133 | + response += "blinking"; |
| 134 | + break; |
| 135 | + case PWM: |
| 136 | + response += "PWMing"; |
| 137 | + break; |
| 138 | + } |
| 139 | + bot.sendMessage(chat_id, response, ""); |
| 140 | + } |
| 141 | + |
| 142 | + if (text == "/ledon") { |
| 143 | + ledmode = ON; |
| 144 | + ledcDetachPin(ledPin); // detach pin from ledc |
| 145 | + digitalWrite(ledPin, LOW); // turn the LED on (drive pin LOW) |
| 146 | + Serial.println(F("Turning LED on")); |
| 147 | + bot.sendMessage(chat_id, "Turning LED on", ""); |
| 148 | + } |
| 149 | + |
| 150 | + if (text == "/ledoff") { |
| 151 | + ledmode = OFF; |
| 152 | + ledcDetachPin(ledPin); // detach pin from ledc |
| 153 | + digitalWrite(ledPin, HIGH); // turn the LED off (drive pin HIGH) |
| 154 | + Serial.println(F("Turning LED off")); |
| 155 | + bot.sendMessage(chat_id, "Turning LED off", ""); |
| 156 | + } |
| 157 | + |
| 158 | + if (text == "/blink") { |
| 159 | + ledmode = BLINK; |
| 160 | + // We use ledc for blinking by setting PWM at a low frequency |
| 161 | + ledcSetup(0, 1, 8); // Channel, Freq., Resolution |
| 162 | + ledcAttachPin(ledPin, 0); // Pin, Channel |
| 163 | + ledcWrite(0, 192); // Channel, Duty (stay off for 90% time) (remember inverse polarity!) |
| 164 | + Serial.println(F("Blink set")); |
| 165 | + bot.sendMessage(chat_id, "Blink set", ""); |
| 166 | + } |
| 167 | + |
| 168 | + if (text == "/PWM") { // Send an inline keyboard for seleting PWM values (percentage) |
| 169 | + // For inline keyboard markup, see https://core.telegram.org/bots/api#inlinekeyboardmarkup |
| 170 | + String keyboardJson = "[[{ \"text\" : \"0\", \"callback_data\" : \"0\" }],"; |
| 171 | + keyboardJson += "[{ \"text\" : \"10\", \"callback_data\" : \"10\" },"; |
| 172 | + keyboardJson += "{ \"text\" : \"20\", \"callback_data\" : \"20\" },"; |
| 173 | + keyboardJson += "{ \"text\" : \"30\", \"callback_data\" : \"30\" }],"; |
| 174 | + keyboardJson += "[{ \"text\" : \"40\", \"callback_data\" : \"40\" },"; |
| 175 | + keyboardJson += "{ \"text\" : \"50\", \"callback_data\" : \"50\" },"; |
| 176 | + keyboardJson += "{ \"text\" : \"60\", \"callback_data\" : \"60\" }],"; |
| 177 | + keyboardJson += "[{ \"text\" : \"70\", \"callback_data\" : \"70\" },"; |
| 178 | + keyboardJson += "{ \"text\" : \"80\", \"callback_data\" : \"80\" },"; |
| 179 | + keyboardJson += "{ \"text\" : \"90\", \"callback_data\" : \"90\" }],"; |
| 180 | + keyboardJson += "[{ \"text\" : \"100\", \"callback_data\" : \"100\" }]]"; |
| 181 | + Serial.println(F("Sending PWM keyboard")); |
| 182 | + bot.sendMessageWithInlineKeyboard(chat_id, "Set PWM level", "", keyboardJson); |
| 183 | + } |
| 184 | + |
| 185 | + if(message_type=="callback_query") { // Received when user taps a button on inline keyboard |
| 186 | + // In our case, callback_query is only received for PWM values. In other cases you may |
| 187 | + // want to append an identifier to the values sent in 'callback_data' (e.g. 'duty=10') |
| 188 | + // and then check for it here using text.startsWith("duty=") or something similar. |
| 189 | + ledmode = PWM; // set proper LED mode |
| 190 | + uint8_t duty = text.toInt(); // Convert value to int |
| 191 | + duty = duty*2.55; // For duty between 0 - 100%, actual duty would be between 0 - 255 |
| 192 | + |
| 193 | + // We use ledc for PWM |
| 194 | + ledcSetup(0, 5000, 8); // Channel, Freq., Resolution |
| 195 | + ledcAttachPin(ledPin, 0); // Pin, Channel |
| 196 | + ledcWrite(0, 255-duty); // Channel, Duty (255 - x to inverse polarity) |
| 197 | + Serial.println(F("PWM set")); |
| 198 | + String message = "PWM set with duty "; |
| 199 | + message += String(duty); |
| 200 | + bot.sendMessage(chat_id, message, ""); |
| 201 | + } |
| 202 | +} |
0 commit comments