Code bricks USB on Atmega32u4..

Hi,

I'm using a Atmega32u4 in my own project, but i flashed the Sparkfun Pro Micro (3.3V,8Mhz) bootloader, its similar to the Leonardo, but they removed the 8 second wait.

The most part of the code works without problems and for long cycles. But if i push a button, the USB just stops working, and disappiers from Windows "Device-Manager" as if you would pull the USB Cable.

-> Tried to swap the button, and then the pin, to make sure its not a Hardware Issue
-> Still not worked.
So i added debut texts for Serial.

This is happening.

  • Hold button for a specific time and then release
  • Release event will trigger a function "log_prepare()";
  • Function works, since "Prepare!" and "done!" gets printed
  • After Preparation the function that does something should run and wait for events. This works a small time. The function Runs exactly 951 times by printing "Service Cycle Nr. " 0 to 951. In the last run only "Service Cycl" gets printed. Thats where the USB-Port disappears.

-> When the Service Cycle is running, it doesnt matter if there are events, or button-pusheds, the port gets removed anyway.

Find attached my code, maybe someone can help.
:grin: Sorry, i know the code is a mess, but i'm developing. Sorry for missing libraries...

I hope someone could help me with this, I'm really stuck here...

DOGM_test.ino (16.7 KB)

Update!

The Problem is in the Switch in Case : 1

but i don't know why.

If y remove it,a nd leave case1 emtpy, it works...

You have several series of SWITCH/CASE in your program. Which one are you referring to?

...R

sgt_johnny:
I hope someone could help me with this, 'm really suck here...

Well, I wouldn't go quite that far...

You have multiple case 1's :wink:

The symptoms that you describe seem to point to a memory issue. How much RAM does you sketch use?

Can you provide links to all the libraries that you use (ClickEncoder, dog_7565, NMEAGPS and Timer1) so we don't have to look for them.

1.) "suck" should be "stuck" :slight_smile:

2.) The problem is not about "case : 1", i found out that it still not works, and the "Cycle" runs not always exactly the same time

3.) Find attached the zip with libraries. I have worked since i posted this topic, so this code differs from the first one i posted, but this has to do nothing with the issue

the sketch uses 26443 of 28672 (92%) program space
and it says 963 bytes of dynamic memory.

The function that causes trouble starts on LINE 632

DOGM_test_forum.zip (86.4 KB)

sgt_johnny:
The function that causes trouble starts on LINE 632

Sorry, I'm lazy and your program is much too big to figure out in 5 or 10 minutes.

By the way, line 632 is not part of any SWITCH/CASE so I can't relate it to your Reply #1

And all line 632 does is increment a variable so that is not actually where the problem is. It must be someplace where that variable is used.

This

DOG.string(

makes me wonder if the DOG library uses the String class. That is often responsible for memory corruption.

...R

Oh sorry, the first .ino i posted, the line would be 483!!

on the later .zip file with libraries its line 632 the function "m2_service()" starts, thats the function that causes the problem, since the serial Print "Service Cycle Nr:" gets executed a few times before bricking.

For trying i removed the switch's case 1 (line 645) content, but this DID NOT solve the problem

About DOG.string. I use this in other parts of the code way much and faster - no problem.

Here is the fucntion from the library that executes DOG.String

void dog_7565R::string(byte column, byte page, const byte *font_adress, const char *str)
{
	unsigned int pos_array; 										//Postion of character data in memory array
	byte x, y, column_cnt, width_max;								//temporary column and page adress, couloumn_cnt tand width_max are used to stay inside display area
	byte start_code, last_code, width, page_height, bytes_p_char;	//font information, needed for calculation
	const char *string;

	
	
	start_code 	 = pgm_read_byte(&font_adress[2]);  //get first defined character
	last_code	 = pgm_read_byte(&font_adress[3]);  //get last defined character
	width		 = pgm_read_byte(&font_adress[4]);  //width in pixel of one char
	page_height  = pgm_read_byte(&font_adress[6]);  //page count per char
	bytes_p_char = pgm_read_byte(&font_adress[7]);  //bytes per char
  
  if(type != DOGM132 && page_height + page > 8) //stay inside display area
		page_height = 8 - page;
  else  if(type == DOGM132 && page_height + page > 4)
    page_height = 4 - page;
  
	
	//The string is displayed character after character. If the font has more then one page, 
	//the top page is printed first, then the next page and so on
	for(y = 0; y < page_height; y++)
	{
		position(column, page+y); //set startpositon and page
		column_cnt = column; //store column for display last column check
		string = str;             //temporary pointer to the beginning of the string to print
		digitalWrite(p_a0, HIGH);
		digitalWrite(p_cs, LOW);
		while(*string != 0)
		{	
			if((byte)*string < start_code || (byte)*string > last_code) //make sure data is valid
				string++;
			else
			{							
				//calculate positon of ascii character in font array
				//bytes for header + (ascii - startcode) * bytes per char)
				pos_array = 8 + (unsigned int)(*string++ - start_code) * bytes_p_char;
				pos_array += y*width; //get the dot pattern for the part of the char to print
        
        if(type != DOGM132 && column_cnt + width > 128) //stay inside display area
					width_max = 128-column_cnt;
        else if(type == DOGM132 && column_cnt + width > 132)
           width_max = 132-column_cnt;
				else
					width_max = width;
          
				for(x=0; x < width_max; x++) //print the whole string
				{
					spi_out(pgm_read_byte(&font_adress[pos_array+x]));
					//spi_out(pgm_read_byte(&font_adress[pos_array+x])); //double width font (bold)
				}
			}
		}
		digitalWrite(p_cs, HIGH);
	}
}

sgt_johnny:
Here is the fucntion from the library that executes DOG.String

That does not seem to use the String class.

...R

Update!

I have included a library "MemoryFree" that allows you to display free memory.

If the normal code runs (even with lots of gps traffic) it has alwas "free 1460".

The moment it enters the function "m2_service", the memory is only "free 7".

Interesting is, that not the function steals the ram, it must happen before. I will now try around to find out where exactly

Another weird thing i found out;

I added a Serial.print() (Status+millis() when the GPS gets a new message from Serial1

The Response looks like this:

STATUS10221
STATUS11220
STATUS12220
STATUS13221
STATUS14221
STATUS15220

it looks like the gps gets a new message each Second. So if we looks at the Status, the next message should be arrive at around "16220" right?

So i added to my m2_service(), a Serial.print with Service run + millis().
Like i guessed, the code stops exactly at 16220...

Service run16218
Service run16218
Service run16220
Service run

Its very interesting, that the code even breaks when there is no SERIAL Stuff in the Service...
I removed all Serial.print() from the Service and its pre-functions, but still it breaks

Interesting fact is, that when i use //GPSLoop() or //m2_service(), so they can not run, it works perfectly when one of them is disabled.

Very weird.

I also added a function to the display to see the ram even if the serial port is gone, and its always around 1400, it never breaks down alot...

Some of your char array are one character short. Do not forget the trailing null.