Require guidance in my new project

PaulRB:
It would be much more efficient to store your passwords as long int instead of string (char *). Only half the space would be required.

For less than 1000 paswords, you could use 1 byte of eeprom to indicate that a password had been used/deleted. For example if an entered password matched the stored password at index 123, then you could write a 1 to eeprom address 123. When the next entered password was matched, for example with the password stored at index 234, you would read the eeprom address 234 to see if a 1 had been previously written there, before accepting the password.

Ok. But I am a bit confused. What I did in the previous sketch means it has stored 520 passwords in the flash memory which is 32 Kb but not in the EEPROM, is that right?
Below I am giving a working sketch that I used and wrote 36 passwords in the flash memory. It is working fine but is it possible that I could delete the correct password in run time? I saw on the forum that it was not possible but now it is due to a third party bootloader.
I think it is possible to read and write in EEPROM in run time, isn't it? And you are suggesting that if the number of passwords is less than 1000, I should go for EEPROM and not the flash memory, did I understand you correctly?

#include <avr/pgmspace.h>
#include <Keypad.h>

const char string_0[] PROGMEM = "1234567"; // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "1232345";
const char string_2[] PROGMEM = "6384625";
const char string_3[] PROGMEM = "1129864";
const char string_4[] PROGMEM = "2312345";
const char string_5[] PROGMEM = "7429573";
const char string_6[] PROGMEM = "1234167";
const char string_7[] PROGMEM = "1232145";
const char string_8[] PROGMEM = "6384125";
const char string_9[] PROGMEM = "1129164";
const char string_10[] PROGMEM = "2312145";
const char string_11[] PROGMEM = "7429173";
const char string_12[] PROGMEM = "1234267";
const char string_13[] PROGMEM = "1232245";
const char string_14[] PROGMEM = "6384225";
const char string_15[] PROGMEM = "1129264";
const char string_16[] PROGMEM = "2312245";
const char string_17[] PROGMEM = "7429273";
const char string_18[] PROGMEM = "1234667";
const char string_19[] PROGMEM = "1232645";
const char string_20[] PROGMEM = "6384625";
const char string_21[] PROGMEM = "1129664";
const char string_22[] PROGMEM = "2312645";
const char string_23[] PROGMEM = "7429673";
const char string_24[] PROGMEM = "1234067";
const char string_25[] PROGMEM = "1232045";
const char string_26[] PROGMEM = "6384025";
const char string_27[] PROGMEM = "1129064";
const char string_28[] PROGMEM = "2312045";
const char string_29[] PROGMEM = "7429073";
const char string_30[] PROGMEM = "1234867";
const char string_31[] PROGMEM = "1232845";
const char string_32[] PROGMEM = "6384825";
const char string_33[] PROGMEM = "1129764";
const char string_34[] PROGMEM = "2312845";
const char string_35[] PROGMEM = "7429873";

// Then set up a table to refer to your strings.

const char *const availablePassword[36] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8, string_9, string_10, string_11, string_12, string_13, string_14, string_15, string_16, string_17, string_18, string_19, string_20, string_21, string_22, string_23, string_24, string_25, string_26, string_27, string_28, string_29, string_30, string_31, string_32, string_33, string_34, string_35};

char buffer[8];                    // make sure this is large enough for the largest string it must hold

#define Password_Length   8

char enteredPassword [Password_Length];

byte data_count = 0;
bool passwordAccepted = false;

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

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

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

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
  Serial.begin(9600);
  while (!Serial);  // wait for serial port to connect. Needed for native USB
}


void loop() {
  /* Using the string table in program memory requires the use of special functions to retrieve the data.
     The strcpy_P function copies a string from program space to a string in RAM ("buffer").
     Make sure your receiving string in RAM is large enough to hold whatever
     you are retrieving from program space. */


  char customKey = customKeypad.getKey();

  if (customKey) {
    enteredPassword[data_count] = customKey;
    Serial.print(enteredPassword[data_count]);
    data_count++;
  }
  
  if (data_count == Password_Length - 1) {

    for (int i = 0; i < 36; i++) {
    strcpy_P(buffer, (char *)pgm_read_word(&(availablePassword[i])));   
      if (!strcmp(enteredPassword, buffer)) {
        passwordAccepted = true;
        break;
      }
        passwordAccepted = false;
     }
    
    if (passwordAccepted) {
      Serial.println("Password accepted.");
    }
    else {
      Serial.println("Wrong Password...");
    }
   clearData();
 }
}

void clearData() {

  while (data_count != 0) {
    enteredPassword[data_count--] = 0;
  }
  return;
}

did I understand you correctly?

When you said:

Sorry Paul, will be careful next time.

I thought you had understood, but now I realise you did not.

PaulRB:
I thought you had understood, but now I realise you did not.

Why? What went wrong again?
Well, next time I am not gonna use a quote again. Will just use the reply option.

By all means use the quote option if necessary, but edit the quote back to only the single sentence to which your reply refers. Don't edit out the quote tags if you do this though. :astonished:

Paul__B:
edit the quote back to only the single sentence to which your reply refers.

Ok, sure :slight_smile:

unsigned long long int baseNumber = 5217440798311;              // uint64_t
unsigned long long int divided;

void setup() {
   Serial.begin(9600);
   
   for (int i = 1; i <= 500; i++) {
    int y = 6 * i;
    divided = (baseNumber/y);
    sprintf("%llu", divided);
  }

}

void loop() {
 
}

Hi,
I am trying to divide and print the value but it doesn't work. May I know the mistake in the code, please?
Thanks

bilal40:
it doesn't work.

From the forum guide:

Code ALWAYS works, that is the nature of code. Whether it does what you expect is a different thing altogether. We need to know what you expected the code to do and what happened instead.

How do you know it doesn't work?

You are using sprintf() incorrectly, you gave the wrong parameters.

What I meant was, I was expecting the values to be printed but it did not print anything.
@Paul, I saw the sprintf ("%llu\n", divided); on a forum. Though it compiled correctly but didn't print anything. Just a (?).

Your code doesn't have a print in it.
The code should not even compile, which is why I asked how you knew it didn't work.

I don't know how did it compile. I saw the sprintf for the first time. Thought it is going to print something. Even my program did print 500 values once, if there is no printing function, it is strange how did that happen.
Printing the unsigned long long value got some way of printing?

char buffer[20];
sprintf(buffer, "%llu", divided);
Serial.println(buffer);

The code compiled, the serial monitor scrolls down as it has to run the loop 500 times. But the serial monitor is blank, scrolling but blank.

unsigned long long int baseNumber = 1234567891112;
unsigned long long int divided = 0;
char buf [20];

void setup() {
   Serial.begin(9600);
   
   for (int i = 1; i <= 500; i++) {
    int y = 6 * i;
    divided = (baseNumber/y);
    sprintf(buf, "%llu", divided);
    Serial.println(buf);
  }

}

void loop() {
 
}

Change all the "long long int" to "long int" and the "%llu" to "%lu" and the baseNumber value to below 10 digits. Does it run correctly? If so, perhaps sprintf() does not work with 64-bit integers on Uno, for the same reason that Serial.print() does not work.

@PaulRB, yes, with the unsigned long int it works fine. But with unsigned long long int, it isn't working.

I have been reading about the data comparison between sd card data to user input data through serial monitor but couldn't grasp the exact idea.
I am able to write to the sd card a number, for instance, a number 500. Later on, I want to put 500 through the serial monitor and wanna compare it to the data in the sd card that if 500 already exists there.
So, in the given code below I am writing 500 to the card.

#include <SPI.h>
#include <SD.h>
int enteredNumber = 500;
File myFile;

void setup() {

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

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

  if (myFile) {
    myFile.println(enteredNumber);
    myFile.close();
  } else {
    Serial.println("error opening TESTING.txt");
  }

I can read the written data to the card as:

#include <SPI.h>
#include <SD.h>
int enteredNumber = 500;
File myFile;

void setup() {

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  
  myFile = SD.open("TESTING.txt");
  
  if (myFile) {

    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  } else {
    Serial.println("error opening TESTING.txt");
  }
}

void loop() {
  // nothing happens after setup
}

What I don't understand here is when the data is read from the TESTING file, it should be assigned to something so that I can make a comparison then.

For example, enteredNumber = 500, so for comparison I could say, if (enteredNumber == xxxxx). where xxxxx shows the variable which could hold the data from the sd card. May I know how can I make this comparison?

Secondly, enteredNumber is in int form. The data stored in the sd card, when it is read, what format or data type it would be?

Thank you!

In your first sketch above, myFile.println() converts the int into a string of 3 characters, ie. '5', '0', '0' followed by CR and/or LF codes for the end of line. Your second sketch simply reads one character at a time from the file and echoes it to serial monitor one character at a time.

To read the number back from the file as an int, you can use myFile.parseInt().

Alternatively you can write, and read back, int from the file without converting it to characters. This will be faster and the file will be smaller, but if you want to remove the sd card and read it on pc or laptop, that might be difficult.

@PaulRB, thank you. I did it with this technique. I can read the file first to check for the password if already available, and then write to the Passwords.txt if a valid password gets entered and not on the list already. The password entered for the second time gets declined.

myFile = SD.open("Passwords.txt");

    if (myFile) {
      Serial.println("PASSWORDS.txt:");

      while (myFile.available()) {                                                      // Something left to read
        char c = myFile.read();                                                         // Get the next character
        if (isdigit(c)) {                                                               // It's a number 0-9
          savedNum *= 10;                                                               // Make room by decimal shifting to the left
          savedNum += (c - '0');                                                        // Convert the character to a number and add it to the total
        } else if (c == '\n') {                                                         // End of line                                                  // Show us the number
          numberOne = savedNum;                                                         // Store it somewhere else - enhance this for multiple numbers.
          savedNum = 0;                                                                 // Reset to 0 ready to read the next line
        }
        if (userPassword == numberOne) {
          Serial.println("Match found");
          matchFound = true;
          break;
        }
      }
      myFile.close();                                                                   // close the file:
    }
    else {
      Serial.println("error opening test.txt");
    }

Hello everyone,
I have already asked this question but yesterday I was implementing it and got some issues.
I am using an HC-SRD4 ultrasonic sensor. I want to connect the trig and echo pins to analog pins on Arduino as I am short with digital pins. With one of the sketches I uploaded, I didn't get the expected result when the pins were connected to analog pins, but I got the expected result when the pins got connected to digital pins.

I then uploaded another example sketch and got expected results even with the analog pins. Generally, when I watch videos regarding the ultrasonic sensor integrated with Arduino, the trig and echo pins are connected to digital pins. So, my question is can I connect it to analog pins without experiencing issues now or in the future? Thanks