Strings and OLED?

128x128 pixel 1.5" full colour OLED display with MicroSD card slot. [Product page]
Post Reply
Jed Hodson
Posts: 71
Joined: Wed Apr 24, 2013 5:14 am
Location: New South Wales, Australia

Strings and OLED?

Post by Jed Hodson » Thu Sep 19, 2013 7:50 am

Hi,
Currently working on project and have struck a problem.
I'd finished the code and when I verified it I got an error talking about the Strings I had used and the oled.drawString command.
here is the code;

Code: Select all

/*OLED Temprature, Humid and time
Created 19/09/2013
Jed Hodson 
*/
#include <SPI.h>
#include <SD.h>
#include <FTOLED.h>
#include <fonts/SystemFont5x7.h>
#include <fonts/Arial14.h>
#include <fonts/Arial_Black_16.h>
#include <fonts/Droid_Sans_36.h>
#include "DHT.h"
#include <Wire.h>
#include "RTClib.h"
#define DHTPIN 3
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);

RTC_DS1307 RTC;
const byte pin_cs = 7;
const byte pin_dc = 2;
const byte pin_reset = 3;

OLED oled(pin_cs, pin_dc, pin_reset);

const char *WELCOME = "Temprature,\nHumidity \nand Time\nOn OLED \nDisplay\nJed Hodson \n2013";
const char *ERRORHAP = "An ERROR has\noccured,\nplease try\nagain later!";
void setup() {
  //Start everything up
  oled.begin();
  dht.begin();
  Wire.begin();
  RTC.begin();
  //Display start up message
  oled.selectFont(Arial14);
  oled.drawString(10,101,WELCOME,GREEN,BLACK);
  //Check everythings connected
  //No RTC!
  if (! RTC.isrunning()) {
    oled.selectFont(Arial14);
    //DISPLAY ERROR MESSAGE
    oled.drawString(10,101,ERRORHAP,RED,BLACK);
  }
  // following line sets the RTC to the date & time this sketch was compiled
  RTC.adjust(DateTime(__DATE__, __TIME__));
  //And DHT22
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    oled.drawString(10,101,ERRORHAP,RED,BLACK);
  }
}



void loop() {
  oled.begin();
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    oled.drawString(10,101,ERRORHAP,RED,BLACK);
  } 
  else {
    DateTime now = RTC.now();
    //Time to make some Strings
    String dateString = "";
    dateString += String(now.day());
    dateString += "/";
    dateString += String(now.month());
    dateString += "/";
    dateString += String(now.year());
    int temp = t;
    String tempString = "";
    tempString += String(temp);
    tempString += "*C";
    int humid = h;
    String humidString = "";
    humidString += String(humid);
    humidString += "%RH";
    String timeString = "";
    timeString += String(now.hour());
    timeString += ":";
    timeString += String(now.minute());
    


    oled.selectFont(Arial_Black_16);
    oled.drawString(63,15,humidString,ROYALBLUE,BLACK);

    oled.selectFont(Arial_Black_16);
    oled.drawString(15,15,tempString,RED,BLACK);

    oled.selectFont(SystemFont5x7);
    oled.drawString(25,105,dateString,WHITE,BLACK);

    oled.selectFont(Droid_Sans_36);
    oled.drawString(10,45,timeString,GREEN,BLACK);


  } 
}
Any help appreciated
Jed

csconsulting
Posts: 70
Joined: Fri Sep 21, 2012 7:22 am

Re: Strings and OLED?

Post by csconsulting » Thu Sep 19, 2013 10:23 am

can you post the actual compiler error?

Jed Hodson
Posts: 71
Joined: Wed Apr 24, 2013 5:14 am
Location: New South Wales, Australia

Re: Strings and OLED?

Post by Jed Hodson » Thu Sep 19, 2013 10:28 am

SCREENSHOT OF ERROR in attachments
Attachments
Untitled (2).png
screenshot

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: Strings and OLED?

Post by angusgr » Sun Sep 22, 2013 11:38 pm

Hi Jed,

Good catch! The FTOLED library only had support for plain character array strings, not the Arduino String object.

I've just added support for String objects (and put a usage example into the fonts_demo example sketch) so if you re-download the FTOLED library, your code should work. Sorry about that.

You may also find the alternative OLED_TextBox approach useful if you're displaying a lot of multiline data, you can read about it on the wiki. However either approach should work just fine.

- Angus

Jed Hodson
Posts: 71
Joined: Wed Apr 24, 2013 5:14 am
Location: New South Wales, Australia

Re: Strings and OLED?

Post by Jed Hodson » Mon Sep 23, 2013 12:44 am

Thanks for that downloading new library now, I'll keep you updated on how it goes.

Jed

glenhawx
Posts: 1
Joined: Sat Feb 22, 2014 12:35 pm

Re: Strings and OLED?

Post by glenhawx » Sat Feb 22, 2014 1:01 pm

I wanted to go a step further with strings and write a library that take in an INT and returns a STRING.
Specifically, take a value in milliseconds and return a string in the format "hh:mm:ss".

If I declare it as a function at the bottom of my sketch it works:

Code: Select all

String DigClockString(long int milliseconds)
{
  String result = "";
  int seconds = milliseconds/1000;
  int minuteSec = seconds % 60;
  int minutes = seconds / 60;
  int hourMin = minutes % 60;
  int hours = minutes / 60;
  int dayHr = hours % 24;
  if (dayHr <10)
  result += "0";
  result += dayHr;
  result += ":";
  if (hourMin <10)
  result += "0";
  result += hourMin;
  result += ":";
  if (minuteSec <10)
  result += "0";
  result += minuteSec;
  return result;
}
...but I can't seem to write a library to do the same thing:

Code: Select all

/*
  DigClock.h - Library for taking millisecond values and outputting them in a string formatted hh:mm:ss.
  Created by Glen Hawksworth, Feb 22, 2014
  Released into the public domain.
*/
#ifndef DigClock_h
#define DigClock_h

#include "Arduino.h"

class DigClock
{
	public:
		DigClock();
		String ClockString(long int milliseconds);
	private:
		int _seconds;
		int _minuteSec;
		int _minutes;
		int _hourMin;
		int _hours;
		int _dayHr;
		String _result;
};

#endif

Code: Select all

/*
  DigClock.h - Library for taking millisecond values and outputting them in a string formatted hh:mm:ss.
  Created by Glen Hawksworth, Feb 22, 2014
  Released into the public domain.
*/

#include "Arduino.h"
#include "Morse.h"

DigClock::DigClock()
{
}

string ClockString(long int milliseconds)
{
  string _result = "";
  _seconds = milliseconds/1000;
  _minuteSec = _seconds % 60;
  _minutes = _seconds / 60;
  _hourMin = _minutes % 60;
  _hours = _minutes / 60;
  _dayHr = _hours % 24;
  if (_dayHr <10)
  _result += "0";
  _result += _dayHr;
  _result += ":";
  if (_hourMin <10)
  _result += "0";
  _result += _hourMin;
  _result += ":";
  if (_minuteSec <10)
  _result += "0";
  _result += _minuteSec;
  return _result;
}
I get this error on compile:

Code: Select all

Contest5.ino: In function ‘void loop()’:
Contest5.ino:92:19: error: request for member ‘ClockString’ in ‘Contest’, which is of non-class type ‘DigClock()’
Contest5.ino:121:20: error: request for member ‘ClockString’ in ‘Contest’, which is of non-class type ‘DigClock()’
I am currently figuring it is because "String" has been designed just for the OLED.
Any ideas?

PS: SystemFont5x7 seems to be the only font able to recognise spaces (" ") in strings.
Also it appears to be the only font with regular spacing. Printing a digital readout to the OLED in SystemFont5x7 doesn't require clearing. Any other font leaves behind artifacts as the string shrinks and grows.
eg. 1 is thinner than 0 so my 1 ends up looking like "1)" in any font other than SystemFont5x7.

I can use bigger fonts without artifacts but I need to clear the text with a black rectangle each cycle making the display flicker.

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: Strings and OLED?

Post by angusgr » Mon Feb 24, 2014 11:54 pm

Hi glen,
glenhawx wrote:...but I can't seem to write a library to do the same thing:
I get this error on compile:

Code: Select all

Contest5.ino: In function ‘void loop()’:
Contest5.ino:92:19: error: request for member ‘ClockString’ in ‘Contest’, which is of non-class type ‘DigClock()’
Contest5.ino:121:20: error: request for member ‘ClockString’ in ‘Contest’, which is of non-class type ‘DigClock()’
I am currently figuring it is because "String" has been designed just for the OLED.
Any ideas?
The error is related to the way you're defining the "ClockString" function. To be a member of the class DigClock it needs a definition in the .cpp file that looks more like this:

Code: Select all

String DigClock::ClockString(long milliseconds) {
//etc
}
However if you really only want this one function in there, I wouldn't declare it as part of a class at all - just copy your working function directly from the .ino file to .cpp file, then add a declaration line to the header file (on its own, not in a class) like this:

Code: Select all

String DigClockString(long int milliseconds);
... and use it the same as you're using it at the moment in your working sketch.

PS: SystemFont5x7 seems to be the only font able to recognise spaces (" ") in strings.
Also it appears to be the only font with regular spacing. Printing a digital readout to the OLED in SystemFont5x7 doesn't require clearing. Any other font leaves behind artifacts as the string shrinks and grows.
eg. 1 is thinner than 0 so my 1 ends up looking like "1)" in any font other than SystemFont5x7.

I can use bigger fonts without artifacts but I need to clear the text with a black rectangle each cycle making the display flicker.
Yes, SystemFont5x7 is the only monospaced font we supply.

The recommended way to display variable-width text messages is to use OLED_TextBox, end the line of output with a newline (ie by using the println() function), and then call reset() on the textbox when you go to redraw the message. This technique is described here with a quick sample:

https://github.com/freetronics/FTOLED/w ... -and-reset

Printing the newline causes the textbox to erase the rest of the box at the end of the line, and the reset() causes it to go back to the beginning of the box without erasing anything - avoiding the flicker.

If you want a simpler solution and you have a bit of screen real estate to play with, a quick hack is to just pad the string you pass to ::drawString() with one or two spaces at the end. This will overwrite any stray pixels.

Please let us know how you get on.

- Angus

Post Reply