Analysis for Arduino schematic for SD card, flow sensor, Oled, Servo and GPS

I tried to give you an example how to fix your problem. The following code is more for a learning book:

void OledShowString(const __FlashStringHelper *ifsh, int Xpos, int Ypos)
{
  const char PROGMEM *p = (const char PROGMEM *)ifsh;
  size_t n = 0;
  do {
    unsigned char c = pgm_read_byte(p++);
    n++;
  } while (c != 0);
  p = (const char PROGMEM *)ifsh;
  char pOledChars[n];
  n = 0;
  do {
    pOledChars[n] = pgm_read_byte(p++);
  } while (pOledChars[n++] != 0);
  oled.drawString(Xpos, Ypos, pOledChars);
}

while(1) loops are not that unusual in C programming though because you're not always able to check a condition at the beginning or end of a loop. If you have to structure your code to avoid that you're making your code unnecessarily complex and harder to understand. There are equivalent examples for the use of the "goto" statement, which is also a no-no in other languages (most don't have it) but there are cases where you can code much more readable and understandable by using it.

Hello,
Were you able to get your SD card working with this OLED? I have not had any luck, even after making the modifications to use hardware SPI (http://arduino.cc/forum/index.php/topic,108542), and ensuring that each device was using a different pin for CS. The OLED seems to go garbled if I leave in the line:

SdFile root;
SdFile file;

I've put in the time looking for a solution, thought I'd throw it out there. I'm using the adafruit datalogger shield, BTW.
Thanks.

Sounds like a memory problem to me. The SD library uses a 512 byte buffer (one block), so on an UNO it's using a quarter of the available RAM. Show us your code and post the details about your hardware, maybe then we can tell you more.

Alright,

I'm using an OSEPP UNO board with the Adafruit datalogger shield attached. I've removed much of the code to try to reduce the memory required. I'm using the OLED ssd1306 128x64 breakout board. I started with the example code from adafruit (File>examples>Adafruit_1306SSD>1306SSD_128x64_spi). I did the modifications for hardware driven SPI using the following pin assignments:

Reset 3 --> 7 (was 13)
CS 5 --> 9 (was 12)
D/C 9 --> 8 (was 11)
CLK 11 --> 13 (was 10)
DAT/MOSI 14 --> 11 (was 9)

This is from the previous post but I changed CS to from 10 to 9 because I believe the datalogger shield uses 10. Here's the front end of the code.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>


#include <SdFat.h>
#include <SdFatUtil.h> // use PgmPrint
#include <Wire.h>
#include "RTClib.h"
//#include <math.h>

RTC_DS1307 RTC; // define the Real Time Clock object

// The objects to talk to the SD card
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define OLED_DC 8
#define OLED_CS 9
#define OLED_CLK 13
#define OLED_MOSI 11
#define OLED_RESET 7
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static unsigned char __attribute__ ((progmem)) logo16_glcd_bmp[]={
0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0xf8, 0xbe, 0x9f, 0xff, 0xf8, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 
0x20, 0x3c, 0x3f, 0x3f, 0x1f, 0x19, 0x1f, 0x7b, 0xfb, 0xfe, 0xfe, 0x07, 0x07, 0x07, 0x03, 0x00, };

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup()   {                
  Serial.begin(9600);
  
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC);
  // init done
  
  display.display(); // show splashscreen
  delay(2000);
  display.clearDisplay();   // clears the screen and buffer
   
}

The rest of the code is just the example code unmodified. If I upload this the uno, it displays the adafruit industry logo but it's garbled. If I comment out the two sdFile lines, it is fine.

Thanks for your help

I did the modifications for hardware driven SPI using the following pin assignments:

Unfortunately changing the pin assignments does not activate the hardware driven SPI. The library does not include support for that. It has support for hardware driven I2C but not SPI.

// The objects to talk to the SD card
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file

This code uses the hardware SPI including the SS pin 10 although your SD card probably is on pin 4 and, even much more important, you told the adafruit library that it may use pin 10. The conflict is imminent.

Thanks for your response. I did follow the instructions here:(http://arduino.cc/forum/index.php/topic,108542) which I believe modifies the oled libraries to use hardware SPI. It was certainly faster at drawing the example graphics after the modifications.
WRT to the SD card CS pin, this site:Data-Logger Shield for Arduino shows the SD card using Pin10. So I think I've done it right, but I might be wrong.
Thanks again for you help.

So you have applied Nick's patch? Please supply a link to such modifications and to all libraries you downloaded so we don't have to search and find the wrong code in the end.

Try defining your SD card stuff not globally:

// The objects to talk to the SD card
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

but in a routine where they are used (at least the SdFile variables). Then correctly initialize the SD library in setup() before you use the SdFile variables. You have to be sure all the devices on the SPI uses it not concurrently, meaning their CS (or SS) pin is not LOW at the same time.

Well I tried this, to no avail.

I also went back to the software SPI and switched the pins to avoid those used by hardware SPI and the adafruit datalogger shield, to no avail.

Has anyone actually gotten the adafruit datalogger shield to work with the OLED 1306 128x64 breakout board?

Hello again,

Well, I have the Adafruit Datalogger shield working with the SSD1306, but I had to make a few changes. Besides the changes above for hardware SPI, I'm using only the 128x32 libraries and code because using the 128x64 library used up more than 2kB of SRAM on the UNO. I think I'll need to upgrade to the MEGA to work more freely with the two devices, especially when using String objects.

I'm using the FreeRam function and things crash once this gets down below 182 bytes.

I understand the OLED Buffer uses 512 bytes of SRAM for the 128x32 OLED, and 1024 bytes for the 128x64. It would be nice to free up this RAM. Is there any way to move this buffer into progMem? Any other SRAM saving techniques? Do I have to worry about libraries like WIRE being included twice?

Thanks again.

Is there any way to move this buffer into progMem?

No.

Do I have to worry about libraries like WIRE being included twice?

No, the compiler is taking care for that stuff.

Any other SRAM saving techniques?

Show us your real code and we try to help you.
With an UNO (2kB of RAM) and the SD library (512 Bytes buffer) as well as the OLED library (1024 Bytes buffer) you just have 512 Bytes for all the rest including the library variables. I'd try to eliminate all unnecessary variables from your code as well as from the libraries used. You have to take care for every byte, so don't use an int when an uint8_t has enough number range. Don't use the String class at all, avoid character array if ever possible.

Hi satoer.

Just wanted to say that this is quite an amazing project you have here with many applications.

I would love to have a look at your code at some stage, as this is quite similar to a project I want to do when my knowledge is a bit better!

Keep up the good work!

Great project! I'm doing something similar using a global sat gps and serial OLED.

I plan on adding fuel flow data later and am curious where you purchased your fuel flow sensor. I've looked at the Flowscan but it requires 12v. I'd rather stick with 5V from my Arduino Mega 2560.

Thanks!