Well, until I can suss out the proper EOL timing, this is the best I can get without flooding Debug data at it… and even then it doesn’t actually print in the proper line order all the time (note the ms times are out of order).
But something with the EOL must be automatically being accounted for in the buffer dump…everything lines up to the left margin properly…
My dream of a “portable” Blynk status and debug monitor is still out of my grasp… with this cutting edge screen at least But as stated, it is good fearning… I am learning to not toss the thing out the window
#include <SPI.h> // For LCD
#include <U8g2lib.h> // For LCD
U8G2_PCD8544_84X48_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 16, /* dc=*/ 4, /* reset=*/ 17); // Nokia 5110 Display
#define BLYNK_PRINT u8g2
//#define BLYNK_DEBUG
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <ESPmDNS.h> // For OTA
#include <WiFiUdp.h> // For OTA
#include <ArduinoOTA.h> // For OTA
#include <TimeLib.h>
#include <WidgetRTC.h>
char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
int line;
int height = 6;
BlynkTimer timer;
WidgetRTC rtc;
void setup() {
u8g2.begin();
u8g2.enableUTF8Print(); // Set for Arduino Print() support
u8g2.setFont(u8g2_font_u8glib_4_hf); // Choose a suitable font
u8g2.drawFrame(0, 0, 83, 47); // Draw Frame
line = height;
Blynk.begin(auth, ssid, pass, "xxx.xxx.xxx.xxx", 8442);
rtc.begin();
setSyncInterval(30); // Show somthing on the screen every 30 seconds (Time Sync: OK)
timer.setInterval(100, []() { // Up Time
Blynk.virtualWrite(V1, millis() / 1000);
});
ArduinoOTA.setHostname("Lolin32"); // For OTA
ArduinoOTA.begin(); // For OTA
}
void loop()
{
u8g2.setCursor(0, line);// Sets the left/bottom start point for first character
u8g2.sendBuffer(); // this is what dumps data the th LCD
// Makeshift... line shifter
line += height;
if (line > 48) {
line = height;
}
Blynk.run();
timer.run();
ArduinoOTA.handle(); // For OTA
}
BLYNK_WRITE(V0) { // Optional frame and screen clear
if (param.asInt() == 1) {
u8g2.drawFrame(0, 0, 83, 47); // Draw Box
} else {
u8g2.clearDisplay();
}
}
Negligible at best… without it the metal casing never gets above 39°C I just put the heat sink there cuz it was rattling around on my desk otherwise
Now the little regulator, that gets hot … but then I am also using the ESP32 to power a 3.3v rail on the breadboard for a ESP-01 as I don’t have any other regulators.
And the library for this project is the aformentioned u8g2 because it has the needed, for this application, UTF8 support for the Arduino print function.
@vshymanskyy I think I am in the right direction in looking for syncing EOL and my own cursor positioning,
But I am not well versed in C++ to both discover the correct point (without insight) wherein I might intercept and and interpret (I am working on that via Google) the outgoing characters from BLYNK_PRINT to the target (i.e. Serial, Serial1, Screen, u8g2, etc).
At this point I would like to simultaneously and internally (via code) monitor the output as well as react to specific characters in said output.
I have found a few files locations in the Blynk Library, based on a simple search of BLYNK_PRINT, but can you, or someone, point me to the correct file, and perhaps correct segment of said file, where the characters are actually passed on?
@Gunner
The easiest way is to define your own custom console object:
// Lets define a custom console
class CustomConsole
: public Print // This automatically adds functions like .println()
{
public:
CustomConsole() {}
virtual size_t write(uint8_t ch) {
// Process symbols here:
//if (ch == '\n') ...
return 1; // <- this means we processed 1 symbol
}
private:
// Here you can define some variables you want to use in your console
int cursorY = 0;
int cursorX = 0;
};
// Now we instantiate it
CustomConsole myConsole;
// And use for Blynk output
#define BLYNK_PRINT myConsole
... [rest of the sketch] ...
These print(), println() functions are added from Print class, and it will call your write function every time it wants to print a symbol. You can then apply your own logic of any complexity
P.S. Another example of how this approach is used in Blynk library, is WidgetTerminal.
Well thank you @vshymanskyy Once I got my head around it, I made it work with this wee little LCD.
Not much practical use on such a small screen, but all output is more or less readable Larger font at the start for a logo that, while truncated, is all lined up… then to a smaller font for “normal” serial output.
Nice thing is, this should work on any size LCD that the u8g2 Library supports.
Much of my if() checking is just for displaying the Blynk Logo the way I wanted it and could be discarded to simplify the print output, which scrolls line by line until at the bottom, then clearing and starting from the top.
#include <SPI.h> // For LCD
#include <U8g2lib.h> // For LCD
U8G2_PCD8544_84X48_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 16, /* dc=*/ 4, /* reset=*/ 17); // Nokia 5110 Display
// Define a custom console for LCD debug output
class CustomConsole
: public Print // This automatically adds functions like .println()
{
public:
CustomConsole() {}
virtual size_t write(uint8_t ch) { // Grabs character from print?
u8g2.print(char(ch)); // Add character to LCD buffer
Serial.print(char(ch)); // Repeat all character output to Serial monitor
if (char(ch) == ']') { // Watch for closing brackets
x++; // Increment bracket count
if (x == 4) { // If after forth closing bracket on millis count...
line -= height; // ... backstep one line to fit Blynk Logo on screen
}
}
if (ch == '\n') { // End of line check
line += height; // Increment next line down
u8g2.sendBuffer(); // Dump buffer to LCD
if (line >= 49) { // Last line on screen check
if (x == 4) { // If after fourth closing bracket on millis count...
delay(10000); // ... delay 10 seconds to view Blynk Logo
u8g2.setFont(u8g2_font_u8glib_4_hf); // set font to smaller size for remainder of debug prints
u8g2.clearDisplay(); // Clear display
}
u8g2.sendBuffer(); // Dump buffer to LCD
u8g2.setCursor(0, height); // Reset line to top of screen
line = height; // Reset line counter
delay(500); // Small delay to allow visual of last line output on LCD
u8g2.clearDisplay(); // Clear display
} else {
u8g2.sendBuffer(); // Dump buffer to LCD
u8g2.setCursor(0, line); // Set curser to next line down
}
}
return 1; // Processed 1 character
}
private:
// Here you can define some variables you want to use in your console
int x = 0; // bracket counter
int line; // line counter
int height = 6; // Line pixel height
};
// Now we instantiate it
CustomConsole myConsole;
#define BLYNK_PRINT myConsole
//#define BLYNK_DEBUG
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <ESPmDNS.h> // For OTA
#include <WiFiUdp.h> // For OTA
#include <ArduinoOTA.h> // For OTA
#include <TimeLib.h>
#include <WidgetRTC.h>
char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
char server[] = "xxx.xxx.xxx.xxx";
int line;
int height = 6; // Line pixel height
BlynkTimer timer;
WidgetRTC rtc;
void setup() {
line = height; // Reset line counter
Serial.begin(115200);
u8g2.begin(); // Start LCD library
u8g2.enableUTF8Print(); // Activates UTF8 support for the Arduino print function
u8g2.setFont(u8g2_font_micro_mr); // choose a suitable font for Logo
u8g2.setCursor(0, 6); // Sratrt at top line of LCD
//Blynk.connectWiFi(ssid, pass);
//Blynk.config(auth, server, 8442);
Blynk.begin(auth, ssid, pass, server, 8442);
rtc.begin();
setSyncInterval(30); // Time Sync - not working with Blink.config()??
BLYNK_LOG("Hello Gunner"); // Say Hello
timer.setInterval(1000, []() { // Up Time
Blynk.virtualWrite(V1, millis() / 1000); // Display Uptime in seconds
BLYNK_LOG("Hello Gunner"); // Initial message
//u8g2.print(WiFi.RSSI()); // Optional RSSI strength
});
ArduinoOTA.setHostname("Lolin32"); // For OTA
ArduinoOTA.begin(); // For OTA
}
void loop() {
Blynk.run();
timer.run();
ArduinoOTA.handle(); // For OTA
}
Yes! it verx! … one of the purposes of this was to eventually have a localised (aka On Device) debug of things normally only seen on the Serial monitor…
So somehow, my device lost connection… considering it does nothing right now but (supposedly) regularly sync the time… but refuses to say so?? 'nother issue 'nother day
I still have it plugged into the PC for testing… so it was nice to compare the two…
OH, Look… Something? happened after a really big number … Now all I need is a higher resolution LCD, or a nice wide format OLED… added to my Christmas list.
I like the idea! In spare time will try to use my brand new (but already 2 years old…) UC1608 240x128 display supported by u8glib. Will Blynk logo fit on that?
I am too lazy to make a proper YouTube video … but here is a GIF of my current alliteration… I realise now that you can’t really see the data scrolling by in the top half of the LCD…
I merged in my above redirection code and a Virtual LED matrix code (not showing, but running in another tab) and now also containing random servo moves and CPU temp checks - Basically a programming test bench for my ESP32.
The top half of the screen is a scrolling account of any Blynk prints, logs & errors, plus any timer based “serial” prints I make, actually myConsole.println(), such as RSSI and time/date stamps.
While the bottom half is a direct screen print of real-time data like Servo position and CPU temp.
One benefit I have already noticed is that occasionally my ESP seemed to loose Blynk connection… but even while originally using Blynk.begin() and without any coded checks or Blynk.run() bypasses, somehow keep on running everything else in the code?? maybe an automatic dual core ESP32 thing??
Anyhow… so I never really knew it was disconnected until I checked the App. But now I can see the "connecting to… " message in the screen
I have since added in Blynk.config() and re-connection routines
Well, I am not sure where my fascination with displays and LEDs comes from… probably the whole visual understanding thing… but I can’t leave this one alone
So I finally managed to get my little SSD1331, a 96x64 Full Colour OLED display (that I had previously wired as a Wemos shield) and added in this Blynk print redirection… so far so good.
The best library I found for this OLED for speed is an older one. https://github.com/sumotoy/SSD_13XX But very fast and relatively easy to program for… just lousy / non-existent directions for all the commands… have to spend lots of time dissecting and testing from the library files.
It allows simpler Blynk Print setup and word wrapping… which makes it much nicer to just dump test to
It even has a small collection of external fonts. Unfortunately, the font that looks the best for the Blynk Logo (Terminal_9) is a bit too big… so only half a logo for me
//#define BLYNK_DEBUG
#define BLYNK_NO_BUILTIN // Disable Blynk's built-in analog & digital pin operations
#include <SPI.h>
#include <SSD_13XX.h>
#include "_fonts/Terminal_9.c"
#define __CS_TFT 16 // pin D0
#define __DC_TFT 15 // pin D8
SSD_13XX tft = SSD_13XX(__CS_TFT, __DC_TFT);
class CustomConsole
: public Print // This automatically adds functions like .println()
{
public:
CustomConsole() {}
virtual size_t write(uint8_t ch) { // Grabs character from print
tft.setTextWrap(false); // Enable/disable word wrapping
tft.setFontInterline(1); // Add single pixel in-between lines
tft.print(char(ch)); // print character to OLED
Serial.print(char(ch)); // Repeat all character output to Serial monitor
if (ch == '\n') { // End of line check
line ++;
if (line >= 7 ) { // Last line on screen check
line = 0; // Reset line counter
if (firstScreen == 0) {
firstScreen = 1;
delay(5000); // One-time delay to view Logo :)
}
tft.print(char(ch)); // print character to OLED
delay(500); // Small delay to allow viewing of last line befor screen clear
tft.clearScreen();
} // End screen wrap
} // End line count
return 1; // Processed 1 character
} // End character print
private:
int line = 0;
int firstScreen = 0;
};
CustomConsole myConsole;
#define BLYNK_PRINT myConsole
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;
char auth[] = "xxxxxxxxxx"; // Local Server
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
char server[] = "xxx.xxx.xxx.xxx";
int port = 8080;
void setup() {
Serial.begin(115200);
tft.begin();
WiFi.begin(ssid, pass);
Blynk.config(auth, server, port);
Blynk.connect();
// Timed Lambda Function - UpTime counter
timer.setInterval(1000L, []() { // Run every second
Blynk.virtualWrite(V0, millis() / 1000); // Display the UpTime in Minutes to App
myConsole.println(millis() / 1000); // Display the UpTime in Minutes to OLED and Serial
}); // END Timer Function
}
void loop() {
Blynk.run();
timer.run();
}
@Gunner can you please provide the full pin details for the OLED you are using. I have 4 or 5 OLED’s that I haven’t used for a year or more. Some have 4 pins but with pins switched around between different models and some have 7 like yours. Might be my lack of soldering skills that’s a problem but I couldn’t get any of them to work. They were working when I last used them but I might have destroyed one of them.
In the old days you had to tweak the libraries to your particular OLED but it looks like most of that is now done in the sketch.