small issue but i believe this would be easily solvable. I have been reading this code for too long and must be missing something. In short, i have an character array of phone numbers stored, and i wish to ADD a number to this array from the input of the keypad. HOWEVER, as i measure of error checking i wish to compare each stored phone number to the input number to ensure there are no doubles, its meant to be something simple, however doesnt seem to work. code is below.
Also, once i do work out if there is or isnt a match, any advice on how to input the phone number into the array?
/* Keypadtest.pde
*
* Demonstrate the simplest use of the keypad library.
*
* The first step is to connect your keypad to the
* Arduino using the pin numbers listed below in
* rowPins[] and colPins[]. If you want to use different
* pins then you can change the numbers below to
* match your setup.
*
*/
#include <Keypad.h>
const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'#','0','*'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 45, 47, 49, 51 };
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 39, 41, 43};
// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char remoteNumber[][11]= { "0411216560", "0411216560", "0411216560", "0411842412"};
#define ledpin 13
void setup()
{
pinMode(ledpin,OUTPUT);
digitalWrite(ledpin, HIGH);
Serial.begin(9600);
}
int i=0;
char Key;
char entryStr[3];
void loop(){
char key;
key = 0;
while(key ==0)
{
key = kpd.getKey();
}
char key2 = key;
key = 0;
while(key ==0)
{
key = kpd.getKey();
}
int comkey= ((key2-'0')*10)+(key-'0');
switch(comkey)
{
case 10:
char number;
char numberfinal[8];
for (i = 0; i <10; i++)
{
number = 0;
while( number == 0)
{
number = kpd.getKey();
}
numberfinal[i] = number;
Serial.print("NUMBER:");
Serial.print(number);
Serial.println();
Serial.print("NUMBER FINAL:");
Serial.print(numberfinal);
}
Serial.print("POINT1");
i = 0;
point:
Serial.print("Point2");
if (strcmp(remoteNumber[i], numberfinal) == 0)
{
Serial.print("MATCH");
}
else
{
i++;
Serial.print("NONE");
Serial.print(i);
Serial.println();
goto point;
}
break;
case 12:
Serial.print("Entry 12");
Serial.println();
break;
default:
Serial.print("NOTHING");
Serial.println();
}
}
How about you edit your post and format the code a bit better? That's disgusting to read.
Just hit Ctrl-T in the IDE, then replace the current code with the result.
You could also remove the superfluous empty lines while you're at it. They don't improve readability.
Make it easy for people to help you, not hard.
And why are you using "goto". That's taboo, and shouldn't be necessary.
You create an 8-element array, then store 10 values in it. That won't be helping a whole lot:-
char numberfinal[8];
for (i = 0; i < 10; i++)
{
number = 0;
while ( number == 0)
{
number = kpd.getKey();
}
numberfinal[i] = number;
Edit: Also, you need to add a terminating nul character to 'numberfinal' before the comparison using 'strcmp()', or it will fail. (A terminating nul char is '\0'.) So to hold 10 digits + '\0', the array needs to be 11 elements long, not 8.
sterretje:
You can't add a number to your array of numbers. Your array of numbers has a fixed size for 4 numbers; you can only edit the existing numbers.
Ha ha, I completely missed that.
Edit: In my defence, the code makes no attempt to add a number to the original 'remoteNumber' array.
hey, sorry about that i fixed it up and ended up getting it working, except for adding the number in. So there is no possibe way to add a number to that array? what about using a vector how would i go about using that? sorry i am just very inexperience with programming
/* Keypadtest.pde
Demonstrate the simplest use of the keypad library.
The first step is to connect your keypad to the
Arduino using the pin numbers listed below in
rowPins[] and colPins[]. If you want to use different
pins then you can change the numbers below to
match your setup.
*/
#include <Keypad.h>
const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'#', '0', '*'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 45, 47, 49, 51 };
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 39, 41, 43};
// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char remoteNumber[][11] = { "0411216560", "0411216560", "0411216560", "0411842412"};
#define ledpin 13
#define arr_len( x ) ( sizeof( x ) / sizeof( *x ) )
int arrSize = ((arr_len( remoteNumber ) * arr_len( remoteNumber[ 0 ] )) / 11);
char number;
char numberfinal[11];
void setup()
{
pinMode(ledpin, OUTPUT);
digitalWrite(ledpin, HIGH);
Serial.begin(9600);
}
int i = 0;
char Key;
char entryStr[3];
void loop() {
char key;
key = 0;
while (key == 0)
{
key = kpd.getKey();
}
char key2 = key;
key = 0;
while (key == 0)
{
key = kpd.getKey();
}
int comkey = ((key2 - '0') * 10) + (key - '0');
switch (comkey)
{
case 10:
for (i = 0; i < 10; i++)
{
number = {};
while ( number == 0)
{
number = kpd.getKey();
}
numberfinal[i] = number;
Serial.print("NUMBER:");
Serial.print(number);
Serial.println();
Serial.print("NUMBER FINAL:");
Serial.print(numberfinal);
}
Serial.print("POINT1");
i = 0;
point:
Serial.print("Point2");
if (strcmp(remoteNumber[i], numberfinal) == 0)
{
Serial.print("MATCH");
}
/* else if (i >= arrSize)
{
int arrSizenew = arrSize + 1;
strcat(remoteNumber[arrSizenew], numberfinal);
Serial.println(); Serial.println(); Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.print("ARRSIZE NEW:");
Serial.println();
for ( i = 0; i <= arrSizenew; i++)
{
Serial.println();
Serial.print(remoteNumber[i]);
Serial.println();
Serial.print("NEW NUMBER");
Serial.print(remoteNumber[arrSizenew]);
}
}
*/
else
{
i++;
Serial.print("NONE");
Serial.print(i);
Serial.println();
goto point;
}
break;
case 12:
Serial.print("Entry 12");
Serial.println();
break;
default:
Serial.print("NOTHING");
Serial.println();
}
}
It's not a good idea to use dynamic memory allocation in microcontrollers. That can very quickly get you into trouble.
It's better to declare an array in advance that can hold the maximum number of entries that you'll want to store. Far safer.
e.g.
// This array can hold another 48 phone numbers:-
char remoteNumber[50][11] = {"0411234567","0411345678"};
Edit: Oops, a blonde moment. I removed this bit to avoid misleading anyone. Sorry.
I haven't thoroughly read over your latest code. The formatting is better, but there are still lots of extra blank lines for no particular reason. And when you comment out part of it, we have no way of knowing whether or not to consider it a part of the code. (I personally always totally ignore anything that's commented out.)
You should really edit your original post and fix the formatting in it too, as I suggested, to make it more readable for anyone else that reads this thread, now or in the future.
If you don't want to waste SRAM memory on 50 phone numbers, you can store them in EEPROM. Solves the problem as well that you would loose the edited / added numbers after a reset.
sterretje:
If you don't want to waste SRAM memory on 50 phone numbers, you can store them in EEPROM. Solves the problem as well that you would loose the edited / added numbers after a reset.
This is the best answer.
Or for a huge number of entries, it's even possible to store them in flash program memory.
(I installed the "MiniCore" to add this functionality, among other things.)
sterretje:
If you don't want to waste SRAM memory on 50 phone numbers, you can store them in EEPROM. Solves the problem as well that you would loose the edited / added numbers after a reset.
This seems like the best option, anyone have any advice as to learning how to use and access EEPROM, im only a beginner programmer and the concept sounds difficult, however im willing to learn as it will provide fantastic functionality!
char numbers[][11] = {"0411216560", "0411216560", "0411216560", "", "0411842412"};
void setup()
{
char number[11];
Serial.begin(9600);
// save the numbers
for(int cnt=0;cnt<sizeof(numbers) / sizeof(numbers[0];cnt++)
{
eeprom.put(cnt*sizeof(numbers[0]), numbers[cnt]);
delay(50);
}
// read them back
for(int cnt=0;cnt<sizeof(numbers) / sizeof(numbers[0];cnt++)
{
eeprom.get(cnt*sizeof(numbers[0]), number);
Serial.print("id = "); Serial.println(cnt);
Serial.print(", number = ");
if(strcmp(number,""))
Serial.println(number);
else
Serial.println("no number stored");
}
}
void loop()
{
}
Not tested.
For demo purposes, there is an initial array that will be written to eeprom. The first for-loop writes the data to eeprom. It writes all 11 characters of the number (even if a number would only be 2 characters).
The second loop reads the numbers back but does not store them in the initial array.
Then you would put a new entry in 'remoteNumber[numEntries]'
That will NOT work. The value in numEntries will ALWAYS be the number of elements that the array can hold, NOT the location of the first unused element.
// save the numbers
for(int cnt=0;cnt<sizeof(numbers) / sizeof(numbers[0];cnt++)
{
eeprom.put(cnt*sizeof(numbers[0]), numbers[cnt]);
delay(50);
}
// read them back
for(int cnt=0;cnt<sizeof(numbers) / sizeof(numbers[0];cnt++)
{
eeprom.get(cnt*sizeof(numbers[0]), number);
Serial.print("id = "); Serial.println(cnt);
Serial.print(", number = ");
if(strcmp(number,""))
Serial.println(number);
else
Serial.println("no number stored");
}
}
void loop()
{
}
Not tested.
For demo purposes, there is an initial array that will be written to eeprom. The first for-loop writes the data to eeprom. It writes all 11 characters of the number (even if a number would only be 2 characters).
The second loop reads the numbers back but does not store them in the initial array.
ahh yeah i get what it does. However what if i wanted to load all of those preloaded numbers into a char array matrix to be used when the program initialises, and only when i add or remove a single number does it access the EEPROM. Is this possible?
if i wish to remove the phone number for example 0411698785, is it possible to search through the EEPROM and then remove it? sorry for stupid questions, my programming ability is only basic (for now)!
if i wish to remove the phone number for example 0411698785, is it possible to search through the EEPROM and then remove it?
It is.That is NOT going to be terribly efficient, though. The usual thing to do is store something in every position - a phone number string, a "not used" string, or a "end of data" string.
Then, if you want to add a phone number, you find the first "not used" string, and replace it with the phone number. If there is no "not used" string before the "end of data" string, replace the "end of data" string with the phone number and store the "end of data" string in the next position.
To remove a number, just replace the number with the "not used" string.
If you want to print the stored phone numbers, iterate through the array, until the "end of data" is found. Print the phone number only if it is not the "not used" string.
The "not used" string and the "end of data" string do not have to be "not used" and "end of data".
PaulS:
That will NOT work. The value in numEntries will ALWAYS be the number of elements that the array can hold, NOT the location of the first unused element.
Oops, a mental slip on my part.
You're right, of course. The number of entries needs to be kept track of.
(I removed that to avoid misleading the OP or anyone else in the future.)
PaulS:
It is.That is NOT going to be terribly efficient, though. The usual thing to do is store something in every position - a phone number string, a "not used" string, or a "end of data" string.
Then, if you want to add a phone number, you find the first "not used" string, and replace it with the phone number. If there is no "not used" string before the "end of data" string, replace the "end of data" string with the phone number and store the "end of data" string in the next position.
To remove a number, just replace the number with the "not used" string.
If you want to print the stored phone numbers, iterate through the array, until the "end of data" is found. Print the phone number only if it is not the "not used" string.
The "not used" string and the "end of data" string do not have to be "not used" and "end of data".
i think i understand what your saying however i feel this is way beyond my capabilities... im not sure what to do or how to start anything remotely as complex as this.
sterretje:
Do you understand the example that I gave? There was, on purpose, an empty entry. It is not complex once you understand what is going on.
yes your example was easy to understand, as EEPROM stores as single bits and we know that the phone numbers are in intervals of 10, with null termination as 11th bit, we can store it and retrieve it like that!
Is that correct?
My concern was though should there be an addition or deletion of phone number how would i go about adding or removing a single number from the EEPROM, as far as i understood your code only reads the whole EEPROM and stores in a new char array matrix, or takes an existing matrix and places it in the memory
i think i understand what your saying however i feel this is way beyond my capabilities... im not sure what to do or how to start anything remotely as complex as this.
Grab a stack of 3 x 5 cards. Write some data on some of them. Leave one blank, at the end. Cross out the data on some of the cards.
Now, go through the stack of cards and decide how YOU would:
Delete the data on a card.
Add a new card when the collection of cards contains deleted data.
Add a new card when the collection of cards does not contain deleted data.
Think about how you might create some functions, like DeleteRecord(), AddRecord(), FindEntryPosition(), etc.
Think about what those functions might need to know, such as which record to delete, what data to add, where to add the data, etc. Think about what those functions might return, such as nothing, the position of a record containing deleted data, etc.
The process seems daunting at first, but is really very simple, once you have broken it down into steps that you understand and know how to perform.