February 23, 2014
by escartiz
|
Hi everyone, I need help with if else validation of a char array, I have hooked up a keypad to the mcu and I am gathering inputs as char arrays so for example I have:
char buf[5];
buf[0] = 0;
then as I get inputs I assing them as follow
buf[0] = 1; buf[1] = 3; etc...
Once I gather all 5 arrays for buf[] I like to do an if else evaluation to find out if the whole buf[0-5] is equal to "12345" else set buf to blank again
if(buf[] == '12345') {
// continue
} else {
buf[0] = 0x00;
}
this is not working, so what would be the best way to do a full evaluation of buf[]
I was thinking of using &&
if((buf[0] == 1) && (buf[1] == 2) && (buf[2] == 3)….);
but before I try that as it would look messy I like to know the best approach to accomplish this |
February 23, 2014
by esoderberg
|
escartiz,
There are function to do this using the include file string.h.
#include <stdio.h>
#include <string.h>
int main()
{ char buf[bufsize], test[bufsize], result=1;
if( strcmp(buf,test) == 0 )
result=0;
else
result=1;
}
Without the library I might try:
char buf[bufsize], test[bufsize], result=1;
for ( x = 0; x < bufsize; x++ ){if !(buf[x]==test[x]) result=0;}
if the strings are the same result will remain 1, if not result = 0.
Eric |
February 23, 2014
by Ralphxyz
|
Boy am I glad to see some activity, I swear I learn something with every question.
Ralph |
February 23, 2014
by Noter
|
Strings must be null terminated. Best not to leave it to chance and always allocate an extra byte for the null terminator and then be sure it is a null character.
Maybe memcmp would be easier in this case -
result = memcmp(buf, test, bufsize);
|
February 24, 2014
by JKITSON
|
Ralph:
I agree. I still am having problems with strings & my radio setup. I think I will try some of these ideas..
Eric & Noter.. thanks for the time to help.
Jim |
February 24, 2014
by escartiz
|
Thanks everyone for your help. I usually strugle with my projects by spending countless hours looking trough the other member's post and the library (thanks Ralph for introducing me to the webbackarchive). It really worried me when I could no longer access the library and since there is not much activity I wanted to ask openly and just maybe let Humberto and Mike know that there are lots of us still wanting to use the nerdkit website for our projects. Anyways, back to the char evaluation, I made it worst :S hahaha here is what I got so far:
#define F_CPU 14745600
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/io_328p.h"
// PIN DEFINITIONS:
//
// PB5 -- key 1
// Pc0 -- key 2
// Pc1 -- key 3
// Pc2 -- key 4
// Pc3 -- key 5
// Pc4 -- key 6
// Pc5 -- key 7
// PD7 -- buzzer
// PD2 -- green led
// PD3 -- red led
void play_tone(uint16_t dely, uint16_t duration) {
while (duration > 0) {
PORTD |= (1<<PD7);
delay_us(dely);
PORTD &= ~(1<<PD7);
delay_us(dely);
duration--;
}
}
int main() {
// as output
DDRD |= (1<<PD7);
DDRD |= (1<<PD2);
DDRD |= (1<<PD3);
// BUTTONS/SWITCHES
PORTB |= (1<<PB5);
PORTC |= (1<<PC0);
PORTC |= (1<<PC1);
PORTC |= (1<<PC2);
PORTC |= (1<<PC3);
PORTC |= (1<<PC4);
PORTC |= (1<<PC5);
uint16_t x, result;
char buf[4], test[4],
test[] = '12345';
while(1) {
//if (strcmp(buf,test) == 0) {
// result = 0;
//} else {
// result = 1;
//}
result = memcmp(buf, test, 4);
while (x < 4) {
if((PINB & (1<<PB5)) == 0) { // number 1
play_tone(25, 15);
buf[x] = '1';
x++;
}
if((PINC & (1<<PC0)) == 0) { // number 2
play_tone(25, 15);
buf[x] = '2';
x++;
}
if((PINC & (1<<PC1)) == 0) { // number 3
play_tone(25, 15);
buf[x] = '3';
x++;
}
if((PINB & (1<<PC2)) == 0) { // number 4
play_tone(25, 15);
buf[x] = '4';
x++;
}
if((PINB & (1<<PC3)) == 0) { // number 5
play_tone(25, 15);
buf[x] = '5';
x++;
}
if((PINC & (1<<PC4)) == 0) { // number 6
play_tone(25, 15);
buf[x] = '6';
x++;
}
if((PINC & (1<<PC5)) == 0) { // number 7
play_tone(25, 15);
buf[x] = '7';
x++;
}
delay_ms(10);
}
if (result == 1) {
PORTD |= (1<<PD2); // GREEN LED ON
PORTD &= ~(1<<PD3); // RED LED oFF
} else {
PORTD &= ~(1<<PD2); // GREEN LED oFF
PORTD |= (1<<PD3); // RED LED on
}
}
return 0;
}
the only way I have to test right now are the green and red leds. I used the lcd for another project and my serial/usb fried
stupid leds wont light up anymore. I need to understand this strcmp and memcpm a little better. |
February 24, 2014
by escartiz
|
I think I got it |
February 24, 2014
by escartiz
|
The following seems to do the trick, I am still doing more testing. After pressing four times pc5 I get the green light :)
int main() {
// as output
DDRD |= (1<<PD7);
DDRD |= (1<<PD2);
DDRD |= (1<<PD3);
DDRD |= (1<<PD4);
// BUTTONS/SWITCHES
PORTC |= (1<<PC5);
uint16_t x, result;
x = 0;
char buf[5];
char test[5];
memcpy(test, "7777", 4);
while(1) {
result = memcmp(buf, test, 4);
if (result > 0) { // gather more keys
PORTD &= ~(1<<PD2); // GREEN LED oFF
PORTD |= (1<<PD3); // RED LED on
if((PINC & (1<<PC5)) == 0) { // number 7
play_tone(25, 30);
buf[x] = '7';
x++;
}
} else if (result < 0) { // clear buf
PORTD &= ~(1<<PD2); // GREEN LED oFF
PORTD |= (1<<PD4); // AMBAR LED on
play_tone(300, 50);
x = 0;
buf[0] = 0x00;
} else { // char match
PORTD |= (1<<PD2); // GREEN LED ON
PORTD &= ~(1<<PD3); // RED LED oFF
}
}
return 0;
}
|
February 26, 2014
by escartiz
|
here is my home alarm code with the original keypad, buzzer, leds. I just need to hook the pir sensors to ADC.
I am sure this could be better, but it works fine for now :) I might look into debouncing the buttons and once I get a new serial cable I am thinking in doing a python script to send an email or maybe make a SIP call to let me know if the alarm fired off. Thanks for your help, I had a hard time trying to work that password match. let me know what you think and if you catch any thing that could go wrong.
Thanks
// PIN DEFINITIONS:
//
// PC1 -- sensor 1
// PC2 -- sensor 2
// PC3 -- sensor 3
// PC4 -- sensor 4
// PB0 -- keypad 1
// PB1 -- keypad 2
// PB2 -- keypad 3
// PB3 -- keypad 4
// PB4 -- keypad 5
// PB5 -- keypad 6
// Pc0 -- keypad 7
// PD7 -- buzzer
// PD2 -- green led
// PD3 -- red led
// PD4 -- relay
void play_tone(uint16_t dely, uint16_t duration) {
while (duration > 0) {
PORTD |= (1<<PD7);
delay_us(dely);
PORTD &= ~(1<<PD7);
delay_us(dely);
duration--;
}
delay_ms(10);
}
double what_action(uint8_t this_mode) {
PORTD &= ~(1<<PD2); // GREEN LED oFF
PORTD &= ~(1<<PD3); // RED LED oFF
PORTD &= ~(1<<PD4); // RELAY oFF
if(this_mode == 1) {
uint8_t i;
for(i=0; i<10; i++) { // i<40 = 15 sec aprox
play_tone(30, 480);
}
} else {
play_tone(30, 40);
delay_ms(10);
}
return this_mode;
}
int main() {
// as output
DDRD |= (1<<PD7);
DDRD |= (1<<PD2);
DDRD |= (1<<PD3);
DDRD |= (1<<PD4);
// COLS outpu
DDRB |= (1<<PB4);
DDRB |= (1<<PB5);
DDRC |= (1<<PC0);
// ROWS inputs
PORTB |= (1<<PB0);
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB3);
//sensors
PORTC |= (1<<PC1);
PORTC |= (1<<PC2);
PORTC |= (1<<PC3);
PORTC |= (1<<PC4);
PORTC |= (1<<PC5);
uint16_t this_state, count_down, x, result;
this_state = 0;
x = 0;
char buf[5];
char test[5];
memcpy(test, "1234", 4); //Password
memcpy(buf, "0000", 4);
while(1) {
if (this_state == 0) { //system deactivated
PORTD |= (1<<PD2); // GREEN LED ON
count_down = 100; // count down to leave
}
if (this_state == 1) { // system activated
PORTD |= (1<<PD3); // RED LED on
if(((PINB & (1<<PB1)) == 0) || ((PINB & (1<<PB2)) == 0) || ((PINB & (1<<PB3)) == 0) || ((PINB & (1<<PB4)) == 0)) {
this_state = what_action(2);
}
}
if (this_state == 2) { //intrusion
if(count_down == 0) { // exceded count down
PORTD |= (1<<PD4); // relay alarm
} else {
count_down--;
delay_ms(1);
play_tone(30, 40);
}
}
result = memcmp(buf, test, 4);
if (result == 0) {
if(this_state == 0) {
this_state = what_action(1);
} else {
this_state = what_action(0);
}
x = 0;
memcpy(buf, "0000", 4);
} else {
if (x >= 4) { // failed password
play_tone(350, 30);
x = 0;
} else {
// keypad
PORTB &= ~(1<<PB4);
delay_ms(1);
if((PINB & (1<<PB3)) == 0){ buf[x] = '3'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB2)) == 0){ buf[x] = '6'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB1)) == 0){ buf[x] = '9'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB0)) == 0){ x=0; memcpy(buf, "0000", 4); play_tone(100, 30); delay_ms(10); play_tone(100, 30);}
PORTB |= (1<<PB4);
PORTB &= ~(1<<PB5);
delay_ms(1);
if((PINB & (1<<PB3)) == 0){ buf[x] = '2'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB2)) == 0){ buf[x] = '5'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB1)) == 0){ buf[x] = '8'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB0)) == 0){ buf[x] = '0'; x++; play_tone(25, 30); delay_ms(35); }
PORTB |= (1<<PB5);
PORTC &= ~(1<<PC0);
delay_ms(1);
if((PINB & (1<<PB3)) == 0){ buf[x] = '1'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB2)) == 0){ buf[x] = '4'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB1)) == 0){ buf[x] = '7'; x++; play_tone(25, 30); delay_ms(35); }
if((PINB & (1<<PB0)) == 0){ x=0; memcpy(buf, "0000", 4); play_tone(100, 30); delay_ms(10); play_tone(100, 30);}
PORTC |= (1<<PC0);
}
}
}
return 0;
}
|
February 26, 2014
by BobaMosfet
|
For those of you interested in how string functions work; I've written these which you can use, and learn from. They aren't -super-tight-, but they are adequate for most things. My goal was that they be educational/useful.
/*****
*
* MY_STRLEN
*
*****
*
* IN: char* - string being measured
* OUT: int - length in bytes
*
* NOTE: This function has a limit of an int (short), so if data
* exceeds this, (unlikely) it will roll.
*
*****/
int my_strlen(char *str)
{
char *p;
p = str;
while(*p++);
p--;
return((int)(p-str));
}
/*****
*
* MY_STRCPY
*
*****
*
* IN: char* - address of source string
* char* - address of destination string
* OUT: int - number of bytes copied
*
* NOTE: This function copies the contents of the c-style source string, based on
* its length, from its memory location to the one specified by the
* destination string. It does no checking on destination storage space,
* this is left as an exercise for the caller.
*
*****/
int my_strcpy(char *src,char *dst)
{
int len = 0;
int i;
len = my_strlen(src); // Get length of source
for(i=0;i<len;i++) // Copy it
dst[i] = src[i];
dst[len+1] = 0x00; // terminate it
return(len); // Return length of copied data
}
/*****
*
* MY_STRCMP
*
*****
*
* IN: char* - address of source string
* char* - address of comparison string
* OUT: bool - whether or not strings the same
*
* NOTE: This function simply compares the two strings, byte for
* byte. If same, including length byte, we return TRUE.
*
*****/
bool my_strcmp(char *s1,char *s2)
{
int i;
int len;
len = my_strlen(s1);
for(i=0;i<(len+1);i++)
if(s1[i] != s2[i])
return(FALSE);
return(TRUE);
}
I hope this is useful.
Warm regards
BM |
February 26, 2014
by BobaMosfet
|
As an additional note-- you may have to typedef TRUE and FALSE for your implementation. I know that I prefer to.
BM |
February 27, 2014
by Ralphxyz
|
escartiz, I hope you post your project on dropbox or some other public forum.
I need some thing similar to what you are doing, especially the email notification of event.
Ralph |