NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » char array if statement

February 23, 2014
by escartiz
escartiz's Avatar

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
esoderberg's Avatar

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
Ralphxyz's Avatar

Boy am I glad to see some activity, I swear I learn something with every question.

Ralph

February 23, 2014
by Noter
Noter's Avatar

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
JKITSON's Avatar

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
escartiz's Avatar

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
escartiz's Avatar

I think I got it

February 24, 2014
by escartiz
escartiz's Avatar

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
escartiz's Avatar

here is my home alarm code with the original keypad, buzzer, leds. I just need to hook the pir sensors to ADC.

alt image text

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
BobaMosfet's Avatar

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
BobaMosfet's Avatar

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
Ralphxyz's Avatar

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

Post a Reply

Please log in to post a reply.

Did you know that you can read diagnostic data from some cars with a NerdKit? Learn more...