Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

integer and comparing problem

Status
Not open for further replies.

skmdmasud

Member
Hi..
Its been a while since my last project, this time i am building a automatic water changing system for my aquarium. I ran into a problem with integer becoming <0 and my comparison in my WHILE statement fails to detect that...

I have attached a part of my code. I am sending the temp variable to my LCD. the temp gets minus with 2 or 3 or 4 depending on power head capacity.

In my LCD i see
temp is 10
temp is 6
temp is 2
temp is *$&@!
temp is *${})*

and so on... my while fails to see that temp became <1 and loops forever:confused:
all variable are 16bit

Code:
while (temp >1 | float_sensor_bottom == 0) //check amount of water drained
	{
		lcd_light_on();
		powerhead_on();
		if (bit_is_clear(PIND,5))
		{
			float_sensor_bottom = 1;
		}
		
		if (internal_sec >40) // it will take 10s for internal_sec to become 40 cuz 4hz it goes ++
		{
			temp = temp - power_head_liter_10s;
			internal_sec = 0;			
			eeprom_update_word((&NV_water_drained), temp); //writing drained amount at eeprom memory
}
 
There is not enough of the code to give a definite answer so I'll just say that you should make sure that 'temp' is a signed 16 bit variable, and not an unsigned one.
 
There is not enough of the code to give a definite answer so I'll just say that you should make sure that 'temp' is a signed 16 bit variable, and not an unsigned one.

Hi..
i am using avr atmega8.

i declared using

uint16_t temp;

ok. i will try adding signed.:)
 
You have a bitwise OR '|' instead of logical OR '||'

EDIT: The above does not make a difference in this case. (But you should use the logical OR '||')
 
Last edited:
You have a bitwise OR '|' instead of logical OR '||'

EDIT: The above does not make a difference in this case. (But you should use the logical OR '||')
I am happy as long as it works but i will fix it and will keep that in mind..
 
I am happy as long as it works but i will fix it and will keep that in mind..

Once it stops working the bug is really hard to find.
 
Making my variable signed did not work. I did a simple experiment

signed int a,b;
a=10;
b=7;

while(a>1)
{
LCDPrint(a);
a=a-b;
_delay_ms(500);
}

in the above code i see
10
3
>@<#
!@#$
and so on...
the while fails to see break
 
What LCD library are you using... Most LCD routines do not use print formatting

If you need to print a decimal variable you will need the print string function

Code:
LCDprintstring( itoa(a));

This will convert your variable to a string so you may output it to the screen...
 
Making my variable signed did not work. I did a simple experiment
...
in the above code i see
10
3
>@<#
!@#$
and so on...
the while fails to see break
The code is ok and will run correctly if compiled with a standard (ANSI) C compiler. Can you post the actual code file you're having trouble with (not just an excerpt).
 
What LCD library are you using... Most LCD routines do not use print formatting

If you need to print a decimal variable you will need the print string function

Code:
LCDprintstring( itoa(a));

This will convert your variable to a string so you may output it to the screen...

Hi..
this was just an example to show what i was doing. please check my next post.

Regards.
 
The code is ok and will run correctly if compiled with a standard (ANSI) C compiler. Can you post the actual code file you're having trouble with (not just an excerpt).

Hi..
below is my whole function. i changed variable input to fixed number to test it out. It still didnt work.

there are 2 while the second while to fill the tank works fine because it does --.

I use ATMEL AVRStudio 6.

Code:
void start_water_change_nomix(void)
{
	LCDWriteStringXY(0,0,"Water Drained   ");
	lcd_light_on();
	water_solenoid_off(); //solenoid off
//	powerhead_on();//turn on powerhead
	signed int temp2 = 10;//eeprom_read_word(&NV_water_drain_amount ); // read EEPROM
	
	signed int power_head_liter_10s;
	//power_head_liter_10s = eeprom_read_word(&NV_Power_Head_ltrHr ); // read EEPROM
	power_head_liter_10s = 7;
	internal_sec = 0; //reset ISR seconds
	eeprom_update_word((&NV_running_function), 1); //writing 1 at eeprom memory
	int float_sensor_bottom = 0;
//	power_head_liter_10s=((power_head_liter_10s*10)/3600); //water drained in 10s
	while (temp2 >1 || float_sensor_bottom == 0) //check amount of water drained
	{
		lcd_light_on();
		powerhead_on();
		if(bit_is_clear(PIND,5))
		{	float_sensor_bottom = 1;	}
		
		if(internal_sec >40) // it will take 10s for internal_sec to become 40 cuz 4hz it goes ++
		{
			temp2 = temp2 - power_head_liter_10s;
			temp = temp2;
			internal_sec = 0;			
			eeprom_update_word((&NV_water_drained), temp2); //writing drained amount at eeprom memory
		}
		if (bit_is_clear(PIND,3)) //detect cancel button
		{
			powerhead_off();
			LCDWriteStringXY(0,0,"Water Drain     ");
			LCDWriteStringXY(0,1,"...Cancelled... ");
			_delay_ms(2000);			
			break;
		}
		
	}	//-----------------END OF Power head run time---------NOW Start Filling the tank--------
	
	powerhead_off(); //turn off power head
	LCDWriteStringXY(0,0,"Drain Complete  ");
	LCDWriteStringXY(0,1,"Opening Solenoid");
	_delay_ms(3000);
	//----now start filling the tank-----------
	water_solenoid_on();
	eeprom_update_word((&NV_running_function),2); //writing 2 at eeprom memory for filling progress
	LCDWriteStringXY(0,0,"Water Fill... In");
	LCDWriteStringXY(0,1,"Progress. Cancel");
	
	temp = eeprom_read_word(&NV_max_fill_time ); // read EEPROM
	int float_sensor_top = 0;
	int time_count;
	while (temp >1 || float_sensor_top == 0)
	{
		lcd_light_on();
		water_solenoid_on();
		if (bit_is_clear(PIND,4))
		{
			float_sensor_top = 1;			
		}
		
		if (internal_sec >40) // every 10 sec.. it will take 10s for internal_sec to become 40 cuz 4hz it goes ++
		{	
			internal_sec = 0;
			time_count ++;
			if(time_count > 5) //every min
			{
				temp --;
				time_count = 0;
				
				eeprom_update_word((&NV_water_filled), temp); //writing 1 at eeprom memory
				
			}
		}
		if (bit_is_clear(PIND,3)) //detect cancel button
		{
			water_solenoid_off();
			LCDWriteStringXY(0,0,"Water Change    ");
			LCDWriteStringXY(0,1,"...Cancelled... ");
			_delay_ms(2000);
			break;
		}		
	} //end of while water fill
	water_solenoid_off();
	LCDWriteStringXY(0,0,"   Water Fill   ");
	LCDWriteStringXY(0,1,"    Complete    ");
	_delay_ms(2000);
	lcd_display_home();
	
}	//end of start water change no mix
 
In your code, if bit_is_clear(PIND,5) is false (& therefore float_sensor_bottom == 0), the loop will continue forever.
 
In your code, if bit_is_clear(PIND,5) is false (& therefore float_sensor_bottom == 0), the loop will continue forever.

hi..
when i make PIND5 ground then float_sensor_bottom becomes 1 and loops breaks and work perfectly. the condition has an OR || so any one condition becoming true will make it break. Or am i missing something:confused::confused:..

Regards.
 
In your code, if bit_is_clear(PIND,5) is false (& therefore float_sensor_bottom == 0), the loop will continue forever.

hi..
when i make PIND5 ground then float_sensor_bottom becomes 1 and loops breaks and work perfectly. the condition has an OR || so any one condition becoming true will make it break. Or am i missing something:confused::confused:..

Regards.
 
Excuse me for being dumb... Where do you write the value to the LCD???

void powerhead_on(void)
{
PORTC |= 1<<PINC2;
if ( internal_sec%2==0 ) //blink the water change activity led
{ PORTC |= 1<<PINC1;

}
else { PORTC &= ~(1<<PINC1); LCDWriteIntXY(0,1,temp,4); }

}
 
when i make PIND5 ground then float_sensor_bottom becomes 1 and loops breaks and work perfectly. the condition has an OR || so any one condition becoming true will make it break. Or am i missing something:confused::confused:..
Yes, you are missing something. The while loop will continue looping so long as the condition is true. so your construct while (temp2 >1 || float_sensor_bottom == 0) will keep looping if either temp > 1 OR if float_sensor_bottom == 0. So float_sensor_bottom == 0 then it doesn't matter what value is in temp - it will continue to loop irrespective!

Try: while (temp2 > 1 && float_sensor_bottom == 0) instead; if either case becomes false, the loop will end.
 
Yes, you are missing something. The while loop will continue looping so long as the condition is true. so your construct while (temp2 >1 || float_sensor_bottom == 0) will keep looping if either temp > 1 OR if float_sensor_bottom == 0. So float_sensor_bottom == 0 then it doesn't matter what value is in temp - it will continue to loop irrespective!

Try: while (temp2 > 1 && float_sensor_bottom == 0) instead; if either case becomes false, the loop will end.

Hi dougy83
i surely did mix up the && and || :confused::confused:. I get it now ...with || 'OR' both condition needed to be false.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top