Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - DataL

Pages: [1]
1
I have been doing well to solve my own problems but this one has me stumped.

I have developed my code so far successfully using SD.h for the SD card and Wire.h for the RTC and display until I decided to make the display work over SPI instead.
Of all the SPI code examples I have found for the display the only one I have made work is the big-banged one in my sketch, however if SD.h or SPI.h are included in the code the screen doesn't do anything - a previous working sketch's output will remain frozen on the screen after upload. Remove SPI/SD.h and the display works again.
I have taken a look over SD.h and SD.cpp, as well as the many others included in that library but nothing jumps out at me and it is going over my head.

Code: [Select]
/* Datalogger v0.93.3 for Arduino Mega2560, NHD-0420CW-Ax3, DS3231 and SD card - 8% progmem; 19% SRAM
*
* The circuit:
* OLED pin 7 (SCK)          to Arduino pin 52 (SCK)
* OLED pin 8 (MOSI)         to Arduino pin 51 (MOSI)
* OLED pin 9 (MISO)         to Arduino pin 50 (MISO)
* OLED pin 15 (CS)          to Arduino pin 29 (CS)
* OLED pin 16 (/RES)        to Arduino pin 36 // Reset or VDD 5V (or to Arduino pin D13, to control reset by sw)
* MISO to ICSP pin 1 / 50
* MOSI to ICSP pin 4 / 51
* CLK to ICSP pin 3 / 52
* SDcard CS to pin 31
* Arduino Pin 20 to I2C SDA w/ 10K pull-up
* Arduino Pin 21 to I2C SCL w/ 10K pull-up

* Original example created by Newhaven Display International Inc.
* Modified and adapted 15 Mar 2015 by Pasquale D'Antini
* Modified 19 May 2015 by Pasquale D'Antini
* Further modified and added to by DataL
* This example code is in the public domain.
*/

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#define DS3231_I2C_ADDRESS 0x68

int count;        // Process loop couter

//----- For the inputs:
//Analog
#define muxPin A0    // sensor mux input
#define otsPin A2    // sensor OTS input
#define opsPin A4    // sensor OPS input
#define iatPin A6    // sensor IAT input
int svpValue;   // sensor supply voltage value
int svnValue;   // sensor supply earth value
int mpsValue;   // sensor MPS value
int otsValue;   // sensor OTS value
int opsValue;   // sensor OPS value
int iatValue;   // sensor IAT value
int otsTemp;    // Engine Oil Temperature in Celcius
int opsPres;    // Engine Oil Pressure
int iatTemp;    // Inlet Air Temperature
int mpsPres;    // Manifold Pressure
//Digital
#define muxaPin 34     // multiplexer control A
#define muxbPin 36     // multiplexer control B
#define muxcPin 38     // multiplexer control C
#define ignPin 02      // voltage IGN input
#define dosPin 04      // voltage DOS input
int ignValue;          // binary Ignition On value
int dosValue;          // binary Door Open Switch value

//----- For the sensor calculations:
int svpVolt;     // sensor supply voltage
int svnVolt;     // sensor earth voltage
int mpsVolt;     // sensor MPS voltage
int otsVolt;     // sensor OTS voltage
int opsVolt;     // sensor OPS voltage
int iatVolt;     // sensor IAT voltage
int otsRes;      // sensor OTS resistance
double iatRes;     // sensor IAT resistance
double otsTempK;   // Engine Oil Temperature in Kelvin
double iatTempK;   // Inlet Air Temperature in Kelvin
//Sensor averages
int i = 0;
long svpAve;
long svnAve;
long svdAve;
long mpsAve;
long otsAve;
long opsAve;
long iatAve;

//-----For the SPI Comms
#define SCLK 52
#define MOSI 51
#define MISO 50
#define sdCS 31         // SD card SPI Chip Select pin
#define lcdCS 29        // LCD screen SPI Chip Select pin

//----- For the SD card:
File mainLog;
//File faultLog;

//----- For the LCD screen:
//Setup
#define COLUMN_N 20     // Number of display columns
#define ROW_N 4         // Number of display rows
#define lcdRes 44       // Reset LCD screen when LOW
byte new_line[4] = {0x80, 0xA0, 0xC0, 0xE0};   // Maybe 0x01?? // DDRAM address for each line of the display (128, 160, 192, 224)
byte rows = 0x08;                              // Display mode: 2/4 lines; default (0x08 = 8)
byte r = 0;                                    // Row index
byte c = 0;                                    // Column index
//Welcome arrays
const char welcome0[21] PROGMEM = "X     Starting     X";
const char welcome1[21] PROGMEM = "     Datalogger     ";
const char welcome2[21] PROGMEM = "       v0.93        ";
const char welcome3[21] PROGMEM = "X                  X";
const char* const welcometable[] PROGMEM = {welcome0, welcome1, welcome2, welcome3};
char welcome[21];
//Output arrays
char buffer0[21];
char buffer1[21];
char buffer2[21];
char buffer3[21];
char buffer4[9];
char buffer5[9];

//----- For the power control:
#define lcdReg 46      // LCD display power supply transistor
#define perReg 03      // Peripheral power supply transistor
#define senReg 32      // Sensor power supply transistor

//----- For the date and time:
char weekDayVerb[10] = "AnyDayYet";
const char monday[7] PROGMEM = "Monday";
const char tuesday[8] PROGMEM = "Tuesday";
const char wednesday[10] PROGMEM = "Wednesday";
const char thursday[9] PROGMEM = "Thursday";
const char friday[7] PROGMEM = "Friday";
const char saturday[9] PROGMEM = "Saturday";
const char sunday[7] PROGMEM = "Sunday";
char monthVerb[4] = "AnyMonth";
const char jan PROGMEM = "Jan";
const char feb PROGMEM = "Feb";
const char mar PROGMEM = "Mar";
const char apr PROGMEM = "Apr";
const char may PROGMEM = "May";
const char jun PROGMEM = "Jun";
const char jul PROGMEM = "Jul";
const char aug PROGMEM = "Aug";
const char sep PROGMEM = "Sep";
const char oct PROGMEM = "Oct";
const char nov PROGMEM = "Nov";
const char dec PROGMEM = "Dec";

//----- For the refresh rate:
unsigned long previousMillis = 0;        // will store last time logs were updated
const long interval = 1000;              // interval at which to update logs (milliseconds)


void setup(void)  {
  count=0;
  i=0;
 
  pinMode(SCLK, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(MISO, INPUT);
  pinMode(sdCS, OUTPUT);
  pinMode(lcdCS, OUTPUT);
  pinMode(lcdRes, OUTPUT);
 
  pinMode(lcdReg, OUTPUT);
  pinMode(perReg, OUTPUT);
  pinMode(senReg, OUTPUT);
  pinMode(muxPin, INPUT);
  pinMode(otsPin, INPUT);
  pinMode(opsPin, INPUT);
  pinMode(iatPin, INPUT);
  pinMode(muxaPin, OUTPUT);
  pinMode(muxbPin, OUTPUT);
  pinMode(muxcPin, OUTPUT);
  pinMode(ignPin, INPUT);
  pinMode(dosPin, INPUT);
 
  digitalWrite(SCLK, HIGH);
  digitalWrite(MOSI, LOW);
  digitalWrite(sdCS, HIGH);
  digitalWrite(lcdCS, HIGH);
  digitalWrite(lcdRes, HIGH);       // Disable LCD reset
 
  digitalWrite(lcdReg, HIGH);       // Enable transistor
  digitalWrite(perReg, HIGH);       // Enable transistor
  digitalWrite(senReg, HIGH);       // Enable transistor
  delay(1);
 
  Wire.begin();                     // Initiate the Wire library and join the I2C bus as a master
//  settime();                      // Use when need to reset datetime with uploading
  Serial.begin(9600);               // Initialize serial communication
  while (!Serial){;}                // Wait for serial port to connect
 
  LCDinit();
  SDinit();
  Welcome();
  delay(2500);
}


void loop(void)  {                     // MAIN PROGRAM   
  if (!SD.exists("/MainLogs/"))    {
    SDinit();
  }
  inputs();                            // Read values on input pins
  calculate();                         // Convert values into info
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    buffers();                         // Compose output text buffers.
    LCDdisplay();                      // Output buffers to screen
    seriallog();                       // Output to serial
    SDlogmain();                       // Output to SD card
    count = count + 1;
    i = 0;                             // Reset mean count
    svpAve = 0;                        // Reset means
    svnAve = 0;
    mpsAve = 0;
    otsAve = 0;
    opsAve = 0;
    iatAve = 0;
    previousMillis = currentMillis;
  }
}


void Welcome()  {
  Serial.print(F("\nStarting Datalogger v0.93"));
  Serial.print(F("\nCount: "));
  Serial.print(count);
  r = 0;                              // Row index
  c = 0;                              // Column index
  command(0x01);                      // Clears display (and cursor home)
  delay(2);                           // After a clear display, a minimum pause of 1-2 ms is required
  for (int r = 0; r < 4; r++)  {
    strcpy_P(welcome, (char*)pgm_read_word(&(welcometable[r])));
    command(new_line[r]);            // Moves the cursor to the first column of line [i]
    for (c=0; c<COLUMN_N; c++)  {    // One character at a time,
      data(welcome[c]);              // Displays the corresponding string
    }
  }
}


void LCDdisplay()  {
   byte r = 0;                         // Row index
   byte c = 0;                         // Column index
   
   r = 0;                              // Choose line 0
      command(new_line[r]);            // Moves the cursor to the first column of that line
      for (c=0; c<COLUMN_N; c++)  {    // One character at a time,
        data(buffer0[c]);  }        // Displays the correspondig string
   r = 1;                              // Choose line 1
      command(new_line[r]);            // Moves the cursor to the first column of that line
      for (c=0; c<COLUMN_N; c++)  {    // One character at a time,
         data(buffer1[c]);  }       // Displays the correspondig string
   r = 2;                              // Choose line 2
      command(new_line[r]);            // Moves the cursor to the first column of that line
      for (c=0; c<COLUMN_N; c++)  {    // One character at a time,
         data(buffer2[c]);  }       // Displays the correspondig string
   r = 3;                              // Choose line 3
      command(new_line[r]);            // Moves the cursor to the first column of that line
      for (c=0; c<COLUMN_N; c++)  {    // One character at a time,
         data(buffer3[c]);  }       // Displays the corresponding string
}


//-----For the SD card:

void SDinit(void) {
 
  Serial.print(F("\n\nInitializing SD card...  "));
  if (SD.begin(sdCS))   {
    Serial.print(F("SD card initialised."));
    Serial.print(F("\n"));   }
  else    {
    Serial.print(F("SD card inaccessible."));
    Serial.print(F("\n"));
    return;   }

  if (SD.exists("/MainLogs/"))    {                                                     // *Directory name
    Serial.print(F("\n/MainLogs/ Directory exists"));   }                               // *Directory name
  else    {
    Serial.print(F("\n/MainLogs/ directory doesn't exist. Creating directory... "));    // *Directory name
    SD.mkdir("/MainLogs/");                                                             // *Directory name
    if (!SD.exists("/MainLogs/"))   {                                                   // *Directory name
      Serial.print(F("\nDirectory /MainLogs/ failed to be created"));                   // *Directory name
    return;   }
    else  {
      Serial.print(F("\nDirectory /MainLogs/ has been created"));    }   }              // *Directory name
/*    // Save the following for a later date //
  if (SD.exists("/FaultLog/"))    {                                                    // *Directory name
    Serial.print(F("\n/FaultLog/ Directory exists"));                                  // *Directory name
    Serial.print(F("\n\n"));   }
  else    {
    Serial.print(F("\n/FaultLog/ Directory doesn't exist. Creating directory... "));   // *Directory name
    SD.mkdir("/FaultLog/");                                                            // *Directory name
    if (!SD.exists("/FaultLog/"))   {                                                  // *Directory name
      Serial.print(F("\nDirectory /FaultLog/ failed to be created"));                  // *Directory name
      Serial.print(F("\n\n"));
    return;   }
    else  {
      Serial.print(F("\nDirectory /FaultLog/ has been created"));                      // *Directory name
      Serial.print(F("\n\n"));    }
*/
}


void SDlogmain(void)  {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);  // retrieve data from DS3231
 
  char filepath[9];
  snprintf (filepath, 9, "%d%d%d.csv", dayOfMonth, monthVerb, year);
  Serial.print("filepath = ");
  Serial.println(dayOfMonth);

  mainLog = SD.open("filepath", FILE_WRITE);
  if  (!mainLog)   {
    Serial.print(F("\nSDlogmain failed to open file "));
    Serial.print("filepath");
    digitalWrite(42, LOW);    }
  else  {
    Serial.print(F("\nSDlogmain successfully opened file "));
    Serial.print("filepath");
    digitalWrite(42, HIGH);   }
 
  mainLog.println("Testing, writing, filling...");

  mainLog.close();
  if (!mainLog)   {
    Serial.print(F("\nSDlogmain successfully closed file "));
    Serial.println("filepath");
    Serial.println();   }
  else  {
    Serial.print(F("\nSDlogmain failed to close file "));
    Serial.println("filepath");
    Serial.println();   }

  mainLog = SD.open("filepath");
  Serial.print("Text file contains: ");
  while (mainLog.available()) {
  Serial.write(mainLog.read());   }
  Serial.print("\n\n");
  mainLog.close();
 
}

//-----For The RTC Module:

//-----For the LCD screen:

void command(byte c)   {              // PREPARES THE TRANSMISSION OF A COMMAND BYTE
  byte i = 0;                         // Bit index
  for(i=0; i<5; i++)  {
    digitalWrite(MOSI, HIGH);
    clockCycle();
  }
  for(i=0; i<3; i++)  {
    digitalWrite(MOSI, LOW);
    clockCycle();
  }
  send_byte(c);                       // Transmits the byte
}


void data(byte d)    {                // PREPARES THE TRANSMISSION OF A BYTE OF DATA
  byte i = 0;                         // Bit index
  for(i=0; i<5; i++)  {
    digitalWrite(MOSI, HIGH);
    clockCycle();
  }
  digitalWrite(MOSI, LOW);
  clockCycle();
  digitalWrite(MOSI, HIGH);
  clockCycle();
  digitalWrite(MOSI, LOW);
  clockCycle();
  send_byte(d);                       // Transmits the byte
}


void send_byte(byte tx_b)  {          // SEND TO THE DISPLAY THE BYTE IN tx_b
  byte i = 0;                         // Bit index
  for(i=0; i<4; i++)  {
    if((tx_b & 0x01) == 1)  {
      digitalWrite(MOSI, HIGH);
    }
    else  {
      digitalWrite(MOSI, LOW);
    }
    clockCycle();
    tx_b = tx_b >> 1;
  }
  for(i=0; i<4; i++)  {
    digitalWrite(MOSI, LOW);
    clockCycle();
  }
  for(i=0; i<4; i++)  {
    if((tx_b & 0x1) == 0x1)  {         // <------- Change (?)
      digitalWrite(MOSI, HIGH);
    }
    else  {
      digitalWrite(MOSI, LOW);
    }
    clockCycle();
    tx_b = tx_b >> 1;
  }
  for(i=0; i<4; i++)  {
    digitalWrite(MOSI, LOW);
    clockCycle();
  }
}


void clockCycle(void)  {          // EXECUTE THE CLOCK SIGNAL CYCLE
  digitalWrite(lcdCS, LOW);          // Sets LOW the /CS line of the display (optional, can be always low)
  delayMicroseconds(1);           // Waits 1 us (required for timing purpose)
 
  digitalWrite(SCLK, LOW);        // Sets LOW the SCLK line of the display
  delayMicroseconds(1);           // Waits 1 us (required for timing purpose)
 
  digitalWrite(SCLK, HIGH);       // Sets HIGH the SCLK line of the display
  delayMicroseconds(1);           // Waits 1 us (required for timing purpose)
 
  digitalWrite(lcdCS, HIGH);         // Sets HIGH the /CS line of the display (optional, can be always low)
  delayMicroseconds(1);           // Waits 1 us (required for timing purpose)
}


void LCDinit()    {
  command(0x22 | rows);      // Function set: extended command set (RE=1), lines # (0x22 = 34)
    command(0x71);           // Function selection A: (0x71 = 113)
      data(0x5C);            // Enable internal Vdd regulator at 5V I/O mode (default) (0x00 for disable: 2.8V I/O) (0x5C = 92)
  command(0x20 | rows);      // Function set: fundamental command set (RE=0) (exit from extended command set), lines # (0x20 = 32)

  command(0x08);             // Display ON/OFF control: display off, cursor off, blink off (default values) (0x08 = 8)

  command(0x22 | rows);      // Function set: extended command set (RE=1), lines # (0x22 = 34)
    command(0x79);           // OLED characterization: OLED command set enabled (SD=1) (0x79 = 121)
      command(0xD5);         // Set display clock divide ratio/oscillator frequency: (0xD5 = 213)
      command(0x70);         // Divide ratio=1, frequency=7 (default values) (0x70 = 112)
    command(0x78);           // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set) (0x78 = 120)
     
      command(0x09);         // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 3/4 lines (0x09 = 9)
      command(0x06);         // Entry Mode set - COM/SEG direction: COM0->COM31, SEG99->SEG0 (BDC=1, BDS=0) (0x06 = 6)
      command(0x72);         // Function selection B: (0x72 = 114)
        data(0x0A);          // ROM/CGRAM selection: ROM C, CGROM=250, CGRAM=6 (ROM=10, OPR=10) (0x0A = 10)
        command(0x79);       // OLED characterization: OLED command set enabled (SD=1) (0x79 = 121)
          command(0xDA);     // Set SEG pins hardware configuration: (0xDA = 218)
            command(0x10);   // Alternative odd/even SEG pin, disable SEG left/right remap (default values) (0x10 = 16)
          command(0xDC);     // Function selection C: (0xDC = 220)
            command(0x00);   // Internal VSL, GPIO input disable (0x00 = 0)
            command(0x81);   // Set contrast control: (0x81 = 129)
              command(0x00); // Contrast=127 (default value) (0x7F = 127)
            command(0xD9);   // Set phase length: (0xD9 = 217)
              command(0xF1); // Phase2=15, phase1=1 (default: 0x78) (0x78 = 120)
            command(0xDB);   // Set VCOMH deselect level: (0xDB = 219)
              command(0x40); // VCOMH deselect level=1 x Vcc (default: 0x20=0,77 x Vcc) (0x40 = 64)
        command(0x78);       // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set) (0x78 = 120)
      command(0x20 | rows);  // Function set: fundamental command set (RE=0) (exit from extended command set), lines # (0x20 = 32)

  command(0x01);             // Clear display (0x01 = 1)
    delay(2);                // After a clear display, a minimum pause of 1-2 ms is required
  command(0x80);             // Set DDRAM addlcdRess 0x00 in addlcdRess counter (cursor home) (default value) (0x80 = 128)
  command(0x0C);             // Display ON/OFF control: display ON, cursor off, blink off (0x0C = 12)
    delay(250);              // Waits 250 ms for stabilization purpose after display on
}

Pages: [1]