2

I am trying to create beep sound from characters in the string. Here is the code:

/*
 * Buzzer connected to Arduino uno digital pin 13
 * Switch connected to digital pin 2
 */ 

#include <avr/io.h>
#include <util/delay.h>

const int TBEEP = 1000;
const int TBEEEEP = 3500;
const int TGAP = 500;
const int TGAPLETTER = 2000;
int portb = 0x20;

void beep() {
    PORTB = ~portb; _delay_ms(TGAP);
    PORTB = portb; _delay_ms(TBEEP);
    PORTB = ~portb; _delay_ms(TGAP);
}

void beeeep() {
    PORTB = ~portb; _delay_ms(TGAP);
    PORTB = portb; _delay_ms(TBEEEEP);
    PORTB = ~portb; _delay_ms(TGAP);
}

void gapLetter() {
    PORTB = ~portb; _delay_ms(TGAPLETTER);
}

void morse_S() {
    beep(); beep(); beep();
    gapLetter();
}

void morse_M() {
    beeeep(); beeeep();
    gapLetter();
}

void morse_SMS() {
    morse_S(); morse_M(); morse_S();
}

void morse(char theString[]) {
    for (int i = 0; theString[i] != '\0'; i++)
    {
        if(&theString[i] == "S")
            morse_S();
        else if(&theString[i] == "M")
            morse_M();
    }
}

int main (void)
{
    DDRB = 0xFF;
    DDRD = 0x00;
    PORTD = 0x04;

    while (1) {
        if (PIND & 0x04) {
            PORTB = ~0x20;
        } else {
            //morse_SMS(); // it works
            morse("SMS"); // this one doesnt work like morse_SMS() PLEASE HELP!
        }
    }
    return 0;
}

In function void morse(char theString[]) {...}, I want to produce beep sound from every character in the string "SMS". Unfortunately, only the last character can make it.

I am using Atmel Studio 6. When I build solution (F7) there is no error but warning which I dont understand (sorry for being such a total noob)

comparison with string literal results in unspecified behavior [-Waddress]

How to force every character to beep one after another?

Aji
  • 31
  • 7

2 Answers2

4

First of all,

const int TBEEP = 1000;
const int TBEEEEP = 3500;

These made my day. :)


Apart from that, you should really get a good beginner C book. You can't compare strings using the == operator, because that compares pointers, not contents. If you want to compare strings, use the strcmp() function from the C standard library.

But: in your case, you don't want to compare strings. You want to compare characters. And that can be done with ==, just dereference the character pointer to obtain the actual character, and compare it with a character literal, not with a string literal:

if (theString[i] == 'S')
    morse_S();
else if (theString[i] == 'M')
    morse_M();

Oh, and probably you want to avoid that enormous chained if...else if...else monster. Assuming UTF-8 or at least ASCII encoding, where the character codes of English letters are in alphabetical order:

void (*morse_funcs[26])();
morse_funcs[0] = morse_A;
morse_funcs[1] = morse_B;
// ...
morse_funcs[25] = morse_Z;

// ...

void morse(const char *s)
{
    while (*s)
        morse_funcs[tolower(*s++) - 'a']();
}

Also, notice how I changed char * into const char *. If you don't modify a string, tell the compiler that you don't intend to modify it, so you can safely pass in string literals as well.

Even better: don't use a table of function pointers, but a table of Morse codes. Like this:

const char *mcodes[26] = {
    ".-",        // 'a'
    "-...",      // 'b'
    // etc...
    "--.."       // 'z'
};

void do_morse(const char *code)
{
    while (*code)
        if (*code++ == '-')
            beeeep();
        else
            beep();
}

void morse(const char *s)
{
    while (*s)
        do_morse(mcodes[tolower(*s++) - 'a']);
}
  • I had been tested that before BUT using "S" & "M" instead of 'S' & 'M'. I am surprised such a double quote make something become different in C. Thank You. – Aji Jul 28 '13 at 08:04
  • 1
    @aww Well, if something is different (i. e. double and single quotes), why would you even assume they mean the same thing? Also, as I've mentioned, get a good C tutorial. Instead of making assumptions, **learn** from a trusted source. Then *think,* try to *make sense* of what your code does versus what it should do. Try to work out its working on paper or in head. Apart from all that, compiling with `gcc -Wall` doesn't hurt, and then GCC will output a whole bunch of useful warnings that you should fix. –  Jul 28 '13 at 08:05
  • Thanks for your advice. This is my first week learning C. I am used to code in php that always give me same result using double or single quote (curse you, habit). Can you suggest me a title of good beginner C book? There are lots of book out there. Choosing a good book to buy is a gambling for me :D – Aji Jul 28 '13 at 08:29
  • 1
    @aww "K&R C" (a. k. a. "The C programming langauge" by Brian Kerninghan and Dennis Ritchie) is written by the creators of C. Also, if you google a bit around on SO, you will soon find [this list](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). –  Jul 28 '13 at 08:41
0

Try this:

void morse(char theString[]) {
    for (int i = 0; theString[i] != '\0'; i++)
    {
        if(theString[i] == 'S')
            morse_S();
        else if(theString[i] == 'M')
            morse_M();
    }
}
P0W
  • 46,614
  • 9
  • 72
  • 119
  • Any explanation as to **why** do this? –  Jul 28 '13 at 07:58
  • @H2CO3 I never get time, as soon as I write something, I see a yellow blink with a flashing fast upvotes on other answers :D And to top of that my 'Zero' key doesn't work, which has a 'close brace' on it too :D, thanks. – P0W Jul 28 '13 at 08:02
  • OMG that's sad! :( Get your key fixed, it should be a pain to get those parentheses right... –  Jul 28 '13 at 08:04