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
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..
 
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).
 

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
 
Excuse me for being dumb... Where do you write the value to the LCD???
 
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..

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..

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..
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 || . I get it now ...with || 'OR' both condition needed to be false.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…