BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

My attempts at transferring BLYNK_PRINT to Various Displays


#1

EDIT - As I am progressing on this attempt to emulate what smrtr people can do, I have moved my posts to my own topic so as not to clutter up @vhymanskyy accomplishment topic :wink:


Looks like the u8g2 Library also supports the Arduino print() function. But clearly a PCD8544_84X48 LCD doesn’t cut it… at least in u8x8 straight text mode (fixed font size) :slight_smile:

So far I haven’t had any results with the u8g2 graphical font mode. I haven’t figured out its screen buffer method yet :thinking:


OTA NodeMCU
Serial arduino to terminal blynk
I want it to show the information of the serial begin (9600) of arduino to the Terminal of blink
Bring Blynk console to the LCD/TFT/OLED screen
Event logs widget
Turn ESP32 + OLED as a real-time “serial monitor”, Blynk debugging monitor, etc
#2

Well, this has been fun and all… but also frustrating due my limited programming experience.

I have managed to use smaller fonts, fitting 8-9 lines per screen, with the u8g2 graphical font and buffer dumps… but becasue it needs manual cursor placement for a new line, everything just scrolls along the top line of the screen and instantly becomes unreadable

I just can’t get my head around the complexity of pipes and redirects, etc. in order to figure out how to detect any end of line commands in the stdout buffer or in the BLYNK_PRINT routine :confounded:

So, while I have a nice if() routine to scroll the cursor, one line at a time, I can’t trigger it as necessary.

Much more hassle then worth for my limited LCD :stuck_out_tongue: But a good “make brain work” project :exploding_head:

So if anyone has insight into simply detecting a EOL '\n' in the outgoing serial buffer or BLYNK_PRINT routine, in a way that an if() loop can utilise, that would be appreciated.


#3

Don’t use if, use while :wink: That way you can loop until \n

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

Something like that I think


#4

That works for something like an incoming Serial buffer… but what I am dealing with is how @vhymanskyy was processing the BLYNK_PRINT. But instead of…

BLYNK_PRINT Serial;

or his use of…

BLYNK_PRINT Screen

I am using…

BLYNK_PRINT u8g2  // U8g2: Library for monochrome displays

void setup() {
  u8g2.begin();
  u8g2.enableUTF8Print();  // Activates UTF8 support for the Arduino print function
//...
}

So, no easy (for me) access to the stdout buffer that handles the Arduino Print() function (as I understand it).

I am tweaking the code I have before posting it… so far I am getting some results… just not the holy grail of the Blynk logo :stuck_out_tongue_winking_eye:


#5

Hmm, ok I see your issue. I don’t have a 5110 screen handy, I used that Nokia to reinforce the house I live in…


#6

2nd best use of it :stuck_out_tongue_winking_eye:

Well, I am getting further… but have to use DEBUG to get any real data


#7

Have you seen this library:

It says it has ‘experimental’ support for the Nokia display.

Pete.


#8

That library looks nice… I think I will experiment with it and some of my TFT displays… problem is they are Arduino shields and I don’t think they are SPI or i2C… can’t remember.


#9

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… :thinking:

My dream of a “portable” Blynk status and debug monitor is still out of my grasp… with this cutting edge screen at least :wink: But as stated, it is good fearning… I am learning to not toss the thing out the window :stuck_out_tongue_winking_eye:

#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();
  }
}

#10

off topic: How much does that heat-sink help?
Temps before/after?


#11

@Gunner
which LCD are you using?
which library are you using?
i have used Adafruit_GFX & Adafruit_PCD8544 Libraries for my project.


#12

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 :wink:

Now the little regulator, that gets hot :fire: … 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.


#13

It is a Chineseium Nokia knockoff PCD-8544

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.


#14

@vhymanskyy 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?


#15

@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 :wink:

P.S. Another example of how this approach is used in Blynk library, is WidgetTerminal.


BLYNK_DEBUG print to terminal
#16

Getting closer…


#17

Well thank you @vhymanskyy 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 :wink: 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.

And for anyone interested, here is the code.

Much of my if() checking is just for displaying the Blynk Logo the way I wanted it :stuck_out_tongue_winking_eye: 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
}

#18

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 :wink:

I still have it plugged into the PC for testing… so it was nice to compare the two…

image

OH, Look… Something? happened after a really big number :stuck_out_tongue: … Now all I need is a higher resolution LCD, or a nice wide format OLED… added to my Christmas list.


#19

Need something compact, enough screen real estate… but affordable for individual device use…

Probably still not big enough?? But might work with reduced font.


#20

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? :laughing: