Problem with strcasecmp()

Go To Last Post
34 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello

i wrote a program to control atmega16 pins with sms using sim300 and here is my code:


#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "usart.c"
#include "sim300.c"

int main(void)
{
	DDRB=(1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4);
	DDRD=(1<<PD7);

	uint8_t id,r;

	while(SIM300Init()!=SIM300_OK);//wait for intit

	PORTB|=(1<<PB0);//led to indicate init is done

	while(SIM300GetNetStat()!=SIM300_NW_REGISTERED_HOME);//wait for sim to be registered

	PORTB|=(1<<PB1);//led to indicate sim is registered

	char oa[20];//sender number
	char msg[300];//array to store the message

	while (1)
	{
		while (SIM300WaitForMsg(&id)!=SIM300_OK);//wait for meassge
		PORTB^=(1<<PB4);//toggle pb4 to indicate a message is received
		_delay_ms(300);

		r=SIM300ReadMsg(id,msg,oa);//read the message and store it in msg array

		if(r==SIM300_OK)//if read is successful
		{
			if(strcasecmp(msg,"led3-on")==0)
			{
				PORTB|=(1<<PB3);
			}
			else if (strcasecmp(msg,"led3-off")==0)
			{
				PORTB&=~(1<<PB3);
			}
			else if (strcasecmp(msg,"led2-on")==0)
			{
				PORTB|=(1<<PB2);
			}
			else if (strcasecmp(msg,"led2-off")==0)
			{
				PORTB&=~(1<<PB2);
			}

			msg[0]=0;//clear msg array data
		_delay_ms(300);

		if(SIM300DeleteMsg(id)==SIM300_OK)//delete the msg
		PORTD^=(1<<PD7);//led to indicate delete is successful
		}
	}

}

All LED indicators work good but my problem is that when I send any text, only PB2 is toggled (doesnt matter what text i send.)

Last Edited: Mon. Dec 4, 2017 - 08:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But strcasecmp() returns 0 when it matches.

Your code looks as if it expects true for a match.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

oh yes!

i corrected the code in my post

the problem is still remaining

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Your code looks as if it expects true for a match.

Either the code above has been edited, or some of the tests do the correct and test if the return from strcasecmp() is zero, e.g.

			if(strcasecmp(msg,"led3-on")==0)

and the others (erroneously) take the return value as the condition of the if-statments, e.g.

else if (strcasecmp(msg,"led2-on"))

 

david.prentice wrote:
But strcasecmp() returns 0 when it matches.

Indeed.

 

As do most (all?) ..cmp() functions.

 

They do so for the reason that you don't only want to have a match/no-match return, but you want to know if one is "less" than the other. E.g. for using when sorting data. The ..cmp() functions returns -1 first parameter is less than second, 0 if they are equal and 1 of first parameter is greater than second.

 

reza_mslm wrote:
only PB2 is toggled (doesnt matter what text i send.)

if sending "led3-on" isn't working then it might be because the message does not contain exactly "led3-on" when received. Could there be a line ending character, e.g. \r or \n or a combination of those two?

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

now none of PB3 and PB2 toggle.

i dont send any additional character

Last Edited: Mon. Dec 4, 2017 - 08:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Show the source of

SIM300ReadMsg()

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
int8_t	SIM300ReadMsg(uint8_t i, char *msg, char *oa)
{
	//Clear pending data in queue
	UFlushBuffer();

	//String for storing the command to be sent
	char cmd[16];

	//Build command string
	sprintf(cmd,"AT+CMGR=%d",i);

	//Send Command
	SIM300Cmd(cmd);

	uint8_t len=SIM300WaitForResponse(1000);

	if(len==0)
		return SIM300_TIMEOUT;

	sim300_buffer[len-1]='\0';

	//Check of SIM NOT Ready error
	if(strcasecmp(sim300_buffer+2,"+CMS ERROR: 517")==0)
	{
		//SIM NOT Ready
		return SIM300_SIM_NOT_READY;
	}

	//MSG Slot Empty
	if(strcasecmp(sim300_buffer+2,"OK")==0)
	{
		return SIM300_MSG_EMPTY;
	}

	//Check if OK
	if(strncasecmp(sim300_buffer+2,"+CMGR:",6)==0)
	{
		char *start,*end;

		//Find the 3rd "
		start=strchr(sim300_buffer,'"');
		start++;

		start=strchr(start,'"');
		start++;

		start=strchr(start,'"');
		start++;

		end=strchr(start,'"');

		*end='\0';

		strcpy(oa,start);
	}

	//Now read the actual msg text
	len=SIM300WaitForResponse(1000);

	if(len==0)
		return SIM300_TIMEOUT;

	sim300_buffer[len-1]='\0';
	strcpy(msg,sim300_buffer+1);//+1 for removing trailing LF of prev line

	return SIM300_OK;
}

 

Attachment(s): 

Last Edited: Mon. Dec 4, 2017 - 09:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

reza_mslm wrote:
i dont send any additional character

If that was re my post, then I wasn't talking about what "you" (i.e. the AVR) is sending.

 

You are having problems interpreting what the SIM module sends to the AVR. Are you sure the SIM module does not send line endings?

 


reza_mslm wrote:
now none of PB3 and PB2 toggle.

We can say nothing about that unless you post the code you have "now".

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"now" means <after i corrected the code as i said in my second post.

 

my code:

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "usart.c"
#include "sim300.c"

int main(void)
{
	DDRB=(1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4);
	DDRD=(1<<PD7);

	uint8_t id,r;

	while(SIM300Init()!=SIM300_OK);//wait for intit

	PORTB|=(1<<PB0);//led to indicate init is done

	while(SIM300GetNetStat()!=SIM300_NW_REGISTERED_HOME);//wait for sim to be registered

	PORTB|=(1<<PB1);//led to indicate sim is registered

	char oa[20];//sender number
	char msg[300];//array to store the message

	while (1)
	{
		while (SIM300WaitForMsg(&id)!=SIM300_OK);//wait for meassge
		PORTB^=(1<<PB4);//toggle pb4 to indicate a message is received
		_delay_ms(300);

		r=SIM300ReadMsg(id,msg,oa);//read the message and store it in msg array

		if(r==SIM300_OK)//if read is successful
		{
			if(strcasecmp(msg,"led3-on")==0)
			{
				PORTB|=(1<<PB3);
			}
			else if (strcasecmp(msg,"led3-off")==0)
			{
				PORTB&=~(1<<PB3);
			}
			else if (strcasecmp(msg,"led2-on")==0)
			{
				PORTB|=(1<<PB2);
			}
			else if (strcasecmp(msg,"led2-off")==0)
			{
				PORTB&=~(1<<PB2);
			}

			msg[0]=0;//clear msg array data
		_delay_ms(300);

		if(SIM300DeleteMsg(id)==SIM300_OK)//delete the msg
		PORTD^=(1<<PD7);//led to indicate delete is successful
		}
	}

}

 

 

 

 

Last Edited: Tue. Dec 5, 2017 - 03:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

usart library is attached.

 

PB0,PB1,PB4 and PD7 toggle as they should but PB2 and PB3 dont.

please help

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

reza_mslm wrote:

#include "usart.c"
#include "sim300.c"

 

Is this actually what you have in the code or is it a typo?

 

If that is the code then that could be causing issues as you are including the C source code instead of the header files. It should be:

#include "usart.h"
#include "sim300.h"

It may not fix all your problems but it may help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The include thing doesn't seem entirely likely to be relevant, if things are building at all it's probably unidiomatic but not breaking anything.

 

What you probably need here is some more insight into what's happening.

 

I note that you have a couple instances of |=, and a couple of ^=, for LED toggles. Probably ought to be using |= to turn on, and &=~ to turn off, so you know which way each thing is setting the LED. An LED being toggled really fast can be invisible.

 

I don't see the declaration of sim300_buffer. I guess what I'd probably do first is, on message receive, set one LED to indicate which of the SIM300 codes you got back (_OK, _MSG_EMPTY, _SIM_NOT_READY, _TIMEOUT), and delay for a little bit so you have time to see the light flash. If you consistently see the light for _OK, then you know you should at least be getting *some* kind of string back. Obviously, if you can get a console you can dump things to, that'll make it a lot easier...
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

no, that is the code.

i have added .h files to my solution.

that is OK and there is no problem.

 

my only problem is what that is said.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the_real_seebs wrote:
I don't see the declaration of sim300_buffer.

it is declared in sim300.c

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the_real_seebs wrote:
What you probably need here is some more insight into what's happening.

Absolutely.

 

The ATMega16 has "Extensive On-chip Debug Support" - so use it!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Fault-seeking is about forming hypotheses about an isolated cause of the problem and the n test those hypotheses. One by one. In a structured manner. Isolated, so that you know what you're testing.

 

Ideas for a list of isolated hypotheses:

  • Something is wrong with how responses from the SIM module is interpreted. (E.g. see my ideas above about the SIM module possibly not sending the exact strings you're thinking it does - e.g. it might add line ending chars". Ways to test: Hook up the SIM to a PC serial port (with a level converter) and use a good terminal software so that you can get "raw" unfiltered/untranslated views of what the SIM module actually sends. Or.. Change your AVR program to test on beginning of SIM message string using strncmp() (rather than the complete message).
  • Something is wrong with how you toggle pins. Start by doing a structured inspection of all your togglings. Make them uniform - i.e. do it the same way everywhere (not ^= in some places and |= in others.
  • Something is wrong, hardware-wise, with some of the port pins. Or with one of the LEDs! Easily tested by swapping a toggle that works to one of the non-working pins.

 

As I said above. Test one of these at a time. Work slowly and structured. Be meticulous with making notes - pen, paper and brain are the prime tools here!

 

This is all standard procedure and way of working when debugging. The Devils is in the details, and in the situations where several things are wrong. "Combinatory bugs" are at least as much hell as are intermittent faults, and require a very structured way of working to get solved. You don't know if your problem is a combination of faults so be structured and prepared from the start!

 

HTH!

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Wed. Dec 6, 2017 - 09:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I assumed it was declared in sim300.c, but since we can't see it, we don't know what type it has, or how much storage it has, or anything else. There's a lot of things here that look like they might need bounds checking, or could be overflowing bounds. I'd check on that, too.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

it is actually attached in #7

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thank you every body

i found the problem by adding a character lcd to my circuit and showing the received message and oa[](sender number).

i found that my message is not received completely in most times. for example when I send "Led3_on" lcd shows: "d3_on" or "_on" etc.

is that problem because i have not attached GSM antenna to the module??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

reza_mslm wrote:
is that problem because i have not attached GSM antenna to the module??

No.

 

Although not having an antenna connected is a Very Bad Idea, the module will either receive the complete message, or nothing at all. The GSM protocols will ensure that it doesn't get partial messages.

 

It must be your code missing characters.

 

EDIT 

 

typo

 

 

See this post for how to monitor your serial communications using two terminals: http://www.avrfreaks.net/comment...

 

And this for a discussion of serial comms debugging tools & techniques: http://www.avrfreaks.net/forum/m...

 

 

 

Last Edited: Fri. Dec 8, 2017 - 09:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The problem is very likely in your usart.c file -  which seems to me to be handling a ring buffer, though in a somewhat "exotic" way making it a hard read (for me). I might review your code in usart.c a bit more later today, but my advice to you is to look in that file first for the problem.

 

This is an excellent case for testing without involving AVRs or Atmel Studio at all. Get your favourite "C for PC" IDE up and write a small test-bench that runs the functions in usart.c. Make extensive use of your favourite IDEs debugger and step through code while debugging. 

 

Another possibility to investigate is the code in sim300.c. It might do bad readouts from the ring buffer. E.g. is that read-out code atomic (non-interruptable)? Since the reception proper is interrupt-driven this is more or less a requirement.

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
This is an excellent case for testing without involving AVRs or Atmel Studio at all. Get your favourite "C for PC" IDE up and write a small test-bench that runs the functions in usart.c. Make extensive use of your favourite IDEs debugger and step through code while debugging. 

+999 !!

 

Also note that the ATMega16 has on-chip debug:

The ATMega16 Datasheet wrote:

• JTAG (IEEE std. 1149.1 Compliant) Interface

– Boundary-scan Capabilities According to the JTAG Standard

– Extensive On-chip Debug Support

– Programming of Flash, EEPROM, Fuses, and Lock Bits through the JTAG Interface

So use it!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Two obvious things. One, you're allocating a 300-byte buffer to use, and that's large enough to be a likely problem on machines with only 2K or so of memory. The other is, you've got a lot of points at which you skip past things (like the strcpy starting from buffer+1) which could be resulting in skipping past some characters.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the_real_seebs wrote:
you've got a lot of points at which you skip past things (like the strcpy starting from buffer+1) which could be resulting in skipping past some characters

 

that is to skip CR or LF characters

 

awneil wrote:
Extensive On-chip Debug Support

 

it requires JTAGICE MKII device and i dont have it (and can't buy it for some reasons)

 

it is noticable (and strange) that oa[] which is sender number is read correctly all of time but msg is not while these both are read with a same manner

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A mega16 is old enough that you can debug with one of the $10 JTAGICE clones from ebay. No need for an expensive device like JTAGICEmkII (or these days probably Atmel-ICE)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I still argue that the code for circular buffer and the whole SIM part of the code is actually not relying on an AVR, or a microcontroller in general. It can be developed and tested in the less "awkward" environment of a IDE targeting any "PC operating system". There, it can be debugged in a controlled manner.

 

This will also have the additional advantage that the code will be clearly modularized.

 

I'd also replace the somewhat "hacky" implementation of the circular buffer with something proven and tested, e.g. Dean Cameras work.

 

I have the code given above in a NetBeans project and might rig it up for testing tomorrow. Or I might not, so don't stay up waiting.. ;-)

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

reza_mslm wrote:
that is to skip CR or LF characters

That may be  the intention - but does it actually work?

 

How have you tested and verified it?

 

JohanEkdahl wrote:
I still argue that the code for circular buffer and the whole SIM part of the code is actually not relying on an AVR, or a microcontroller in general. It can be developed and tested in the less "awkward" environment of a IDE targeting any "PC operating system". There, it can be debugged in a controlled manner.

Agreed.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Obviously the intent is to "skip CR or LF characters". But if you aren't checking what the actual values are, who knows?

 

Basic advice for debugging: If your code is not doing what you think it should be doing, you know that something you believe about your code or its inputs is wrong. So any time you say "well, this must be right, because...", stop and say "have I tested this?"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

the_real_seebs wrote:
So any time you say "well, this must be right, because..." [...]

 

+1

 

Put another way: Assumption is the mother of much evil. The process of debugging is much about removing assumptions and instead establish facts.

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
The process of debugging is much about removing assumptions and instead establish facts.

Indeed.

 

Or, as stated in #16 - also here - it's about forming hypotheses and then testing whether whether they hold up.

 

See also: http://www.ganssle.com/articles/developingagoodbedsidemanner.htm

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

one forgotten note:

the usart,lcd and GSM libraries are written for ATmega32 and sim300

but i use atmega16 and sim808 with no change in the libraries. (I think the AT commands are the same)

 

would this be the problem source?

Last Edited: Sun. Dec 10, 2017 - 07:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

reza_mslm wrote:
I think the AT commands are the same

There's another assumption!

 

What have you done to confirm that they're the same?

 

Likewise with the ATmega32 vs 16 ?

 

However, I'd have thought it most likely that any problems here would result in it not working at all - rather than just missing odd characters?

 

Was the code actually tested on an ATmega32 and sim300 ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Was the code actually tested on an ATmega32 and sim300 ?

 

YES! The libraries are tested in a voting system

http://extremeelectronics.co.in/...

 

when i burn the above voting system Code to my circuit and I SMS (for example) "VOTE D" it is not recognized!(GSM sends Invalid Vote ...) AS "Led3_on" was not in my Code!!

Last Edited: Sun. Dec 10, 2017 - 08:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think buying an atmega32 will not solve the problem:

http://www.atmel.com/Images/doc2...