The main problem is:
This is an simple library for 128*32 I2C OLED displays on HelTec WIFI Kit 8.
Credits
Original code was taken from ESP8266-I2C-OLED project and was modified in form of a library suitable for using with Arduino IDE.
This library just include some basic initial and display function. We highly recommend use a u8g2 library.
How to install u8g2 library
Search "u8g2" in Arduino library mananger and install it.
The code for the print function
void OLED::print(char *s, uint8_t r, uint8_t c) {
DEBUG_PRINT("print ");
DEBUG_PRINT(r);
DEBUG_PRINT(",");
DEBUG_PRINT(c);
DEBUG_PRINT(" ");
DEBUG_PRINTLN(s);
sendStrXY(s, r, c);
}
So your code only looks like it would work, print() expects a zero terminated string.
There happens to be a zero character behind the character you want to print.
If you add other variables or change the code that can change,
or it can change during program execution.
I would also recommend to use the u8g2 library.
As Whandall said, your code results in undefined behavior. You're just lucky that the next byte is null.
I'm just going to quote myself here on the other problems with this approach.
PieterP:
The Arduino's ADC has 10 bits of precision. A char is only 8 bits wide.
On top of that, you want to print it as a readable number, not as ASCII.
E.g. if you read an analog value of 833, the following code would print 'A'.
char va = analogRead(A0);
display.print(&va);
This is because 833 mod 2<sup>8</sup> = 65, which is the ASCII representation of 'A'.
On top of that, it'll probably print all kinds of junk afterwards, because it expects a terminating null character.
I see no good reason to use a fork from the ESP8266 Core with non-standard libraries. I'd just use the 'official', well-supported ESP8266 Arduino Core, and an established OLED library like u8g2 or Adafruit SSD1306.
jremington:
It is very strange that that seems to work for you. What actually gets printed on the display?
Have you (or does your code) somehow redefine Arduino char()?
You're right ... I had compiled the code and it compiled just fine. Then I moved onto something else without actually uploading the code and testing it. Upon testing it, it only puts garbage on the screen. However, doing a Serial.println of the same data yields an accurate number.
jremington:
Here is how to fix your immediate problem:
char buf[8]; //reserve space for itoa() to create string
display.print(itoa(analogRead(A0), buf, 10));
This actually does work.
PieterP:
I'd just use the 'official', well-supported ESP8266 Arduino Core, and an established OLED library like u8g2 or Adafruit SSD1306.
So I ended up switching to those libraries as you suggested, and here is the code that proved the most beneficial that works well as you can see from the images:
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define SDA 4 //GPIO4 -- D2 -- 4
#define SCL 5 //GPIO5 -- D1 -- 5
#define RST 16 //GPIO16 -- D0 -- 16
#define in 0
U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C oled(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ RST); // Adafruit Feather ESP8266/32u4 Boards + FeatherWing OLED
int xPos = 30;
const double PWM_Ratio PROGMEM = 00306976744186047ll;
char buf[20];
void setup(void) {
pinMode(in, INPUT);
pinMode(RST, OUTPUT);
oled.begin();
oled.setFont(u8g2_font_inb30_mf);
}
void loop(void) {
double value = double(analogRead(in)) * PWM_Ratio;
String volts = String(value, 2) + "V";
volts.toCharArray(buf, 20);
oled.firstPage();
do {
oled.drawStr(0,xPos,buf);
} while ( oled.nextPage() );
delay(200);
}