running version of TelegramBot that can show 2 lines of Text
This commit is contained in:
parent
ce8dd2b42f
commit
49d043bd5e
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
/.vscode/extensions.json
|
||||
secrets.h
|
||||
35
include/FlipDotDrv.h
Normal file
35
include/FlipDotDrv.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
|
||||
class FlipDotDrv
|
||||
{
|
||||
private:
|
||||
static constexpr uint8_t templateFrameStart {0x02};
|
||||
static constexpr uint8_t templateFrameAddressByte1 {'1'};
|
||||
static constexpr uint8_t templateFrameAddressByte2 {'0'};
|
||||
uint8_t FrameResolution[2] {};
|
||||
uint8_t *FrameData {nullptr};
|
||||
static constexpr uint8_t templateFrameEnd {0x03};
|
||||
uint8_t FrameCrc[2] {};
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint8_t address;
|
||||
uint8_t *buffer {nullptr};
|
||||
uint16_t FrameDataLength;
|
||||
uint16_t bufferLength;
|
||||
|
||||
GFXcanvas1 myCanvas;
|
||||
|
||||
public:
|
||||
FlipDotDrv(uint8_t width, uint8_t height, uint8_t address);
|
||||
~FlipDotDrv();
|
||||
|
||||
void sendRaw(const uint8_t* bmp, uint16_t length);
|
||||
|
||||
void printText(const char* txt, uint8_t multiplier = 1);
|
||||
void printText(const char* txt, uint8_t x, uint8_t y, uint8_t multiplier = 1);
|
||||
};
|
||||
|
||||
14
include/ITrigger.h
Normal file
14
include/ITrigger.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
class ITrigger
|
||||
{
|
||||
public:
|
||||
ITrigger(/* args */) = default;
|
||||
~ITrigger() = default;
|
||||
|
||||
virtual void printText(String text) = 0;
|
||||
virtual void printOpen() = 0;
|
||||
virtual void printClose() = 0;
|
||||
};
|
||||
|
||||
39
include/README
Normal file
39
include/README
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
29
include/Telegram.h
Normal file
29
include/Telegram.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <UniversalTelegramBot.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
#include "ITrigger.h"
|
||||
|
||||
class Telegram
|
||||
{
|
||||
private:
|
||||
static const char *BOT_TOKEN;
|
||||
static const unsigned long BOT_MTBS; // mean time between scan messages
|
||||
|
||||
|
||||
unsigned long bot_lasttime; // last time messages' scan has been done
|
||||
ITrigger &trigger;
|
||||
WiFiClientSecure &secured_client;
|
||||
UniversalTelegramBot bot;
|
||||
|
||||
void handleNewMessages(int numNewMessages);
|
||||
|
||||
public:
|
||||
Telegram(WiFiClientSecure &sec_client, ITrigger &trig);
|
||||
~Telegram();
|
||||
|
||||
void init();
|
||||
void cyclic(unsigned long now);
|
||||
};
|
||||
|
||||
7
include/secrets.h_template
Normal file
7
include/secrets.h_template
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#define TELEGRAM_BOT_TOKEN "123123123123:BBCeAAewGN_wayA123VnbqRNJL4l3dpXy2S"
|
||||
#define TELEGRAM_BOT_OWNER "321123321"
|
||||
|
||||
#define WIFI_SSID "Wifi_SSID"
|
||||
#define WIFI_PASSWORD "secretPassword"
|
||||
46
lib/README
Normal file
46
lib/README
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
19
platformio.ini
Normal file
19
platformio.ini
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
lib_deps =
|
||||
witnessmenow/UniversalTelegramBot @ ^1.3.0
|
||||
adafruit/Adafruit GFX Library @ ^1.11.11
|
||||
build_flags=-DTELEGRAM_DEBUG
|
||||
115
src/FlipDotDrv.cpp
Normal file
115
src/FlipDotDrv.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include "FlipDotDrv.h"
|
||||
|
||||
#include <Fonts/FreeSans9pt7b.h>
|
||||
|
||||
|
||||
FlipDotDrv::FlipDotDrv(uint8_t width, uint8_t height, uint8_t address)
|
||||
: myCanvas{width, height}
|
||||
{
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->address = address;
|
||||
|
||||
this->FrameDataLength = (width * height / 8 * 2);
|
||||
this->bufferLength = 5 + FrameDataLength + 3;
|
||||
|
||||
this->buffer = new uint8_t[this->bufferLength];
|
||||
this->FrameData = this->buffer + 5;
|
||||
|
||||
pinMode(5,OUTPUT);
|
||||
digitalWrite(5, LOW);
|
||||
|
||||
Serial2.begin(4800, SERIAL_8N1, 16, 17); // (unsigned long baud, uint32_t config = 134217756U, int8_t rxPin = (int8_t)(-1), int8_t txPin = (int8_t)(-1), bool invert = false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = (uint8_t)112U)
|
||||
}
|
||||
|
||||
FlipDotDrv::~FlipDotDrv()
|
||||
{
|
||||
free(this->FrameData);
|
||||
}
|
||||
|
||||
void FlipDotDrv::sendRaw(const uint8_t* bmp, uint16_t length)
|
||||
{
|
||||
char tmpBuff[3] = {0};
|
||||
uint8_t chkSum = 0;
|
||||
|
||||
if (length != (this->width * this->height / 8))
|
||||
{
|
||||
Serial.print("length ");
|
||||
Serial.print(length);
|
||||
Serial.println(" [Bytes] of bitmap is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
this->buffer[0] = templateFrameStart;
|
||||
this->buffer[1] = templateFrameAddressByte1;
|
||||
this->buffer[2] = templateFrameAddressByte2 + this->address;
|
||||
chkSum += this->buffer[1];
|
||||
chkSum += this->buffer[2];
|
||||
|
||||
snprintf(tmpBuff, sizeof(tmpBuff), "%02X", (this->width * this->height / 8));
|
||||
this->buffer[3] = tmpBuff[0];
|
||||
this->buffer[4] = tmpBuff[1];
|
||||
chkSum += this->buffer[3];
|
||||
chkSum += this->buffer[4];
|
||||
|
||||
for (uint16_t i = 0; i < length; ++i)
|
||||
{
|
||||
snprintf(tmpBuff, sizeof(tmpBuff), "%02X", bmp[i]);
|
||||
this->FrameData[i * 2 + 0] = tmpBuff[0];
|
||||
this->FrameData[i * 2 + 1] = tmpBuff[1];
|
||||
|
||||
chkSum += tmpBuff[0];
|
||||
chkSum += tmpBuff[1];
|
||||
}
|
||||
|
||||
this->buffer[5 + FrameDataLength + 0] = templateFrameEnd;
|
||||
chkSum += this->buffer[5 + FrameDataLength + 0];
|
||||
|
||||
chkSum ^= 0xff;
|
||||
chkSum += 1;
|
||||
snprintf(tmpBuff, sizeof(tmpBuff), "%02X", chkSum);
|
||||
this->buffer[5 + FrameDataLength + 1] = tmpBuff[0];
|
||||
this->buffer[5 + FrameDataLength + 2] = tmpBuff[1];
|
||||
|
||||
// digitalWrite(5, HIGH);
|
||||
// delay(200);
|
||||
Serial2.write(this->buffer, this->bufferLength);
|
||||
Serial2.flush();
|
||||
// delay(1000);
|
||||
// digitalWrite(5, LOW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FlipDotDrv::printText(const char* txt, uint8_t multiplier)
|
||||
{
|
||||
printText(txt, 0, 0, multiplier);
|
||||
}
|
||||
|
||||
void FlipDotDrv::printText(const char* txt, uint8_t x, uint8_t y, uint8_t multiplier)
|
||||
{
|
||||
myCanvas.fillScreen(0);
|
||||
|
||||
// myCanvas.setFont(&FreeSans9pt7b);
|
||||
myCanvas.setFont(NULL);
|
||||
myCanvas.setTextSize(multiplier);
|
||||
|
||||
myCanvas.setCursor(x, y);
|
||||
myCanvas.print(txt);
|
||||
|
||||
uint8_t rawBuff[192] = {};
|
||||
|
||||
for (int i = 0; i < (this->width * this->height / 8); ++i)
|
||||
{
|
||||
rawBuff[i] = (myCanvas.getPixel(i / 2, ((i % 2) * 8) + 0) << 0|
|
||||
myCanvas.getPixel(i / 2, ((i % 2) * 8) + 1) << 1|
|
||||
myCanvas.getPixel(i / 2, ((i % 2) * 8) + 2) << 2|
|
||||
myCanvas.getPixel(i / 2, ((i % 2) * 8) + 3) << 3|
|
||||
myCanvas.getPixel(i / 2, ((i % 2) * 8) + 4) << 4|
|
||||
myCanvas.getPixel(i / 2, ((i % 2) * 8) + 5) << 5|
|
||||
myCanvas.getPixel(i / 2, ((i % 2) * 8) + 6) << 6|
|
||||
myCanvas.getPixel(i / 2, ((i % 2) * 8) + 7) << 7 );
|
||||
}
|
||||
|
||||
this->sendRaw(rawBuff, sizeof(rawBuff));
|
||||
}
|
||||
126
src/Telegram.cpp
Normal file
126
src/Telegram.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include <Telegram.h>
|
||||
#include "secrets.h"
|
||||
|
||||
const char *Telegram::BOT_TOKEN = "7502550270:AAEoCSfZJU_wayW453AmarOMIJ7k3iqQb9Y";
|
||||
const unsigned long Telegram::BOT_MTBS = 1000; // mean time between scan messages
|
||||
|
||||
void Telegram::handleNewMessages(int numNewMessages)
|
||||
{
|
||||
Serial.println("handleNewMessages");
|
||||
Serial.println(String(numNewMessages));
|
||||
|
||||
for (int i = 0; i < numNewMessages; i++)
|
||||
{
|
||||
String chat_id = bot.messages[i].chat_id;
|
||||
String text = bot.messages[i].text;
|
||||
|
||||
String from_name = bot.messages[i].from_name;
|
||||
if (from_name == "")
|
||||
from_name = "Guest";
|
||||
|
||||
if (text == "/send_test_action")
|
||||
{
|
||||
bot.sendChatAction(chat_id, "typing");
|
||||
delay(4000);
|
||||
bot.sendMessage(chat_id, "Did you see the action message?");
|
||||
|
||||
// You can't use own message, just choose from one of bellow
|
||||
|
||||
// typing for text messages
|
||||
// upload_photo for photos
|
||||
// record_video or upload_video for videos
|
||||
// record_audio or upload_audio for audio files
|
||||
// upload_document for general files
|
||||
// find_location for location data
|
||||
|
||||
// more info here - https://core.telegram.org/bots/api#sendchataction
|
||||
}
|
||||
|
||||
if (text == "/send_test_action2")
|
||||
{
|
||||
bot.sendChatAction(chat_id, "find_location");
|
||||
delay(4000);
|
||||
bot.sendMessage(chat_id, "Did you see the action message?");
|
||||
}
|
||||
|
||||
if (text.startsWith("/txt "))
|
||||
{
|
||||
trigger.printText(text.substring(5));
|
||||
}
|
||||
|
||||
if (text.startsWith("/open"))
|
||||
{
|
||||
trigger.printOpen();
|
||||
}
|
||||
|
||||
if (text.startsWith("/close"))
|
||||
{
|
||||
trigger.printClose();
|
||||
}
|
||||
|
||||
if (text == "/start")
|
||||
{
|
||||
String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n";
|
||||
welcome += "This is Chat Action Bot example.\n\n";
|
||||
welcome += "/send_test_action : to send test chat action message\n";
|
||||
welcome += "/send_test_action2 : to send test chat action message\n";
|
||||
bot.sendMessage(chat_id, welcome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Telegram::Telegram(WiFiClientSecure &sec_client, ITrigger &trig)
|
||||
: trigger(trig), secured_client(sec_client), bot(BOT_TOKEN, sec_client) {}
|
||||
|
||||
Telegram::~Telegram() {}
|
||||
|
||||
void Telegram::init()
|
||||
{
|
||||
secured_client.setInsecure();
|
||||
secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org
|
||||
secured_client.setHandshakeTimeout(5);
|
||||
// secured_client.setTimeout(5);
|
||||
|
||||
Serial.println("clearing old messages");
|
||||
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
|
||||
while (numNewMessages)
|
||||
{
|
||||
for (int i = 0; i < numNewMessages; i++)
|
||||
{
|
||||
String chat_id = bot.messages[i].chat_id;
|
||||
String text = bot.messages[i].text;
|
||||
String from_name = bot.messages[i].from_name;
|
||||
|
||||
String txt = String("ignored '") + text + String("' from ") + from_name +String("(") + chat_id + String(")");
|
||||
|
||||
Serial.println(txt);
|
||||
}
|
||||
numNewMessages = bot.getUpdates(bot.last_message_received + 1);
|
||||
}
|
||||
|
||||
bot.sendMessage(TELEGRAM_BOT_OWNER, "Hi I'm online.");
|
||||
bot_lasttime = millis();
|
||||
}
|
||||
|
||||
void Telegram::cyclic(unsigned long now)
|
||||
{
|
||||
if (now - bot_lasttime > BOT_MTBS)
|
||||
{
|
||||
Serial.print(bot.last_message_received);
|
||||
Serial.println(" checking");
|
||||
|
||||
auto stat = WiFi.status();
|
||||
Serial.println("WifiStat= ");
|
||||
Serial.println(stat);
|
||||
|
||||
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
|
||||
|
||||
while (numNewMessages)
|
||||
{
|
||||
handleNewMessages(numNewMessages);
|
||||
numNewMessages = bot.getUpdates(bot.last_message_received + 1);
|
||||
}
|
||||
|
||||
bot_lasttime = now;
|
||||
}
|
||||
}
|
||||
124
src/main.cpp
Normal file
124
src/main.cpp
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
#include "Telegram.h"
|
||||
#include "ITrigger.h"
|
||||
#include "FlipDotDrv.h"
|
||||
#include "secrets.h"
|
||||
|
||||
// BearSSL::WiFiClientSecure secured_client;
|
||||
WiFiClientSecure secured_client;
|
||||
bool Start = false;
|
||||
|
||||
FlipDotDrv flip(96, 16, 1);
|
||||
|
||||
class myTrigger : public ITrigger
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
myTrigger(/* args */) = default;
|
||||
~myTrigger() = default;
|
||||
|
||||
void printText(String text) override
|
||||
{
|
||||
Serial.print("Display would show '");
|
||||
Serial.print(text);
|
||||
Serial.println("'");
|
||||
flip.printText(text.c_str());
|
||||
}
|
||||
|
||||
void printOpen() override
|
||||
{
|
||||
flip.printText("offen", 18, 0, 2);
|
||||
}
|
||||
|
||||
void printClose() override
|
||||
{
|
||||
flip.printText("geschlossen", 15, 4, 1);
|
||||
}
|
||||
|
||||
} trigg;
|
||||
|
||||
|
||||
Telegram tele(secured_client, trigg);
|
||||
|
||||
uint8_t rawBuff[192] = {};
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
|
||||
|
||||
|
||||
Serial.println("Initializing Display");
|
||||
flip.sendRaw(rawBuff, sizeof(rawBuff));
|
||||
|
||||
delay(500);
|
||||
Serial.println("draw checker");
|
||||
memset(rawBuff, 0xAA, 192);
|
||||
for (int i = 0; i < 192; ++i)
|
||||
{
|
||||
if ((i % 4) < 2)
|
||||
rawBuff[i] = 0xAA;
|
||||
else
|
||||
rawBuff[i] = 0x55;
|
||||
}
|
||||
flip.sendRaw(rawBuff, sizeof(rawBuff));
|
||||
delay(500);
|
||||
Serial.println("bigger checker");
|
||||
for (int i = 0; i < 192; ++i)
|
||||
{
|
||||
if ((i % 8) < 4)
|
||||
rawBuff[i] = 0x33;
|
||||
else
|
||||
rawBuff[i] = 0xCC;
|
||||
}
|
||||
flip.sendRaw(rawBuff, sizeof(rawBuff));
|
||||
delay(500);
|
||||
Serial.println("largest checker");
|
||||
for (int i = 0; i < 192; ++i)
|
||||
{
|
||||
if ((i % 16) < 8)
|
||||
rawBuff[i] = 0x0F;
|
||||
else
|
||||
rawBuff[i] = 0xF0;
|
||||
}
|
||||
flip.sendRaw(rawBuff, sizeof(rawBuff));
|
||||
|
||||
// attempt to connect to Wifi network:
|
||||
Serial.print("Connecting to Wifi SSID ");
|
||||
Serial.print(WIFI_SSID);
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
Serial.print(".");
|
||||
delay(500);
|
||||
}
|
||||
Serial.print("\nWiFi connected. IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
Serial.print("Retrieving time: ");
|
||||
configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
|
||||
time_t now = time(nullptr);
|
||||
while (now < 24 * 3600)
|
||||
{
|
||||
Serial.print(".");
|
||||
delay(100);
|
||||
now = time(nullptr);
|
||||
}
|
||||
Serial.println(now);
|
||||
|
||||
|
||||
tele.init();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long now = millis();
|
||||
|
||||
tele.cyclic(now);
|
||||
yield();
|
||||
}
|
||||
11
test/README
Normal file
11
test/README
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
Loading…
Reference in New Issue
Block a user