change value with a pointer

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

hi,

 

i want to change a value when a button is pressed.

 

when starting the atmega, "sensorius" is called.

In this function i want to change the value of "config_sensors". to do this i need a pointer, correct?

 

my code so far:

sensorius(int *x)
{

if (!(PINC & (1<<PINC0)))               // wait for button 1
	{
	*x = *x |0b00000001;

	sensorius(*x);                  // not sure about *x, can i use &config_sensors from within the function`?
	}
  else if(!(PINC & (1<<PINC1)))         // wait for button 2
  {
	*x = *x |0b00000010;
		sensorius(*x);
	}
  else if(!(PINC & (1<<PINC7)))         // wait for button 8
  {
	  return 0;
  }


  else
  {
  sensorius(*x);                        // start again
  }
}

i want to change the value when button 1 oder 2 is pressed. to exit the function button 7 must be pressed.

i call the function with

sensorius(&config_sensors);

 

-slook

Last Edited: Wed. Sep 13, 2017 - 05:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So that looks like a good plan. So what's the actual question here?
.
As 'x' is a pointer to config_sensors you might want to call it something like pconfig_senors.
.
If this were C++, not C you might consider a "reference"

Last Edited: Wed. Sep 13, 2017 - 05:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is basic 'C' stuff - nothing to do with Atmel Studio or AVR

 

sl00k wrote:
to do this i need a pointer, correct?

If you want to do it by parameter passing then, indeed, you would have to use a pointer.

 

Alternatives to doing it by parameter passing include:

 

  • Have the function return a value;
     
  • Make the variable global (or, at least, file scope)

 

The code as shown is calling sensorius() recursively; you really don't want to do that - especially on a small microcontroller with limited RAM!!

 

 

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

sl00k wrote:
wait for button 1

No, that wont "wait". It will simply test if PINC pin 0 is low. It will test this once, and depending on the result the program will proceed with either the "if-leg" or the "else-leg" of that test.

 

Furthermore, your function calls itself. This is called "recursion" and can sometimes be a useful technique. In this case, however, it is benign and you will sooner or later run out of RAM: Each unfinished function-call consumes a bit of RAM in a structure called "the stack". Since the sensorius() function will only exit when button 8 is detected, there is a definitive risk of the program consuming all RAM space sooner or later.

 


 

You need a loop, that calls the function repeatedly. Assuming this should go on for as long as the AVR ispowered up, this loop could be in the main() function like so (sketchy, not tested):

int main(void)
{
    uint8_t x = 0;
    
    while (1)
    {
        sensorius(&x);
        
        // Do something using the value of x, e.g. show it on a row of leds
        // connected to PORTD
        
        PORTD = x;
    }
}

 

Now that we have the repetition taken care of, you can remove the calls from sensorius() to itself.

 

And yes, since the value that sensorius() computes is needed in main() we need to pass a pointer to a variaable, rather than the variable itself (notice the &x in the call done in main()).

 

So, we end up with a sensorius() something like this:

 

void sensorius(int *x)
{
    if (!(PINC & (1<<PINC0)))
	{
	    *x = *x |0b00000001;
	}
    else if(!(PINC & (1<<PINC1)))
    {
	    *x = *x |0b00000010;
	}
    else if(!(PINC & (1<<PINC7)))
    {
        *x = 0;
    }
}

Note this:

 

1. The return type of the function is void. The value to come out of the function does so via the pointer parameter.

2. Thus, no explicit return statement is needed, especially not with any value.

3. I've fixed the indentation. Always be meticulous with indentation - it is there for you (and other human readers) so that the meaning of the code is clear. (The compiler does not care sh*t.. ;-)

 

Also: If you have electro-mechanical switches attached to PORTC, the code will work. If your next experiment is to increaser a variable, rather than just setting a bit in it it will stop working properly. This is because such switches "bounce", i.e. the open and close several times when you press down the button. Same thing on release. Special measures will be needed in order to handle this bouncing. Google "button bounce", "button debounce" and similar, possibly in combination with "AVR" to find a lot of stuff already written about this.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"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

clawson wrote:
So that looks like a good plan.

Are you saying recursion is a "good plan" here, Cliff?!?

 

Note: Both Cliff and awneil wedged in before me. That's what you get for writing long answers (a.k.a "rambling"). (-:

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"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

I missed the recursion (almost impossible to read the body of the code on small mobile) but was saying his plan to pass & config then access as *something seems like the obvious way to pass by reference.

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

thanks for all the input, didnt know about the problem with the ram.

 

but how do i loop in the function?

i want to set a few bits. when i have set all bits i want, i press button 7 and want to get out of the function

 

totaly forgot the for loop :D

 


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

int channel;
int config_sensors = 0x00;		// code to selected sensors

sensorius(int *pconfig_sensors)
{

for( ; ; )
{

	if (!(PINC & (1<<PINC0)))
	{
		*pconfig_sensors = *pconfig_sensors |0b00000001;
	}
	else if(!(PINC & (1<<PINC1)))
	{
		*pconfig_sensors = *pconfig_sensors |0b00000010;
	}
	else if(!(PINC & (1<<PINC7)))
	{
	  return 0;
	}

	else
	{
		_delay_ms(2);
	}
}
}

int main(void)
{
DDRC = 0x00;			//Eingang
DDRD = 0xff;			//Ausgang
PORTD= config_sensors;
_delay_ms(200);
sensorius(&config_sensors);
PORTD = config_sensors;
while(1)
{

_delay_ms(200);
PORTD = config_sensors;

}

  return 0;
}

thanks for all your help =)

 

edit: ok, still not working like i want it to :(

 

i use this code in the function

		
		if (!(PINC & (1<<PINC0)))
		{
			_delay_ms(2);
			*pconfig_sensors = *pconfig_sensors |0b00000001;
		}
		else if(!(PINC & (1<<PINC1)))
		{
			_delay_ms(2);
			*pconfig_sensors = *pconfig_sensors |0b00000010;
		}
		else if(!(PINC & (1<<PINC7)))
		{
			return 0;
		}

		else
		{
			_delay_ms(2);
		}


		if (!(PINC & (1<<PINC2)))
		{
			_delay_ms(2);
			*pconfig_sensors = *pconfig_sensors |0b00000100;
		}
		else if(!(PINC & (1<<PINC3)))
		{
			_delay_ms(2);
			*pconfig_sensors = *pconfig_sensors |0b00001000;
		}
		else
		{
			_delay_ms(2);
		}

now, when i press button 4 the same led/bit is set like when i press button 3 !

Last Edited: Wed. Sep 13, 2017 - 08:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
	for( ; ; )
	{

		if (!(PINA & (1<<PINA0)))
		{
			_delay_ms(20);
			*pconfig_sensors = *pconfig_sensors |0b00000001;	//a0
		}
		else if(!(PINA & (1<<PINA1)))
		{
			_delay_ms(20);
			*pconfig_sensors = *pconfig_sensors |0b00000010;	//a1
		}
		else if(!(PINA & (1<<PINA2)))
		{
			_delay_ms(20);
			*pconfig_sensors = *pconfig_sensors |0b00000100;	//a2
		}
		else if(!(PINA & (1<<PINA3)))
		{
			_delay_ms(20);
			*pconfig_sensors = *pconfig_sensors |0b00001000;	//a3
		}
		else if(!(PINA & (1<<PINA7)))
		{
			return 0;
		}

		else
		{
			_delay_ms(20);
		}

	}

now it is working.

maybe my portc on the stk500 or chip is broken :(

edit: portc works fine, jtag was enabled

Last Edited: Wed. Sep 13, 2017 - 08:36 PM