Mega 2560 + ADXL335 + SD Card module + 2 x Servo 360 + Keypad 4x4 membrane

The aim of my project is to turn on my 2 servos for 5 seconds in car with keypad (eg. clicking ‘1’ or ‘2’) and a small delay e.g. 3 seconds until it starts driving. Then it will brake on its own. After clicking keypad I also want to write acceleration on microSD card.
I have this code for SD module, Grove ADXL335 analog accelerometer and servo object and it can measure acceleration, print it in the serial monitor and SD card but I was not able to use keypad properly (remove code from loop). Could you advise me something that would work?

#include <Keypad.h> //biblioteka od klawiatury


const byte ROWS = 4; // ile wierszy
const byte COLS = 4; //ile kolumn


byte rowPins[ROWS] = {2, 3, 4, 5}; //piny wierszy - lewy skrajny przewod podlaczony do pinu nr 2
byte colPins[COLS] = {6, 7, 8, 9}; //piny kolumn - 5 przewod od lewej strony podlaczony do pinu nr 6


char keys[ROWS][COLS] = { //mapowanie klawiatury
 {'1', '2', '3', 'A'},
 {'4', '5', '6', 'B'},
 {'7', '8', '9', 'C'},
 {'*', '0', '#', 'D'}
};


Keypad klawiatura = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); //inicjalizacja klawiatury


String receivedData = "";


#include <Servo.h>


Servo servo1;
Servo servo2;


unsigned long Time ;


int xA;
int yA;
int zA;


#include <SD.h>
#include <SPI.h>


File myFile;
int pinCS = 53;


void setup() {


 Serial.begin(9600);
 pinMode(pinCS, OUTPUT);


 servo1.attach(9);
 servo2.attach(10);


 // SD Card Initialization
 if (SD.begin())
 {
   Serial.println("SD card is ready to use.");
 } else
 {
   Serial.println("SD card initialization failed");
   return;
 }


 // Create/Open file
 myFile = SD.open("test.txt", FILE_WRITE);


 // if the file opened okay, write to it:
 if (myFile) {
   myFile.println("Testing");
   myFile.close(); // close the file
   Serial.println("Done");
 }
 // if the file didn't open, print an error:
 else {
   Serial.println("error opening test.txt");
 }


}
void loop() {
 Time = millis();


 servo1.write(0);
 servo2.write(0);


 if (millis() >= 0 && millis() <= 5000) {
   servo1.write(0);
   servo2.write(0);
   delay(10);
 }


 if (millis() > 5000 && millis() <= 10000) {
   servo1.write(90);
   servo2.write(90);
   delay(10);
 }


 if (millis() > 10000) {
   servo1.write(0);
   servo2.write(0);
   delay(10);
 }


 myFile = SD.open("test.txt", FILE_WRITE);


 xA = analogRead(A0);
 yA = analogRead(A1);
 zA = analogRead(A2);


 Serial.print(xA);
 Serial.print(",");
 Serial.print(yA);
 Serial.print(",");
 Serial.print(zA);
 Serial.println();


 // if the file opened okay, write to it:
 if (myFile) {
   myFile.print(xA);
   myFile.print(",");
   myFile.print(yA);
   myFile.print(",");
   myFile.print(zA);
   myFile.println();
   myFile.close(); // close the file
 }
 // if the file didn't open, print an error:
 else {
   Serial.println("error opening test.txt");
 }
 delay(200);
}

ADXL335_SD_DualServoTiming.ino (2.42 KB)

Please edit your Post and use the code button </>

so that your code looks like this

When you say “I was not able to use keypad properly” what actually happens when you try to use it and what do you want to happen that is different?

It is not a good idea to have delay()s in a program that is using millis() for timing.

You should not use millis() like this as you have no control over the actual value of millis()

 if (millis() > 5000

Always do it like this

if (millis() - startTime >= 5000) {

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

…R

Thanks for your reply
The problem with keypad is that I want to choose 1 key and then servos start working (the car is driving) for 5 seconds and then stop on their own. Meanwhile accelerometer starts collecting values on SD card in any independent interval (200 ms) until I choose 2 key. So it measures acceleration and then braking and thats all. I can make keypad write values on serial monitor but they do not work I mean they do not impact servos and SD module.
Now tried sth like that but nothing is being written on SD and servo does not work. How could I use switch & case functions here?

#include <Keypad.h>
#include <SD.h>
#include <SPI.h>
#include <Servo.h>

const byte ROWS = 4;
const byte COLS = 4;

byte rowPins[ROWS] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 8, 9};

char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

Keypad klawiatura = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

Servo servo2;

int xA;
int yA;
int zA;
unsigned long millis();
unsigned long startTime;
unsigned long currentMillis = 0;
int pinCS = 53;
String receivedData = "";
char key = klawiatura.getKey();

File myFile;



void setup() {

  Serial.begin(9600);
  pinMode(pinCS, OUTPUT);

  servo2.attach(10);
  servo2.write(0);

  startTime = millis();  //initial start time

  // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready to use.");
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }

  // Create/Open file
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    myFile.println("Testing");
    myFile.close(); // close the file
    Serial.println("Done");
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("error opening test.txt");
  }


}
void loop() {
  currentMillis = millis();

  accelerationToSD() ;
  servoCycle() ;
}

void servoCycle() {
  if (Serial.available() > 0) {

    if (key == "1") {

      if (currentMillis - startTime >= 0 && currentMillis - startTime < 5000) {
        servo2.write(0);
        delay(10);
      }

      if (currentMillis - startTime >= 5000 && currentMillis - startTime < 10000) {
        servo2.write(150);
        delay(10);
      }

      if (currentMillis - startTime >= 10000) {
        servo2.write(0);
        delay(10);
      }
    }
    else {

    }
  }
}

void accelerationToSD() {

  if (key == "1") {
    xA = analogRead(A0);
    yA = analogRead(A1);
    zA = analogRead(A2);

    myFile = SD.open("test.txt", FILE_WRITE);

    // if the file opened okay, write to it:
    if (myFile) {
      myFile.print(xA);
      myFile.print(",");
      myFile.print(yA);
      myFile.print(",");
      myFile.print(zA);
      myFile.println();
      myFile.close(); // close the file
    }
    else {
      Serial.println("error opening test.txt");
    }

  }
  if (key == "2") {
    myFile.close(); // close the file
    Serial.println("Measurement complete");
  }
  delay(200);
}

My second code works but it doesn’t use keypad unfortunately.

#include <Servo.h>

Servo servo1;
Servo servo2;

unsigned long millis();
unsigned long startTime = 0;
unsigned long currentMillis = 0;

int xA;
int yA;
int zA;

#include <SD.h>
#include <SPI.h>

File myFile;
int pinCS = 53;

void setup() {

  Serial.begin(9600);
  pinMode(pinCS, OUTPUT);

  startTime = millis();  //initial start time

  servo1.attach(9);
  servo2.attach(10);

  servo1.write(0);
  servo2.write(0);

  // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready to use.");
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }

  // Create/Open file
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    myFile.println("Testing");
    myFile.close(); // close the file
    Serial.println("Done");
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("error opening test.txt");
  }

}
void loop() {

  accelerationToSD() ;
  servoCycle() ;
  currentMillis = millis();
}

void   servoCycle() {
  
  if (currentMillis > 5000 && currentMillis <= 10000) {
    servo1.write(90);
    servo2.write(90);
    delay(50);
  }

  if (currentMillis > 10000) {
    servo1.write(0);
    servo2.write(0);
    delay(50);
  }

}

void     accelerationToSD() {
  myFile = SD.open("test.txt", FILE_WRITE);

  xA = analogRead(A0);
  yA = analogRead(A1);
  zA = analogRead(A2);

  Serial.print(xA);
  Serial.print(",");
  Serial.print(yA);
  Serial.print(",");
  Serial.print(zA);
  Serial.println();

  // if the file opened okay, write to it:
  if (myFile) {
    myFile.print(xA);
    myFile.print(",");
    myFile.print(yA);
    myFile.print(",");
    myFile.print(zA);
    myFile.println();
    myFile.close(); // close the file
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("error opening test.txt");
  }
  delay(200);
}

I'm not familiar with the Keypad library. I wonder if it is necessary to call klawiatura.getKey(); regularly?

If you want an action to continue for some time after a key is detected then you need to save the value of millis() when the key is detected and follow up with code like this

if (millis() - timeKeyWasDetected >= interval) {
   // time is up
   // turn something off
}

...R