How To Process a String of Several USART Commands

Hi, I'm currently making a mock vending machine. The way it receives change is through serial commands entered on the serial monitor. The commands +0.10, +0.25, and +1.00 increment the global money total in the machine, the command +0.00 resets the total, essentially giving your change back. Currently a single command at a time can be processed. I want to be able to process several at a time. The way I am differentiating between separate commands in the string of commands is by the plus symbol.

For instance, if I type into the serial monitor ( +1.00+0.25+0.25+0.10 ), the global money total should be $1.60. The way I have it set up now, it can only handle a string of two commands and only even process the last command, adding just $0.25. 3 commands at once and more is a total failure.

Here is all my relevant code from when a command is received until the last step of processing it:

Actual multiDeposit() function that I'm having trouble with:

Serial monitor when entering commands:

For something like "+1.00+0.25+0.25+0.10", I would use maybe strtok() to filter out the numbers. Keep the same IF statement to check if it is a '+' or '-', and then just use that function to get the numbers, to either add or subtract them from the total.

Did you really just post a screenshot of your code instead of posting your actual code that can be copied and manipulated?

Sorry, I thought it would be easier to read/

/**********************************************************************************
* Checks for a USART command
*********************************************************************************/
void CommandCheck_Routine()
{
	if (BytesNbuffer() > 0 )
	{
		if ( Get_Byte(0) == '+' )
		{
			MoneyCommand(); //if it starts with a + symbol, it's a money deposit
		}
		else
		{
			DebugCommand();
		}
	}
}

/**********************************************************************************
* Checks for money deposited by serial port comman
*********************************************************************************/
void MoneyCommand()
{
	char* command = checkfor_Instruction();

	snprintf((char *)string, SERIAL_MESSAGE, "\n\n  %s   ", command);
	mySerialWrite(string);

	MoneyDeposited( command );	ShowMoney();
}

/**********************************************************************************
* Actions for Money being Deposited
*********************************************************************************/
void MoneyDeposited(char* command)	//for single commands at a time
{
	if ( strcmp(command, "+0.00" ) == 0) 
	{
		msnprint(8);	ShowMoney();	msnprint(5);	g_dollars = 0;	g_moneyTotal = 0;
	}
	else
	{
		msnprint(5);  // A function to access PROGMEM lines and transmit them via USART
		if ( strcmp(command, "+0.10" ) == 0)
		{
			printhis(" $0.10	");		g_moneyTotal += 10;
		}
		else if ( strcmp(command, "+0.25" ) == 0) 
		{
			printhis(" $0.25	");		g_moneyTotal += 25;
		}
		else if ( strcmp(command, "+1.00" ) == 0) 
		{
			printhis(" $1.00	");		g_moneyTotal += 100;
		}
		else
		{
			g_moneyTotal += multiDeposit( command ); //if not a single command
		}	//hand it over to the multideposit function
	}
}

/**********************************************************************************
* Show's current amount of money
*********************************************************************************/
void ShowMoney()
{
	g_cents = g_moneyTotal;		g_dollars = 0;

	while (g_cents >= 100)
	{
		g_dollars += 1;	g_cents -= 100;
	}

	snprintf((char *)string, SERIAL_MESSAGE, " Total: $%d.%.2d ", g_dollars, g_cents);
	mySerialWrite(string);
}
uint16_t multiDeposit( char* src1)
{
	uint8_t string[SERIAL_MESSAGE];
	uint16_t deposit = 0;
	uint8_t length = strlen( src1 );  //length of command string

	// char dst1[6]; //working
	char dst1[length];
	void *c;

	c = memccpy( dst1 , src1 , NULL , length );
	//c = memcpy(dst1, src1, length);
	//c = memcpy(dst1, &src1[1], 4); //working

	//For some reason, without this snprintf here.  Thigns don't work.
	snprintf((char *)string, SERIAL_MESSAGE, "  %d   ", length);
	//mySerialWrite(string);
	
	char* pointchar;
	char character;

	pointchar = strchr(dst1, '+'); //looks for + signs
	uint8_t index; 
	char dst2[6];

	//These while loops are my attempt to get it to do more than one command at a time
	while ( pointchar != NULL )
	{

		while (( pointchar != NULL ) )
		{
			index = (pointchar - dst1) ;
			snprintf((char *)string, SERIAL_MESSAGE, "\n found @ %d   \n", index);
			mySerialWrite(string);

			pointchar = strchr ( pointchar+1, '+');	
			character = dst1[index+1];	
		}

		c = memcpy(dst2, &dst1[index+1] , 4);
		deposit = SingleDeposit(dst2);

		index = (pointchar - dst1) ;
		pointchar = strchr ( pointchar+1, '+');	
	}

	return deposit;
}

//These change amounts are just temporary until I can get it all figured out
uint16_t SingleDeposit(char* dstA)
{
	uint16_t deposit = 0;

		if ( strcmp(dstA, "0.50" ) == 0)
		{
			printhis(" $0.50	");		deposit += 50;
		}
		else if ( strcmp(dstA, "0.05" ) == 0) 
		{
			printhis(" $0.05	");		deposit += 5;
		}
		else if ( strcmp(dstA, "0.01" ) == 0) 
		{
			printhis(" $0.01	");		deposit += 1;
		}
		else
		{
			msnprint(6);
			uint8_t string[SERIAL_MESSAGE];
			snprintf((char *)string, SERIAL_MESSAGE, "\n\n Entered %s   ", dstA);
			mySerialWrite(string);
		}
	
	return deposit;
}

Post your full code.

Could I just post the visual studio zip file? There's a lot of code in a lot of different source files.

Here is the full visual studio 2012 project files.

https://dl.dropboxusercontent.com/u/106878694/VendingMachine.zip

The code's a little bit sloppy yet, I want to get it to work before I optimize everything.

Not everyone has visual studio, just make it a .txt file.

I just got home and finally got the chance to try the strtok() function. Works Great!!! I didn't know it existed, thank you for this.

The final code for that makes this work:

/**********************************************************************************
* Checks for money deposited by serial port comman
*********************************************************************************/
void MoneyCommand()
{
	char* command = checkfor_Instruction();
	multiDeposit( command );		ShowMoney();
}

/**********************************************************************************
* Multiple Deposits with sing string of commands
*********************************************************************************/
void multiDeposit( char* src1)
{
	uint16_t deposit = 0;
	uint8_t string[SERIAL_MESSAGE];
	char str[SERIAL_MESSAGE];
	char * pch;

	snprintf((char *)str, SERIAL_MESSAGE, "%s", src1);

	snprintf((char *)string, SERIAL_MESSAGE, "\n\n \"%s\"",str);
	mySerialWrite(string);

	pch = strtok (str," ,-+");
	while (pch != NULL)
	{
		SingleDeposit(pch);
		pch = strtok (NULL, " ,-+");
	}
}

/**********************************************************************************
* Single Deposit Commands entered here
*********************************************************************************/
void SingleDeposit(char* command)
{
	uint16_t deposit = 0;

	if ( strcmp(command, "0.00" ) == 0) 
	{
		msnprint(8);	ShowMoney();	g_dollars = 0;	g_moneyTotal = 0;
	}
	else
	{
		msnprint(5);  
		if ( strcmp(command, "0.10" ) == 0)
		{
			printhis(" $0.10	");		g_moneyTotal += 10;
		}
		else if ( strcmp(command, "0.25" ) == 0) 
		{
			printhis(" $0.25	");		g_moneyTotal += 25;
		}
		else if ( strcmp(command, "1.00" ) == 0) 
		{
			printhis(" $1.00	");		g_moneyTotal += 100;
		}
		else
		{
			msnprint(6);
			uint8_t string[SERIAL_MESSAGE];
			snprintf((char *)string, SERIAL_MESSAGE, "  %s   ", command);
			mySerialWrite(string);
		}
	}
}


/**********************************************************************************
* Show's current amount of money
*********************************************************************************/
void ShowMoney()
{
	g_cents = g_moneyTotal;		g_dollars = 0;

	while (g_cents >= 100)
	{
		g_dollars += 1;	g_cents -= 100;
	}

	snprintf((char *)string, SERIAL_MESSAGE, " Total: $%d.%.2d ", g_dollars, g_cents);
	mySerialWrite(string);
}

Glad it works.