ST7565 LCD Help -- memory overflow or something?

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
jbishop129
 
Posts: 6
Joined: Wed Jan 26, 2011 4:40 pm

ST7565 LCD Help -- memory overflow or something?

Post by jbishop129 »

Hi all (and a special "we're not worthy" bow to Lady Ada!)

I recently purchased a ST7565 LCD, to give me more space to output than my HD44780 4x20 LCD, and am having trouble getting it to play nice. Problem is I'm not a dev by trade, so my code is bad enough to make even the kludgiest code snippeter shivver.
My setup is a pair of ATmega328's talking to each other over the I2C bus.

Arduino 1 has the ST7565 attached, as well as an array of Dallas one-wire temp sensors, and a DHT11 temp/humidity sensor.

Arduino 2 has an ethernet shield, and is the Master on the Wire bus, pulling data from Arduino 1 every 120 seconds, and uploading to a MySQL database via PHP. Arduino 2 works just fine.

In Arduino 1, I am having to do some very very ugly shifting around between ints, strings, and chars, based on how certain devices are read, and how data must be passed. For example, my temp sensors can only be read as ints (or floats). filling an array to send over Wire.send cannot accept ints, so I am filling them to a byte array for sending. then, the ST7565 cannot print an int or byte, only a char, so I am using toCharArray to convert again. So far so good; believe it or not it actually works, and data is passed around as it should.

The problem (Finally...) is that I am finding the display of the ST7565 to be extremely unreliable in my below code. It seems to be more reliable the less I try to display on it. I have to hit the reset on the Arduino several times to get it to come up; sometimes I get nothing, sometimes I get garbage on the screen, and sometimes it works (after several resets). This leads me to believe my code is unspeakably flawed.

Hopefully that helps you to understand how I got in to this despicable code below!

Code: Select all

#include <dht11.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "ST7565.h"

OneWire oneWire(2); // One Wire bus digital pin #
DallasTemperature sensors(&oneWire);
DeviceAddress bdrTemp = { 0x28, 0xD9, 0x2E, 0x59, 0x03, 0x00, 0x00, 0xB9 };
DeviceAddress serverTemp = { 0x28, 0xE6, 0x58, 0x59, 0x03, 0x00, 0x00, 0x81 };
DeviceAddress lrTemp = { 0x28, 0x98, 0x39, 0x59, 0x03, 0x00, 0x00, 0xD6 };
DeviceAddress outsideTemp1 = { 0x28, 0x78, 0x43, 0x59, 0x03, 0x00, 0x00, 0x2F };

int backlight;
int myData[6];
int humidity;
int temp1;
int tempF1;
int tempF2;
int tempF3;
int tempF4;

String tempString1;
String tempString2;
String tempString3;
String tempString4;
String tempString5;
String humString1;
 
char tempChar1[3];
char tempChar2[3];
char tempChar3[3];
char tempChar4[3];
char tempChar5[3];
char humChar1[3];

dht11 DHT11;
ST7565 glcd(9,8,7,6,5);

void setup()
{
  glcd.begin (0x18);
  glcd.clear();
//  Serial.begin(9600);
  Wire.begin(2); // ID the Slave as node 2
  sensors.begin();
  sensors.setResolution(bdrTemp, 10);
  sensors.setResolution(serverTemp, 10);
  sensors.setResolution(outsideTemp1, 10);
  sensors.setResolution(lrTemp, 10);
  
  Wire.onRequest(requestEvent);
  
  pinMode (3, OUTPUT);
  analogWrite(3, 100);
    
  pinMode (14, OUTPUT); // analog pin 0 = +5v for DHT11 sensor
  pinMode (17, OUTPUT); // analog pin 3 = GND for DHT11 sensor
    
  digitalWrite (14, HIGH); // set pin to 5v
  digitalWrite (17, LOW); //  set pin to GND
}

void loop()
{
  int chk = DHT11.read(15);
  backlight = analogRead(2);
  analogWrite (3, backlight / 4);
  humidity = (DHT11.humidity);
  temp1 = (1.8 * (DHT11.temperature) + 32);
  sensors.requestTemperatures();
  tempF1 = sensors.getTempF(bdrTemp);
  tempF2 = sensors.getTempF(serverTemp);
  tempF3 = sensors.getTempF(outsideTemp1);
  tempF4 = sensors.getTempF(lrTemp);
  myData[0] = temp1;
  myData[1] = humidity;
  myData[2] = tempF1;  
  myData[3] = tempF2;
  myData[4] = tempF3;
  myData[5] = tempF4;

  tempString1 = myData[0];
  humString1 = myData[1];
  tempString2 = myData[2];
  tempString3 = myData[3];
  tempString4 = myData[4];
  tempString5 = myData[5];  
  
  tempString1.toCharArray(tempChar1,3);
  tempString2.toCharArray(tempChar2,3);
  tempString3.toCharArray(tempChar3,3);
  tempString4.toCharArray(tempChar4,3);
  tempString5.toCharArray(tempChar5,3);
  
  humString1.toCharArray(humChar1,3);
  writeLCD();
  delay(1000);
}


void requestEvent()
{
  Wire.send((byte *) myData, sizeof myData);
}

void writeLCD()
{
  glcd.clear();
  glcd.drawstring(0,0,"Temperature Gauge");
  glcd.drawstring(0,1,"Inside   |  Outside");
//  glcd.drawstring(12,2,"F Bedrm|   F ");
//  glcd.drawstring(12,3,"% RH   |");
  glcd.drawstring(0,4,"bdrtemp   F |   F");
  glcd.drawstring(0,5,"svrtemp:");
  glcd.drawstring(0,6,"LRtemp:");
  glcd.display();
 
  glcd.drawstring(0,2,tempChar1); 
  glcd.drawstring(0,3,humChar1);
//  glcd.drawstring(47,4,tempChar2);  //Bedroom
//  glcd.drawstring(47,5,tempChar3); // Server
//  glcd.drawstring(66,2,tempChar4); // Outside
//  glcd.drawstring(47,6,tempChar5);
//  glcd.drawline(0, 31, 127, 31, BLACK);
  glcd.display();
//  delay(1000);
  
}

User avatar
zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: ST7565 LCD Help -- memory overflow or something?

Post by zener »

The best advice I have is comment out parts of the code until one of these two things happens:

It works, or you have the smallest amount of code that still has the problem.

Then post that code. That will probably help someone figure out what is going on, and you might figure it out yourself. On the other hand, someone smarter than me might know what is happening already! Hopefully they will come along soon, but in the mean time you can try my idea.

User avatar
jbishop129
 
Posts: 6
Joined: Wed Jan 26, 2011 4:40 pm

Re: ST7565 LCD Help -- memory overflow or something?

Post by jbishop129 »

Thanks Zener -- That's what I have been doing up to this point, and since my results are sporadic, I know I am dealing with fundamentally flawed coding methods (my own fault). Since the results are not completely consistent (example: I can reduce the glcd. output down, and it gets "more stable", not completely stable), this leads me to believe I am overrunning the 'mega328's memory.

User avatar
nealn
 
Posts: 10
Joined: Sat Oct 08, 2011 7:53 pm

Re: ST7565 LCD Help -- memory overflow or something?

Post by nealn »

A couple of things come to mind. First, there is a free memory utility on the arduino playground: http://www.arduino.cc/playground/Code/AvailableMemory Scrolling down to the second half, it will give you the MemoryFree.h and cpp source codes and an example implementation. It's pretty useful. I think there is also an implementation of something like this in the SDfat library. I think that will assuage your concern about using up the ram. That display costs you have of your ram from the get go. I have one too, and I am just going to devise "backpack" based on the ATMEGA328.

The second thing is, one of my many concurrent projects involves breaking down floats into byte arrays and honestly, I share it because you had mentioned all the recasting that you had done. There is a function called union.

It looks like this...

Code: Select all

union test {
float humiditysensor1;
byte humiditysensor[4];
int humsensor1;}
test;
Now you can assign something to this struc and it will recast different variables, but only cost you the memory of the largest member, in this case it is the float or the byte array..

Code: Select all

test.humidtysensor1 = sensorval; //into the union, where the sensorval is a floating point number
Serial.println(test.humsesnsor[0], HEX);  // out of the union, but the least significant byte of the floating variable
This union thing changed the way I code fundamentally.

One other thing that comes to mind is that I had to modify my I2C library because there is a flaw in it where you can get caught in and endless loop when the slave stops responding, or doesn't respond(or something like that) you can see the effects if you short A4 and A5 when the you are using the wire library. In my configuration I have a GPS talking to a ATMEGA328 and is an I2C slave to an ATMEGA1284P (both using arduino and the wire library). When I first started the whole thing would act funny, lock up every now and then. I thought I was chasing some sort of memory thing too. I can't find the link to the arduino forum where I found the fix and I have to run to work, but it is out there, and it fixed my issue. I recall it just added a timer to prevent the I2c from waiting for forever. I will look for it later.

Anyways good luck,
Neal

User avatar
jbishop129
 
Posts: 6
Joined: Wed Jan 26, 2011 4:40 pm

Re: ST7565 LCD Help -- memory overflow or something?

Post by jbishop129 »

Thanks Neal, this helps! I found when I turned down how frequently the Master was doing a Wire.request, this seems to help stabilize things a bit. Still not perfect, and if you come across that info on setting up a timeout for Wire, that may ultimately solve the problem.

My other question regarding the AdaFruit ST7565 is, mine is the "negative" LCD, in that the background pixels are black (on), and the text is white (off). I saw in the library how most of the functions have a BLACK / WHITE option, but not the glcd.drawstring. If it were possible, it would be handy to invert the LCD to a normal white background, black pixels in scenarios where I do not need the backlight. Is this possible?

User avatar
nealn
 
Posts: 10
Joined: Sat Oct 08, 2011 7:53 pm

Re: ST7565 LCD Help -- memory overflow or something?

Post by nealn »

Here is the link to the arduino forum topic. http://www.arduino.cc/cgi-bin/yabb2/YaB ... 1283887406

At the bottom are links to a user who changed some things in the wire library. If you replace the files in the ~/arduino-0022 (or whatever version)/libraries/Wire/utility with links at the bottom and recompile your sketch it might just fix your issue.

As far as inverting your display, I haven't gotten too deep into it, I wired it and made sure everything worked and put it up. Too many irons in the hobby fire I suppose. I wanted to contrive a 3.3 V ATMEGA328 backpack first so I can take the burden off my main unit. Or just have a stand alone display unit hooked up to an xbee, that is self contained so I get the status of my network just about anywhere in the house. Anyways, I think that you may be able to change the behavior of the way the library handles the print string since (I think) you are updating the whole or part of the bitmap for the device when you make changes. It is just a matter of inverting the bits you want printed (easy to say right?), but there has got to be a SW way of doing that. Even if it is non-trivial, again due to the fact that you are tasking the ucontroller with the job of buffering the contents of your display.

Regards,
Neal

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”