More efficient code - maybe

Go To Last Post
82 posts / 0 new

Pages

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

Kartman wrote:

 

You didn't think about this too carefully did you? No pencil and paper?? And you wonder why things don't work for you. 

You haven't also taken on board the various comments regarding code clarity - no if{}. You also violate the defacto practice of putting constants in upper case - somehow normal variables become upper case in your code.

The secret to writing good comments in your code is not to state the obvious. The comments are to describe the intent of the code, they should tell a story. I've given you some good hints and references in the past that you've clearly ignored.

OK, today I did a little improvement, I got rid of the shifter and kept the other initialized variable of 0xFF.

 

void DH11_read(uint8_t *bits_timing)
{
	uint8_t TMR_TEMP=0,DECODE_TEMP=0;int8_t j,i;
	DDRB = 0xFF;										// Pin0 output
	PORTB &= ~(1<<PB0);									// pull PB0 LOW	for 18ms
	_delay_ms(18);
	PORTB |= (1<<PB0);									// pull it HIGH again
	DDRB = 0xFE;
	
	while((PINB & (1<<PINB0)));							// leading HIGH pulse waiting for response
	while(!(PINB & (1<<PINB0)));						// 1st response 80us LOW
	while((PINB & (1<<PINB0)));							// 2nd response 80us HIGH
	
	for (i=0;i<5;i++)									// 5 bytes for 40-bits DH11 data
    {	uint8_t shifter=0x80,DH11_code =0xff;			// local vars
		for (j=7;j>=0;j--)								// 8-bits loop
		{
			while(!(PINB & (1<<PINB0)));                // wait for 0 leading bit
			TCNT0=0;									// clear the timer0
			while(PINB & (1<<PINB0));                   // high bit 0 or 1 
			TMR_TEMP = TMR0_MSK;						// read timer0 mask
			if (TMR_TEMP < 35 && TMR_TEMP > 20)			// 0 bit length is 26-28us
				DH11_code &= ~(1<<(j));					// set 0-bit
		}
		bits_timing[i] = DH11_code;						// copy the result to the array
    }
}

 

But, setting and shifting the same variable didn't work until now, I'm still trying. But this is my current update.

 

void DH11_read(uint8_t *bits_timing)
{
	uint8_t TMR_TEMP=0,DECODE_TEMP=0;int8_t j,i;
	DDRB = 0xFF;										// Pin0 output
	PORTB &= ~(1<<PB0);									// pull PB0 LOW	for 18ms
	_delay_ms(18);
	PORTB |= (1<<PB0);									// pull it HIGH again
	DDRB = 0xFE;
	
	while((PINB & (1<<PINB0)));							// leading HIGH pulse waiting for response
	while(!(PINB & (1<<PINB0)));						// 1st response 80us LOW
	while((PINB & (1<<PINB0)));							// 2nd response 80us HIGH
	
	for (i=0;i<5;i++)									// 5 bytes for 40-bits DH11 data
    {	uint8_t DH11_code =0;							// local vars
		for (j=7;j>=0;j--)								// 8-bits loop
		{
			while(!(PINB & (1<<PINB0)));                // wait for 0 leading bit
			TCNT0=0;									// clear the timer0
			while(PINB & (1<<PINB0));                   // high bit 0 or 1 
			TMR_TEMP = TMR0_MSK;						// read timer0 mask
			if (TMR_TEMP < 75 && TMR_TEMP > 65)			// 0 bit length is 26-28us
			{
				DH11_code |= 1;	
				DH11_code<<=1;
			}
			else
				DH11_code<<=1;
		}
		bits_timing[i] = DH11_code;						// copy the result to the array
    }
}

 

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

I give the answer to you on a plate and still you manage to screw it up! 

			DH11_code<<=1;

			if ((TMR_TEMP < 75) && (TMR_TEMP > 65))			// 0 bit length is 26-28us
			{
				DH11_code |= 1;	
			}

Here is the answer again. Note the use of () and {}. 

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

sparrow2 wrote:

ISR "But where do I wait?" you don't you trigger on the edges of the port pin, and most chips has a timer function for just what you want (only count when a port pin is either high or low 

 

What you mean by this statement? My understanding:

Of course I don't trigger the edges, it's the response of the sensor, receiving data on the input pin. So, also of course most chips have timers, and that's how I'm applying them in my code. So what I'm doing is that I'm only using a timer and an input pin, but if I want to implement ISR for this function, could use the same procedure? The interrupt of course must be set to pin trigger, but the problem is how to skip the leading 0 bit? It's a transition from HIGH/LOW where the data bits are transitions from LOW/HIGH.

 

Can I use while(!(PINB & (1<<PINB0))); to skip the leading 0 bits in the ISR, and then use the pin interrupt to measure the LOW/HIGH transition? I think yes,

 

EICRA – External Interrupt Control Register A, has pin interrupt settings for INT0,1:

ISC01 ISC00: Setting both bits to 1 gives >> The rising edge of INT0 generates an interrupt request.

 

But I don't know if that settings works as I think.     

 

for an uint  /2 is the the same as shift right (same as in decimal /10) and *2 is a left shift.

I learned that / and * are better than shifting for code efficiency. But you mentioned only uint that works, so I guess by that it doesn't work for signed vars?

 

pointer array:

if you can live with a static array, you don't need to pass anything. And you can still use a pointer inside the function.

How? What is "static array"? How do I "not need to pass anything"? "And you can still use a pointer inside the function." That's really interesting!

 

What do I do is:

1. Declare an array in main application program.

2. Declare and define a function which receives a pointer.

3. Pass the array to the function.

4. Manipulate the array indexing inside the function as pointer references.

 

 

inline:

if a function only is used once the compiler can save the call by placeing the function where it's used if it's inline.

Not quite getting the idea you declared, I learned that inline functions for most often used and small functions.

 

Do you mean, that I don't have to declare and define the function, and if it's used once, then I declare it as an inline function in the header file, and define it in the source file, but because it's an inline function it doesn't take a space in program memory, and called like a macro ... I'm understanding until this point. 

 

I did not compile your code but it looks like a ASM version take about 40 instructions (80 byte), (perhaps a tad more if some of the IO's is outside the IN/OUT range.)

so even if C use more it's still a small rutine in the hole picture.  

This program of LCD_I2C and sensor libraries. The program in Arduino IDE compiles 134 bytes without anything, including everything compiles 3320 bytes. So yeah C takes a lot of space for relatively small libraries.

 

Last Edited: Fri. Aug 24, 2018 - 04:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

True, there's no need - but most professionals will recommend that you use them anyhow - they (help to) prevent several common errors ...

Completely agree with you.

 

sparrow2 wrote:

try to be a bit serious, OP want to make the code small, so unless the function only is called once it should be obvious (for all other than you) that the code will be bigger if the code is called from different places.

unless it's a relative small function with many parameters the code actually could be smaller.(but not the case here)

And unless the function is static the compiler don't know how many time the function is called and will only make it inline if a function is small (not the case here).  

You comment is difficult for me to understand, I go over and over your comment to understand but it looks like you specify further aspects of programming that maybe I'm not at that level yet :) It's OK but I want to clear my level of skill in C.

 

And also other professional members here who told me things that looked complicated to me at first, but after some time, some aspects got more understandable and I could really imagine that point.

 

I still want to understand this comment, here's my idea:

1. Yes, I want to get a smaller code, for my first sketches going to smaller ones means that I'm learning something about code optimization.

2. How "unless the function only is called once it should be obvious (for all other than you) that the code will be bigger if the code is called from different places."? I tried to duplicate the function in my Arduino IDE but the program          size after compilation is not changed much, it's around 3320 bytes, adding duplicated functions actually got less code size; like, 3308 bytes, so this is also got me more confused.

3. The after points are not clear, as I mentioned maybe I'm not in that level yet:

"

unless it's a relative small function with many parameters the code actually could be smaller.(but not the case here)

And unless the function is static the compiler don't know how many time the function is called and will only make it inline if a function is small (not the case here)."

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

Kartman wrote:

I give the answer to you on a plate and still you manage to screw it up! 

			DH11_code<<=1;

			if ((TMR_TEMP < 75) && (TMR_TEMP > 65))			// 0 bit length is 26-28us
			{
				DH11_code |= 1;	
			}

Here is the answer again. Note the use of () and {}. 

It worked, but you know after compiling and running the code I still don't get your method! Why shift then test the bit? And also there's no "else".

 

void DH11_read(uint8_t *bits_timing)
{
	uint8_t TMR_TEMP=0,DECODE_TEMP=0;int8_t j,i;
	DDRB = 0xFF;										// Pin0 output
	PORTB &= ~(1<<PB0);									// pull PB0 LOW	for 18ms
	_delay_ms(18);
	PORTB |= (1<<PB0);									// pull it HIGH again
	DDRB = 0xFE;
	
	while((PINB & (1<<PINB0)));							// leading HIGH pulse waiting for response
	while(!(PINB & (1<<PINB0)));						// 1st response 80us LOW
	while((PINB & (1<<PINB0)));							// 2nd response 80us HIGH
	
	for (i=0;i<5;i++)									// 5 bytes for 40-bits DH11 data
    {	uint8_t DH11_code =0;							// local vars
		for (j=7;j>=0;j--)								// 8-bits loop
		{
			while(!(PINB & (1<<PINB0)));                // wait for 0 leading bit
			TCNT0=0;									// clear the timer0
			while(PINB & (1<<PINB0));                   // high bit 0 or 1 
			TMR_TEMP = TMR0_MSK;						// read timer0 mask
			DH11_code<<=1;
			if ((TMR_TEMP < 75) && (TMR_TEMP > 65))			// 0 bit length is 26-28us
			{
				DH11_code |= 1;	
			}
		}
		bits_timing[i] = DH11_code;						// copy the result to the array
    }
}

 

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

wolfrose wrote:
also there's no "else".

Why would it need an 'else' ?

 

What would need to be done in an 'else' ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wolfrose wrote:
It worked, but you know after compiling and running the code I still don't get your method! Why shift then test the bit? And also there's no "else".

 

There is no else because bits can only be one or zero, I already told you that in #5. When you do this shift:

DH11_code<<=1;

bit 0 becomes zero, so now you only need to test for ones, because if the bit is not one, then it must be zero and you don't need to do anything else in that case.

 

You only need an else if you want to check for values that are neither one nor zero, to generate an error.

 

uint8_t DH11_code =0;							// local vars
        for (j=7;j>=0;j--)								// 8-bits loop
        {
            while(!(PINB & (1<<PINB0)));                // wait for 0 leading bit
            TCNT0=0;									// clear the timer0
            while(PINB & (1<<PINB0));                   // high bit 0 or 1 
            TMR_TEMP = TMR0_MSK;						// read timer0 mask
            DH11_code<<=1;
            if ((TMR_TEMP < 75) && (TMR_TEMP > 65))			// valid 1 bit length is 66-74us
            {
                DH11_code |= 1;	
            } else if ( !(TMR_TEMP < 35 && TMR_TEMP > 20) ) // valid 0 bit length is 21-34us
            {
                // error, bit was not valid
            }
                
        }
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You seem to happy to skip fundamental knowlege and waste our time by going around in circles.

DH11_code<<=1;
//or long hand
DH11_code = DH11_code <<1; //shift left 1 bit

 

what does this do?

 

before 0b11011111 after 0x10111110

before 0b10111110 after 0x01111100

before 0b01111100 after 0x11111000

and so on. Put simply, it shifts the bits left by 1 bit, shifting in a 0

 

DH11_code |= 1;
//or long hand
DH11_code = DH11_code | 1;

what does this do?

 

before 0b10101100 after 0b10101101 it simply sets bit 0

 

It only takes a few minutes to sit down with a pen and paper and write down the combined sequences. Why do the shift , then the 'or' vs doing the 'or' then the shift? Pen and paper will show you.

If you don't know your binary shifts,rotates,ors,ands,xors etc by now, stop and learn.

Last Edited: Fri. Aug 24, 2018 - 10:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

wolfrose wrote:
also there's no "else".

Why would it need an 'else' ?

 

What would need to be done in an 'else' ?

Yes yes you're right there's nothing else to be done other than setting bits to one, also the variable is initialized to 0 at first place.

 

Kartman wrote:
You seem to happy to skip fundamental knowlege and waste our time by going around in circles.

I'm sorry, maybe I didn't express my question more clearly.

 

My question is why you shift then you test the bit? My question is about the arrangement of the instructions.

All the rest of you explanation in your last post is understood, I know what happen when I do left or right shit and using the combined logics instead of the long hand methods.

 

My confusion is that at the start of the for loop, it's an 8-bits loop, so first of all I'm in the first loop testing the first MSB, then after testing the bit I should shift the new data. Then the 2nd loop is for bit1 and so on until the last bit ... or wait a minute, yes after testing and setting the last bit, there shouldn't be any other shifting process! You're right.

 

For the last bit it's clear to me, but for the first bit I thought it's skipping the process of setting the first MSB. But you first shift, which is the correct way, but I want to understand why I must shift first.

Update:

That was my confusion, now I understand it more:

1. First you shift, is that it's not affecting anything to first shift, it's like a dummy bit.

2. Then the test is actually for the 1st MSB << Sorry just got that now :)

3. Then I get out of the 1st loop, the 2nd loop is actually shifting the 1st MSB and setting the 2nd bit!

4. And so on, the 3rd loop is shifting the 2nd bit and setting the 3rd.

5. Last loop (where i=0) shifting 6th bit and setting the 7th bit.

 

Thank you so much it's really a smart way for setting bits without going with the multiple shifts; like, var |= (1<<bit); or var &= ~(1<<bit); 

Last Edited: Sat. Aug 25, 2018 - 03:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I’d say it is the ‘classical’ way of doing it. It translates into assembler efficiently. Doing it any other way probably suggeststhe programmer doesn’t understand microprocessors very well.

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

Kartman wrote:
It only takes a few minutes to sit down with a pen and paper and write down the combined sequences.

Absolutely!

 

This seems so obvious, and is so often suggested here - why does nobody seem to thing of it?

 

Even if you don't have a pencil and/or paper, or are allergic to such old-school tools, you can do the same in a simulator.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Now with that in mind I think you have to reread the thread because then there are a lot of comments that make more sense now !

 

If you want to do more C programming you really need to know more about the HW you use.

Learn how to do bit manipulation for C what does & | ~ ^ actually do. 2's complement etc.

Learn code standards for C style (google has one, I don't 100% agree but the main thing is that you follow something! you still have wrong use a capital letters etc. )

If you want to make a lib things like the range numbers needs to follow F_CPU etc. (so the code still works at a different speed).

 

And this code should live inside a ISR with no waits, but a state machine that handle the different edges.

 

  

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

I just had a look at the DH11 sensor, and I you not do any absolute compares but just :

if it low longer than high it's a 0 else it's a 1.

That way you don't need to know your own speed (make sure that timer don't overflow :) ).

 

And I guess in many cases it's ok to stay inside the function while we receive the 40 bits, but the 18 ms should be started somewhere else, and this routine should start by setting the data line as input, and go from there.   

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

sparrow2 wrote:

If you want to do more C programming you really need to know more about the HW you use.

Yes, but I can't learn all the MCU hardware at once! I learn things as I go through specific projects or experiments. So my plan is to get more developed projects everytime. My goal is to work and program TFT screens with touch features and also develop drones :)

 

Learn how to do bit manipulation for C what does & | ~ ^ actually do. 2's complement etc.

The first 3 operators I work with them a lot, But ^ and 2's complement less to never because I didn't face a project where I need to use them.

 

And I don't work with more professional techniques I find in some codes I download or browse online, my methods are more on the basics approach. But I learn some skills here and there, which I consider more skillful and optimized.

 

Learn code standards for C style (google has one, I don't 100% agree but the main thing is that you follow something! you still have wrong use a capital letters etc. )

For some of my projects, I did some to most of the code functions' results on codeblocks to get the C results without uploading to the chip multiple times to solve a problem.

 

I have many functions I did on CodeBlocks, I can show you some :)

 

For example, I looked for the array set for the dot matrix LED module which receive 8 bytes for each character or symbol. Which is this one:

Related image

And, I found the set of array, which is this one:

uint8_t font8x8_basic[760] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // U+0020 (space)
     0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,   // U+0021 (!)
     0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // U+0022 (")
     0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00,   // U+0023 (#)
     0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00,   // U+0024 ($)
     0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00,   // U+0025 (%)
     0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00,   // U+0026 (&)

1. I wanted to develop a function to enter a string to a function and convert each character in the string in a set of 8 bytes, how to do that? How to call each row of 8 bytes to the specific character in the string?

 

2. I somehow found similar array on arduino code for the same module, and has numbers on the side of the array, I didn't know how to use those numbers, the array on this site:

https://www.brainy-bits.com/scroll-text-using-the-max7219-led-dot-matrix/

 

3. I tried to learn that way of calling each row, but couldn't find someone who can tell me, maybe one told me but I couldn't understand, so I thought to find a similar way to call the characters.

4. I thought why not to call them by the set of ASCII set, so I printed them by codeblock and copied them.

5. Now I have to append each character in the beginning of each row, so it's now the address for that row.

6. I developed a function on CodeBlocks to append each byte of the ASCII array which is 95 bytes into the 8x8 ASCII array which is 760 bytes >> 760 / 95 = 8 bytes for each row. And the output is stored in 855 bytes array.

 

This is the function:

/** The goal is to add a new column to the array of 8 columns
So, the formula would be ((total_bytes/no._of_columns)+total_bytes)
 ((760/8)+760)=95+760=855 */

///////////////////////////////////////////////////////////////////////////////////
				/*example for appending bytes in 8-bytes packets*/
			  /*single dimention array for 8x8 dot matrix project*/
///////////////////////////////////////////////////////////////////////////////////


void append_element(uint8_t *op_arr, uint16_t ar_op_sz, uint8_t *in_arr, uint16_t ar_ip_sz, uint8_t append_pos)
{
    printf("before\n");					// print array before appending
    for (l=0;l<855;l++)
    {
        printf("0x%.2x\t",op_arr[l]);
        if (l%8==7)printf("\n");
    }printf("\n");

    for (l=0;l<95;l++)					// 20 is no. of input bytes
    {
        for (im=855;im>=l*9;im--)
            op_arr[im+1]=op_arr[im];			// spearating process
            op_arr[l*9]=in_arr[l];				// 1st element of every 8 bytes inintialized to 20
    }

    printf("after\n");					// print final example with the new data and appending of array
    for (l=0;l<855;l++)
    {
        printf("0x%.2x, ",op_arr[l]);
        if (l%9==8)printf("\n");
    }
}

///////////////////////////////////////////////////////////////////////////////////
						/*more optimized append function*/
///////////////////////////////////////////////////////////////////////////////////

void append_element(uint8_t *op_arr, uint16_t ar_op_sz, uint8_t *in_arr, uint16_t ar_ip_sz)
{
    for (l=0;l<95;l++)					// 20 is no. of input bytes
    {
        for (im=855;im>=l*9;im--)
            op_arr[im+1]=op_arr[im];			// spearating process
            op_arr[l*9]=in_arr[l];				// 1st element of every 8 bytes inintialized to 20
    }

	// print final example with the new data and appending of array
    for (l=0;l<855;l++)
    {
        printf("0x%.2x, ",op_arr[l]);
        if (l%9==8)printf("  \"//" "%c\n",(l/9)+32);
    }
}

7. The original array >> didn't post all the array because it's long.

uint8_t font8x8_basic[760] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // U+0020 (space)
     0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,   // U+0021 (!)
     0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // U+0022 (")
     0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00,   // U+0023 (#)
     0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00,   // U+0024 ($)
     0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00,   // U+0025 (%)

8. I actually found a problem that the bits are flipped, so I had to develop a function to mirror the bits of each byte. I posted a thread on one of the C forums and found the solution:

///////////////////////////////////////////////////////////////////
/*functon to XOR the unsymmetric bits and skip the symmetric ones*/
///////////////////////////////////////////////////////////////////

uint8_t mirror_bits(uint8_t var)
{
    if ((var & 0x80)&&(!(var & 0x01)) || (!(var & 0x80)&&(var & 0x01)))var ^= 0x81;
    if ((var & 0x40)&&(!(var & 0x02)) || (!(var & 0x40)&&(var & 0x02)))var ^= 0x42;
    if ((var & 0x20)&&(!(var & 0x04)) || (!(var & 0x20)&&(var & 0x04)))var ^= 0x24;
    if ((var & 0x10)&&(!(var & 0x08)) || (!(var & 0x10)&&(var & 0x08)))var ^= 0x18;
    return var;
}


///////////////////////////////////////////////////////////////////
						/*more optimized one*/
///////////////////////////////////////////////////////////////////

uint8_t mirror_bits(uint8_t var)
{
    if ((var & 0x81) && (var != 0x81))var ^= 0x81;
    if ((var & 0x42) && (var != 0x42))var ^= 0x42;
    if ((var & 0x24) && (var != 0x24))var ^= 0x24;
    if ((var & 0x18) && (var != 0x18))var ^= 0x18;
    return var;
}

///////////////////////////////////////////////////////////////////
				  /*call function to mirror bits*/
///////////////////////////////////////////////////////////////////

uint16_t i;
for (i=0;i<760;i++)
array[i] = mirror_bits(array[i]);
for (i=0; i<760; i++)
{
    printf("0x%.2x, ",new_ascii[i]);
    if (i%8==7)printf("  \//" "%c\n",(i/8)+32);
}

9. The array after mirroring the bits:

uint8_t new_ascii[760]={
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
	0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00,   //"!
	0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //"
	0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,   //#
	0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00,   //$
	0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,   //%
	0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00,   //&

 

10. Finally the output array after mirroring the bits and appending the ASCII bytes:

uint8_t new_ascii[855]={
    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // space
    0x21, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00,   //>!
    0x22, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //"
    0x23, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,   //#
    0x24, 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00,   //$
    0x25, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,   //%

11. The function I developed to print characters and symbols on the 8x8 dot matrix module and shift the data:

void shift_letters(void)
{
    uint8_t offset=8, buf_size=40;
    uint8_t shift_buffer[buf_size],bit_mask[buf_size];

    for (i=0;i<buf_size;i++)
    {
        shift_buffer[i] = 0;                // initialize array to zero
        bit_mask[i] = 0;
    }
    s=0;
    for (l=0;l<95;l++)
    {
        for (u=0;u<8;u++)
        shift_buffer[u]=new_ascii[s++];

        for (p=0;p<8;p++)
        {
            for (i=0;i<no_device;i++)                                    // sending the data to all the devices **/
            {
                for (row=1;row<9;row++)                                  // for 8 matrix rows
                {
                    SPI_TX_m(data = (row<<8) | (shift_buffer[(8*(i+1))+(row-1)]),i);
                }
                _delay_ms(30);
            }                                                           // after 64-byte then zero 0 counter :)
			for (h=0;h<buf_size;h++)                                      // shift all array content +8 bytes offset
			{
				if (shift_buffer[h] & 0x80)                         // test MSB if set
				{
					if ((h+8)>buf_size)continue;
					bit_mask[h+8]|=0x01;
				}
			}
			for (k=0;k<buf_size;k++)                                      // shift every byte
			shift_buffer[k]<<=1;
			for (k=0;k<buf_size;k++)                                      // copy the carried bit to the parallel byte
			shift_buffer[k]|=bit_mask[k];
			for (k=0;k<buf_size;k++)                                      // clear bit_mask content for the next test
			bit_mask[k]=0;
        }
    }
}

 

If you want to make a lib things like the range numbers needs to follow F_CPU etc. (so the code still works at a different speed).

Yes, I understand that, but now I work with Arduino which has a constant speed at 16MHz.

 

And this code should live inside a ISR with no waits, but a state machine that handle the different edges.

  You mean the fast good code without delays, should work inside ISR? Yes, that's my goal.

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

the code looks way to complicated. My brain near exploded. divide it up into separate functions. The basic rule is: one function, does one thing - properly. Also your code layout makes it even harder to read. I've mentioned this before, but you don't seem to understand the implication or the importance of it. Programming is two challenges - writing code so that the computer does what you want and writing code that a human can understand simply. If the human can't understand the code, then more defects are likely.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
    for (i=0;i<buf_size;i++)
    {
        shift_buffer[i] = 0;                // initialize array to zero
        bit_mask[i] = 0;
    }

memset() !

        for (u=0;u<8;u++)
        shift_buffer[u]=new_ascii[s++];

memcpy() !

                  SPI_TX_m(data = (row<<8) | (shift_buffer[(8*(i+1))+(row-1)]),i);

I'm with Kartman - my head just exploded too!

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

wolfrose wrote:

And, I found the set of array, which is this one:

uint8_t font8x8_basic[760] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // U+0020 (space)
     0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,   // U+0021 (!)
     0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // U+0022 (")
     0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00,   // U+0023 (#)
     0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00,   // U+0024 ($)
     0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00,   // U+0025 (%)
     0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00,   // U+0026 (&)

1. I wanted to develop a function to enter a string to a function and convert each character in the string in a set of 8 bytes, how to do that? How to call each row of 8 bytes to the specific character in the string?

 

I would use a 95x8 bidimensional array instead of a linear array of 760, it might make the code simpler.

 

I don't understand why do you want to prepend redundant information to the array.

uint8_t new_ascii[855]={
    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // space
    0x21, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00,   //>!
    0x22, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //"
    0x23, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,   //#
    0x24, 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00,   //$
    0x25, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,   //%

If you had a 2D array, you could just add 0x20 to the first index to get those values.

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

Kartman wrote:

the code looks way to complicated. My brain near exploded. divide it up into separate functions. The basic rule is: one function, does one thing - properly. Also your code layout makes it even harder to read. I've mentioned this before, but you don't seem to understand the implication or the importance of it. Programming is two challenges - writing code so that the computer does what you want and writing code that a human can understand simply. If the human can't understand the code, then more defects are likely.

That was a series of development of functions to get the results of shifting chars on the 8x8 dot matrix, it was also a challenge as I'm a beginner, because I had to get myself into these details even if it looks hard for you. Even to me now, but I have to look into it over again to remember what each line do :) But I was so happy I did it and feel that I have some control and can do something.

 

Of course didn't do these functions to be readable for other people, but I can get into it if you're interested and write comments, and start from the goal of the code, and the challenges I faced and what I did to solve those problems.

 

clawson wrote:

    for (i=0;i<buf_size;i++)
    {
        shift_buffer[i] = 0;                // initialize array to zero
        bit_mask[i] = 0;
    }

memset() !

        for (u=0;u<8;u++)
        shift_buffer[u]=new_ascii[s++];

memcpy() !

                  SPI_TX_m(data = (row<<8) | (shift_buffer[(8*(i+1))+(row-1)]),i);

I'm with Kartman - my head just exploded too!

 

You're right, but I didn't think of them. These functions are in the standard C library for AVR-GCC, they're really helpful I used itoa and sprintf recently to convert integers to array so I can print them on LCD1602 module.

 

Also, 

  SPI_TX_m(data = (row<<8) | (shift_buffer[(8*(i+1))+(row-1)]),i);

This is because SPI_TX_m sends 16-bits, (row<<8) for the row of the MAX7219 and (shift_buffer[(8*(i+1))+(row-1)]) for the data to send with the shifting effect. shift_buffer is an array just to get data of the original array put them into this array and shift them for all the 8 columns of the 8x8 dot matrix.

 

 

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

El Tangas wrote:

 

I would use a 95x8 bidimensional array instead of a linear array of 760, it might make the code simpler.

I don't know why I didn't try this at that time, maybe I found it hard for me, and didn't know how to work with 2D array.

 

I don't understand why do you want to prepend redundant information to the array.

1. The added byte is like an address for the subsequent 8-bytes, because each 8-bytes set represent a character or symbol of ASCII set.

2. I can call each 8-bytes and send them to the 8x8 dot matrix module serially. But if I want to enter a string; like, "Hello", how to convert that into 8-bytes sets, that would be 5 sets of 8-bytes.

3. And I have to call them arbitrary, so I need a function which convert this string into a set of 8-bytes and send them to the module.

4. So, I added the same ASCII set with the same arrangement to each row of the 8-bytes array, so it's like an address to that row.

5. That way I can easily call any set with a function which convert string input to 8-bytes sets output.

 

If you had a 2D array, you could just add 0x20 to the first index to get those values.

Hmmm, didn't get your idea, how exactly? Because I wrote this function before like months and not working on it right now. I'm working now on simple projects for my work.

 

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

wolfrose wrote:
Of course didn't do these functions to be readable for other people,
Then you aren't writing C properly. You should always consider the "next reader" because often it will be you in 18 months time and you (like the rest of us) won't have a clue how the code operates. Usually however (in commercial environments) the "next reader" is often a maintenance engineer or simply the engineer who replaced you after you were sacked and you need to give them a fighting chance of being able to understand your code. So always write C 9or any language) with this in mind.

 

In a line like:

 SPI_TX_m(data = (row<<8) | (shift_buffer[(8*(i+1))+(row-1)]),i);

There's no need for the data assignment to be there. The line would start to get simpler with simply:

 data = (row << 8);
 SPI_TX_m(data | (shift_buffer[(8 * (i + 1))+(row - 1)]), i);

The indexing into shift_buffer[] would be hugely aided if you took El Tangas' advice and made some of these arrays two dimensional. Then you wouldn't be having the "* 8" thing in there to multiply by the "width".

 

As I look closer at this line I do wonder what the second parameter to SPI_TX_m() actually is - you are passing "i" but what is that used for?

 

Oh and a s general rule don't do this:

        for (u=0;u<8;u++)
        shift_buffer[u]=new_ascii[s++];

or even, as some may do, this:

        for (u=0;u<8;u++)
            shift_buffer[u]=new_ascii[s++];

but do it like this:

        for (u = 0;u < 8;u++) {
            shift_buffer[u] = new_ascii[s++];
        }

that is, always use braces because even though you are only performing one operation on each iteration right now, you might later want to add something else like:

        for (u=0;u<8;u++)
            shift_buffer[u]=new_ascii[s++];
            if (s > 20) s = 0;

and if you do it like that the new line is not inside the repeating code (even if the indentation fools you to thinking that it is).

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

clawson wrote:

Then you aren't writing C properly. You should always consider the "next reader" because often it will be you in 18 months time and you (like the rest of us) won't have a clue how the code operates. Usually however (in commercial environments) the "next reader" is often a maintenance engineer or simply the engineer who replaced you after you were sacked and you need to give them a fighting chance of being able to understand your code. So always write C 9or any language) with this in mind.

You're absolutely right, I ran into many codes from people online, custom libraries for programmers on Github or from official websites like microchip libraries, most of the codes don't have detailed explanations, I remember Peter Fleury libraries; I really like that programmer I find his I2C library very good example for my next modification for my I2C library to use ISRs.

 

I uploaded complete small projects at Github, I think they have some comments for explanations but not very detailed. I think or thought the small comments are enough just to give a hint about the line.

 

 

There's no need for the data assignment to be there.

I just wanted to put it in one line.

 

 

The indexing into shift_buffer[] would be hugely aided if you took El Tangas' advice and made some of these arrays two dimensional. Then you wouldn't be having the "* 8" thing in there to multiply by the "width".

Yes, I think that I found it hard at that time to work with 2D array because of the indexing arithmetics I need to reach each set of 8-bytes as I recall.

 

 

As I look closer at this line I do wonder what the second parameter to SPI_TX_m() actually is - you are passing "i" but what is that used for?

That's because I was working on 4 dot matrix modules, so sending 32-bytes to the 4 modules and every time I have to update the data in each module. But I did the buffer to 40-bytes to give one blank 8x8 bytes set for the start of shifting effect.

 

 

Oh and a s general rule don't do this:

        for (u=0;u<8;u++)
        shift_buffer[u]=new_ascii[s++];

and if you do it like that the new line is not inside the repeating code (even if the indentation fools you to thinking that it is).

OK, I modified it ;)

 

I actually have a problem with a code I'm doing to read a joystick analog signals and also predict the button press at any time.

void joystick_init(void)
{	
	DIDR0 = 0x03;							// disable digital input buffers for ACD0,1,2
	DDRC=0xF8;							// x,y,button PC0,PC1,PC2 inputs rest output
	DDRB=0x20;							// PB5 output
	ADC_EN;								// enable ADC
}

void joystick_read(void)
{
    uint16_t joystick_AN_xy[2];
    ADC_CH0;						 		// CH0
    ADC_ST;			                 			// start 1st adc
    while(ADCSRA&(1<<ADSC));       					// wait until process is finished
    joystick_AN_xy[0] = (ADCL | (ADCH<<8));		 		// read AN0
    ADC_CH1;		                 			        // CH1
    ADC_ST;                          					// start 2nd adc
    while(ADCSRA&(1<<ADSC));     					// wait until process is finished
    joystick_AN_xy[1] = (ADCL | (ADCH<<8));       			// read AN1
    
    if (PINC&(1<<PINC2))PORTB |= (1<<PB5);     			        // button with pullup resistor 
    else PORTB &= ~(1<<PB5);
    
    sprintf(val_arr,"%d",joystick_AN_xy[0]);
    move_cursor(1,1); 
    LCD_string("x value:");
    move_cursor(1,10); 
    LCD_string(val_arr);
    sprintf(val_arr,"%d",joystick_AN_xy[1]);
    move_cursor(2,1);
    LCD_string("y value:");    
    move_cursor(2,10);      
    LCD_string(val_arr);
    _delay_ms(500);
    sendCMD(clear_display);       
}

But I think the ADC isn't working properly. And the press of course isn't maintained all the time, it misses often. Do I have to apply interrupts for the button press?

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

wolfrose wrote:
Hmmm, didn't get your idea, how exactly? Because I wrote this function before like months and not working on it right now. I'm working now on simple projects for my work.

 

If you define the array thusly:

uint8_t font8x8_basic[95][8] = {
     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0020 (space)
     {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},   // U+0021 (!)
     {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0022 (")
     {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},   // U+0023 (#)
     {0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},   // U+0024 ($)
     {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},   // U+0025 (%)

 

You can access the font bitmap for char c like this:

 

uint8_t index_ = c-0x20;

line0 = font8x8_basic[index_][0];
line1 = font8x8_basic[index_][1];
line2 = font8x8_basic[index_][2];
...
line7 = font8x8_basic[index_][7];

 

edit: I'm having some trouble with formatting...

edit: It seems [index_] (without underscore) is some kind of reserved word for the forum text editor, so i changed to [index_]

Last Edited: Wed. Sep 5, 2018 - 05:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

wolfrose wrote:
Hmmm, didn't get your idea, how exactly? Because I wrote this function before like months and not working on it right now. I'm working now on simple projects for my work.

 

If you define the array thusly:

uint8_t font8x8_basic[95][8] = {
     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0020 (space)
     {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},   // U+0021 (!)
     {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0022 (")
     {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},   // U+0023 (#)
     {0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},   // U+0024 ($)
     {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},   // U+0025 (%)
     {0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},   // U+0026 (&)

 

You can access the font bitmap for char c like this:

 

line0 = font8x8_basic[c-0x20][0];
line1 = font8x8_basic[c-0x20][1];
line2 = font8x8_basic[c-0x20][2];
...
line7 = font8x8_basic[c-0x20][7];

 

OK, if I wanted to convert a string to any line according to the chars of the string?

 

I did this function for this reason:

void convert_string_to_8x8_byte_packets(uint8_t *string_, uint8_t sizeof_string, uint8_t *str_8x8)
{
    uint16_t i;
    uint8_t j,k;
    for (i=0;i<sizeof_string;i++)
    {
        for (k=0;k<95;k++)
        {
            if (string_[i]==new_ascii[k*9])
            {
                for (j=0;j<8;j++)
                {
                    str_8x8[(i*8)+j]=new_ascii[((k*9)+1)+j];
                }
            }
        }
    }
}

 

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

El Tangas wrote:
I'm having some trouble with formatting...

So you are!

 

You mean this:

uint8_t index = c-0x20;

line0 = font8x8_basic[0];
line1 = font8x8_basic[1];
line2 = font8x8_basic[2];
:
:
line7 = font8x8_basic[7];
 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, try to post [_index_] (but without underscores) and you will find outdevil

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

I this function:

void convert_string_to_8x8_byte_packets(uint8_t *string_, uint8_t sizeof_string, uint8_t *str_8x8)
{
    uint16_t i;
    uint8_t j,k;
    for (i=0;i<sizeof_string;i++)
    {
        for (k=0;k<95;k++)
        {
            if (string_[i]==new_ascii[k*9])
            {
                for (j=0;j<8;j++)
                {
                    str_8x8[(i*8)+j]=new_ascii[((k*9)+1)+j];
                }
            }
        }
    }
}

You are scanning the whole array each time you want to find a character! Besides, using a 2D array avoids stuff like

new_ascii[((k*9)+1)+j]

because the compiler will do the calculations for you.

 

This is how I would do it, with the 2D array from #74 instead of the prefixed one:

void convert_string_to_8x8_byte_packets(uint8_t *string_, uint8_t sizeof_string, uint8_t *str_8x8)
{
    uint16_t i;
    uint8_t j, k = 0;
    for (i=0;i<sizeof_string;i++)
    {
        uint8_t char_8x8 = string_[i] - 0x20;
        for (j=0;j<8;j++)
        {
            str_8x8[k++]=new_ascii[char_8x8][j];
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Of course didn't do these functions to be readable for other people

But you're asking for help from other people.  That's just rude!

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

El Tangas wrote:

No, try to post [_index_] (but without underscores) and you will find outdevil

You mean [ index ] ?

 

(the "trick" is spaces ;-)

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

Oh, it was that easy... blush

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

I've run into similar problems.  The forum software seems to support some special tags (although it seems unrelated to this issue with square brackets).  Copy-paste from, say, the GCC documentation, can present some problems.  For example, from https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html we have:

The asm keyword is a GNU extension. When writing code that can be compiled with -ansi and the various -std options, use __asm__ instead of asm (see Alternate Keywords).

I just pasted that, and it will show up fine after I click 'Post', but in the code editor (just now)  it looks like this:

Note the missing asm and __asm__ keywords in three different places.

 

When looking at the HTML source that gets copy/pasted from FF, we see:

<p>The <code>asm</code> keyword is a GNU extension.
When writing code that can be compiled with <samp>-ansi</samp> and the
various <samp>-std</samp> options, use <code>__asm__</code> instead of 
<code>asm</code> (see <a href="Alternate-Keywords.html#Alternate-Keywords">Alternate Keywords</a>).
</p>

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

El Tangas wrote:

You are scanning the whole array each time you want to find a character! Besides, using a 2D array avoids stuff like

new_ascii[((k*9)+1)+j]

because the compiler will do the calculations for you.

 

This is how I would do it, with the 2D array from #74 instead of the prefixed one:

void convert_string_to_8x8_byte_packets(uint8_t *string_, uint8_t sizeof_string, uint8_t *str_8x8)
{
    uint16_t i;
    uint8_t j, k = 0;
    for (i=0;i<sizeof_string;i++)
    {
        uint8_t char_8x8 = string_[i] - 0x20;
        for (j=0;j<8;j++)
        {
            str_8x8[k++]=new_ascii[char_8x8][j];
        }
    }
}

 

I should try this function :) Thanks!

 

 

joeymorin wrote:

Of course didn't do these functions to be readable for other people

But you're asking for help from other people.  That's just rude!

 

I'm sorry I mean myself basically at the time I was developing this code, I didn't think or intend to provide more details about the function, but not entirely! I've written some comments. I can send you my AVR snippets file which has like 1000 lines of code, then you can understand my style of writing code.

 

My principle is that I think the comment I write are enough for other programmers to understand, because when I write the code I think "other programmers are more professional than me, so they should understand this line with this simple comment!", but I think I should put more details.

 

I uploaded my file, it's not all functions and codes, it's like half of it, the other half is data, arrays, hints, other codes from online ... etc.

Attachment(s): 

Pages