Jump to content

Recommended Posts

:blink:

BoostC 6.40 & two EZcontrollers

 

My only feedback from my one-line camera is a graphic LCD. I display my integration clock signal as a small dash that moves up and down a maximum of 32. To allow larger values to display I added more 'bugs' that have been divided by 2's. Everything is fine until /2 & /4 hit 32. They stick at 32 even though I know the clock rate has dropped. I know because my image is the right size and shape. When I press the reset button the image remains the same (so the clock has not changed) but the bugs suddenly drop to where they should be and continue to operate until the next time they reach a maximum.

I limited the value of the clock to 0xFF and the bugs don't stick. Beyond that they do. I have played with many variations of int, short, (), unsigned and casting the answers. Why can my clock not display bigger than 255 when it is a 16bit variable?

 

//Global variables
unsigned int maxht, photo[array_size], clk;
unsigned char	clk2, clk3, clk4;	// clk bugs for feedback

void CheckBright(void)
{
//
if (maxht > 150) clk = clk - 40;		// WAAY Too Bright
if (maxht > 60) clk = clk - 20;			// Far Too Bright
if (maxht > 45) clk = clk - 10;			// Too Bright
if (maxht > 30) clk = clk - 4;			// a bit Too Bright
if (maxht < 24) clk = clk + 4;			// a bit Too Dim
if (maxht < 15) clk = clk + 7;			// Too Dim
if (maxht < 10) clk = clk + 10;			// Much Too Dim
if (clk < 5) 
{
	ouch = true;
}		// Limit clock high speed for A2D
else
{
	ouch = false;		// OK when clk rises
}
if (clk > 0xFF) clk = 0xFF;
}//END CheckBright

//////////////////////////////////////////////////////////////////////////////////
////
clk2 = (clk >> 2);			// HELP!!!
							// if clk exceeds 255 clk2 & clk3
clk3 = (clk >> 3);			// will remain at 32 even when clk drops down.
							// When clk returns to normal values my LCD image
clk4 = (clk >> 4);			// is fine. When I reset, the feedback 'bugs' drop
							// back to normal and the display is stable (before & after)

DrawBox(realcL,24,realcH,26,1);	// Desired Center Mark 
DrawBox(0,clk4,3,clk4+1,1);		// Clk 'bug'	set last digit 
DrawBox(4,clk3,7,clk3+1,1);		// Clk 'bug'	to 0 to hide bugs
DrawBox(8,clk2,10,clk2+1,1);	// Clk 'bug'
//

Thanks for hints to my failure to grasp the obvious

Link to post
Share on other sites

my clk2, 3 & 4 jam if clk gets bigger than 255 but clk itself continues to vary.

How can clk3 =(clk >> 3) remain constant when clk is changing?

I have been all around the scope of variables and it looks like a conflict between variables of the same name but I can't see any.

My function uses only global variables right now.

I tried passing values to the function, I tried local variables in the function. I even turned off optimization. Any hints?

Link to post
Share on other sites
Any hints?
If you can provide a simple but complete program that demonstrates the problem, then there will be more chance that someone can help.

 

Regards

Dave

Link to post
Share on other sites

:huh: OK Here is a chopped down version that demonstrates the problem.

I have an EZ controller and BoostC 6.40.

The clk2,3,4 'bugs' move up and down relative to clk until clk >255. Then they stick at 32. clk is changing but (clk2 = clk>>2) does not.

Keep in mind this is chopped down from 15 pages so there are a lot of useless variables named.

#pragma CLOCK_FREQ 20000000
#include <system.h>


#define	soft_TX_BIT	2		// Portb.2 TX bit

#define	TxDel	43			// Trim with an osc.
#define array_size 128		// 	TSL1401 is 128 bit device
#define swdten		0


// Function declarations
void ReadSensor(void);			// Get input dtat from sensor
void FindMaxht(void);			// Find the brightest element
void FilterData(void);			// Enhance data
void CheckBright(void);			// Automatic gain control
void DisplayData(void);
void DrawGates();
void startpulse(void);			// Overlapping SI & CLK pulses to start TSL1401
void clkout(void);				// Regular CLK sequence for read, TSL1401
void DrawBox(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour);	// To draw a steering box
void TxChar(char TxVal); 		// Display output on serial LCD


// Global Variables
unsigned char DigIn, AdRes[12], UpLink[3], DigOut, contrast;
bool ComError, CommLost, ouch, binthere, Line_Found, Echo_SD, Comms_OK, DataOK;
unsigned int maxht, photo[array_size], clk;
unsigned char min, max, maxhtLoc, maxLoc, minLoc, realc, thresh, happy, band;
unsigned char HappyL, HappyH, ThreshL, ThreshH, realcL, realcH, centerL, centerH, center;
unsigned char soft_delay, errnum, Raw;
signed char request_avg, happy_avg;	// motor runs when enough requests lean Left(+ve) or Right(-ve)
volatile bit Main_D1, Main_D2, Main_SWL, Main_SWR, Per_SWL, Per_SWR, Line_Happy;
volatile bit PLC_LampON, PLC_SD, Auto, Raw_Data;

////////////////////////////////////////////////////////////////
void main()									// FLF_rev7.3.c
////////////////////////////////////////////////////////////////
{
unsigned char i;

// Initialize remote variables from Per board
thresh = 4;
contrast = 150;
PLC_SD = true;
PLC_LampON = false;
Main_SWL = true;
Main_SWR = true;
Per_SWL = true;
Per_SWR = true;
Auto = false;
// Initialize flags for good data present
binthere = false;	
ouch = false;
DataOK = false;

trisa = 00011111b;	// lower 5 PORT A inputs
trisb = 11110011b;	// DON'T BUGGER UP PORTB.0 .1 .2 .3					
trisc = 10000000b;	// all Port C outputs but RX line
adcon1 = 00000010b;					// Change ADC for optical input
adcon0 = 10000001b;					// Read from AN0 for optical input
clk = 50;							// Default clock setting
clear_bit( trisb, soft_TX_BIT ); 	// set tris Tx Line output
clear_bit( latb, soft_TX_BIT );   	// set Tx Line low
set_bit( trisb, 4 );				// RB4 - switch input
set_bit( trisb, 5 );				// RB5 - switch input
DigOut = 0xFF;						// Reset Per board digital outputs
DigIn = 0xFF;						// Reset Per board digital inputs
happy = 4;
band = 2;
realc = 34;
soft_delay = 30;
Line_Found = false;
Echo_SD = false;
Comms_OK = false;
Line_Happy = false;
TxChar(254);		// Command prefix
TxChar(66);			// Turn ON LCD backlight
TxChar(0);			// Forever


while (1)
{
ReadSensor();		// operate TSL1401 sensor and fill array
FilterData();		// Take data array and sharpen peaks
FindMaxht();		// Find the brightest element
CheckBright();		// Adjust clock to keep data on LCD
DrawGates();
DisplayData();

}	
}	
void ReadSensor(void)
{
volatile bit A2D_not_done@0x0FC2.2;		// bit 2 of adcon0
unsigned char i;
// Optical Sensor DATA from AN0
// clear out old data that accumulates between reads
//
//	
startpulse();			// generate the si & clk to start the workings
for (i = 0; i < array_size;  i++)
{							
clkout();				// clears out saturated data to /dev/null
}
clkout();
//				
// get new Optical Sensor data
//
startpulse(); 	// Sends SI overlapping CLKOUT pulses to start reading data
for ( i = 0; i < array_size; i++)
{
	clkout();				// clock to next pixel
	set_bit(adcon0, 2);		// read analog input0 until adcon0.2 drops to zero
	while (A2D_not_done);	// Wait for a2d done flag to change
	photo[i] = adresh; 		// store data in array 
} 
clkout();	
}//END

void FilterData(void)
{
// Filter Optical Data to sharpen line edges
// Using Haley Filter algorithm (c)2005
unsigned char i, j;
short sum, count, average, remove;
// Massage data
// Run data through filter 'j' times

for (j=0; j <= 2; j++)
	{
		sum = 0;
		count = 0;
// Start by getting the average value
		for (i=0; i < array_size; i++)
		{
			if (photo[i] > 0)
			{
				sum = sum + photo[i];
				count++;
			}
		}	// endfor i
average = sum/count;		// average height (brightness)

// and by removing some signal from all
remove = ((average >> 1)+ 6);
		for (i=0; i < array_size; i++)
		{
			if (photo[i] <= remove) 
			{
				photo[i] = 0;
			}

			else
			{
				photo[i] = (photo[i] - remove);
			}	

		}	// endfor i
	} // endfor j

}// END Filter Optical Data

void FindMaxht(void)
{
unsigned char i;
//
maxht = 0;
for (i = 0; i < array_size; i++)
{								// Find the brightest element
	if (photo[i] > maxht) 
	{
		maxht = photo[i];
		maxhtLoc = i;
	}
}
	maxLoc = maxhtLoc + 6;		//	Look near brightest only
	minLoc = maxhtLoc - 6;

}	// END FindMaxht

void CheckBright(void)
{
//
if (maxht > 150) clk = clk - 40;		// WAAY Too Bright
if (maxht > 60) clk = clk - 20;			// Far Too Bright
if (maxht > 45) clk = clk - 10;			// Too Bright
if (maxht > 30) clk = clk - 4;			// a bit Too Bright
if (maxht < 24) clk = clk + 4;			// a bit Too Dim
if (maxht < 15) clk = clk + 7;			// Too Dim
if (maxht < 10) clk = clk + 10;			// Much Too Dim
if (clk < 5) 
{
	ouch = true;
}		// Limit clock high speed for A2D
else
{
	ouch = false;		// OK when clk rises
}

}//END CheckBright

void DrawGates()
{
ouch = false;
TxChar(254);						// Command prefix
TxChar(88);							// Clear screen
//
//	Display Control gates for motor ON & OFF locations on LCD	

// Aids for dimwitted programmer	
//	centerH = maxhtLoc + 2;
//	centerL = maxhtLoc - 2;
//	realcL = realc - 1;
//	realcH = realc + 1;
//////////////////////////////////////////////////////////////////////////////////
////
unsigned char	clk2 = (clk >> 2);		// HELP!!!
						// if clk exceeds 255 clk2 & clk3
unsigned char	clk3 = (clk >> 3);		// will remain at 32 even when clk drops down.
						// When clk returns to normal values my LCD image
unsigned char	clk4 = (clk >> 4);		// is fine. When I reset, the feedback 'bugs' drop
						// back to normal and the display is stable (before & after)


DrawBox(0,clk4,3,clk4+1,1);		// Clk 'bug'	set last digit 
DrawBox(4,clk3,7,clk3+1,1);		// Clk 'bug'	to 0 to hide bugs
DrawBox(8,clk2,10,clk2+1,1);	// Clk 'bug'

}	//END DrawGates

void DisplayData(void)
{
unsigned char i;

for (i = minLoc; i <= maxLoc; i++)
{
	if (photo[i] > 0)		// Don't bother displaying zeroes
	{
		TxChar(254);		// Command prefix
		TxChar(108);		// draw a line
		TxChar(i);			// from x-location
		TxChar(photo[i]);	// height = measured data
		TxChar(i);			// vertical line at x
		TxChar(0);			// reference location y=0
	}
}
}//END DisplayData

void TxChar(char TxVal)
{
unsigned char i;

clear_bit( latb, soft_TX_BIT ); // Start bit
delay_us( TxDel );				// bit time

for (i=0; i<8; i++)
{
	if (test_bit( TxVal, i ))		// Set TX line to bit of TxVal
	{
		set_bit( latb, soft_TX_BIT );
	}
	else
	{
		clear_bit( latb, soft_TX_BIT );
	}	
	delay_us( TxDel );			// bit time
}
set_bit( latb, soft_TX_BIT );	// Stop bit
delay_us( TxDel );				// bit time
}//END

void DrawBox(unsigned char x1,unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour) // To draw control gates on LCD
{
TxChar(254);				// Command prefix
TxChar(114);				// draw a box
TxChar(colour);
TxChar(x1);	
TxChar(y1);				
TxChar(x2);	
TxChar(y2);
}//END

void startpulse(void) 	// bit bang an overlapping clock
{												//			 	 _____
set_bit(portc,1); 		 //  SI is a pulse on portc.1	  __|    |__
delay_us(clk);			//	generate  quarter wave delay 	 _____					
set_bit(portc,0);		//  clk is delayed portc.0      _____|    |__
delay_us(clk);								
clear_bit(portc,1);
delay_us(clk); 
clear_bit(portc,0);
delay_us(clk);			// 	
}//END

void clkout(void)	// bit bang one full clock cycle
{
set_bit(portc,0);		// one pulse up
delay_us(clk);			//
clear_bit(portc,0);		// one down
delay_us(clk);			// generates a full clock cycle 
} End of Code

Link to post
Share on other sites

rfhaley,

:huh: OK Here is a chopped down version that demonstrates the problem.
Its still alot of code.

How would one run this code up without your hardware?

 

See if you can chop it down further (this brings you closer to the problem :huh: ), ideally to something where the problem can be reproduced in the SourceBoost simulator.

 

Regards

Dave

Link to post
Share on other sites

I cut the code down to an example but it works just as I expected. My larger code has something that interferes with the value of clk inside the DrawGates routine.

 

I searched every single occurrence of the word 'clk' but cannot see any unexpected changes where it could display as one fixed value and have the correct & varying value in the timing code.

I know nothing about the simulator since I am using analog inputs.

 

 

// portb.2 simply displays a varying value of clk and it's >> values
// by sending rs232 data to a Matrix Orbital GLK12232 serial graphic LCD @ 19,200

#pragma CLOCK_FREQ 20000000
#include <system.h>

#define	soft_TX_BIT	2		// Portb.2 TX bit
#define	TxDel	43			// Trim with an osc.

// Function declarations
void DrawGates();
void DrawBox(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour);	// To draw a steering box
void TxChar(char TxVal); 		// Display output on serial LCD

// Global Variables
unsigned int clk;

////////////////////////////////////////////////////////////////
void main()									
{
trisa = 00011111b;	// lower 5 PORT A inputs
trisb = 11110011b;	// DON'T BUGGER UP PORTB.0 .1 .2 .3					
trisc = 10000000b;	// all Port C outputs but RX line
clear_bit( trisb, soft_TX_BIT ); 	// set tris Tx Line output
clear_bit( latb, soft_TX_BIT );   	// set Tx Line low
	delay_ms(10);
TxChar(254);		// Command prefix
TxChar(66);		// Turn ON LCD backlight
TxChar(0);		// Forever

while (1)
{
for (clk=0; clk<=512; clk++)
{
DrawGates();
delay_ms(10);
}

for (clk=512; clk>=1; --clk)
{
DrawGates();
delay_ms(10);
}

}	
}	
void DrawGates()
{
unsigned char	clk2, clk3, clk4;	// clk bugs for feedback

TxChar(254);						// Command prefix
TxChar(88);							// Clear screen
//

clk2 = (clk >> 2);		
clk3 = (clk >> 3);						clk4 = (clk >> 4);			
DrawBox(0,clk4,3,clk4+1,1);		// Clk 'bug'	
DrawBox(4,clk3,7,clk3+1,1);		// Clk 'bug'	
DrawBox(8,clk2,10,clk2+1,1);	// Clk 'bug'
//
}//END
void DrawBox(unsigned char x1,unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour) // To draw control gates on LCD
{
TxChar(254);				// Command prefix
TxChar(114);				// draw a box
TxChar(colour);
TxChar(x1);	
TxChar(y1);				
TxChar(x2);	
TxChar(y2);
}//END


void TxChar(char TxVal)
{
unsigned char i;

clear_bit( latb, soft_TX_BIT ); // Start bit
delay_us( TxDel );				// bit time

for (i=0; i<8; i++)
{
	if (test_bit( TxVal, i ))		// Set TX line to bit of TxVal
	{
		set_bit( latb, soft_TX_BIT );
	}
	else
	{
		clear_bit( latb, soft_TX_BIT );
	}	
	delay_us( TxDel );			// bit time
}
set_bit( latb, soft_TX_BIT );	// Stop bit
delay_us( TxDel );				// bit time
}//END

Link to post
Share on other sites

I think I may see the problem? Global Clk is unsigned in but local Clk2, Clk3, Clk4 are unsigned char, therefore the maximum value is 255 for those.

 

Beany

 

 

I cut the code down to an example but it works just as I expected. My larger code has something that interferes with the value of clk inside the DrawGates routine.

 

I searched every single occurrence of the word 'clk' but cannot see any unexpected changes where it could display as one fixed value and have the correct & varying value in the timing code.

I know nothing about the simulator since I am using analog inputs.

 

 

// portb.2 simply displays a varying value of clk and it's >> values
// by sending rs232 data to a Matrix Orbital GLK12232 serial graphic LCD @ 19,200

#pragma CLOCK_FREQ 20000000
#include <system.h>

#define    soft_TX_BIT    2        // Portb.2 TX bit
#define    TxDel    43            // Trim with an osc.

// Function declarations
void DrawGates();
void DrawBox(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour);    // To draw a steering box
void TxChar(char TxVal);         // Display output on serial LCD

// Global Variables
unsigned int clk;

////////////////////////////////////////////////////////////////
void main()                                    
{
   trisa = 00011111b;    // lower 5 PORT A inputs
   trisb = 11110011b;    // DON'T BUGGER UP PORTB.0 .1 .2 .3                    
   trisc = 10000000b;    // all Port C outputs but RX line
   clear_bit( trisb, soft_TX_BIT );     // set tris Tx Line output
   clear_bit( latb, soft_TX_BIT );       // set Tx Line low
       delay_ms(10);
   TxChar(254);        // Command prefix
   TxChar(66);        // Turn ON LCD backlight
   TxChar(0);        // Forever

while (1)
{
   for (clk=0; clk<=512; clk++)
   {
   DrawGates();
   delay_ms(10);
   }
   
   for (clk=512; clk>=1; --clk)
   {
   DrawGates();
   delay_ms(10);
   }
   
}    
}    
void DrawGates()
{
unsigned char    clk2, clk3, clk4;    // clk bugs for feedback

   TxChar(254);                        // Command prefix
   TxChar(88);                            // Clear screen
//

   clk2 = (clk >> 2);        
   clk3 = (clk >> 3);                        clk4 = (clk >> 4);            
DrawBox(0,clk4,3,clk4+1,1);        // Clk 'bug'    
   DrawBox(4,clk3,7,clk3+1,1);        // Clk 'bug'    
   DrawBox(8,clk2,10,clk2+1,1);    // Clk 'bug'
//
}//END
void DrawBox(unsigned char x1,unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour) // To draw control gates on LCD
{
   TxChar(254);                // Command prefix
   TxChar(114);                // draw a box
   TxChar(colour);
   TxChar(x1);    
   TxChar(y1);                
   TxChar(x2);    
   TxChar(y2);
}//END


void TxChar(char TxVal)
{
   unsigned char i;

   clear_bit( latb, soft_TX_BIT ); // Start bit
   delay_us( TxDel );                // bit time

   for (i=0; i<8; i++)
   {
       if (test_bit( TxVal, i ))        // Set TX line to bit of TxVal
       {
           set_bit( latb, soft_TX_BIT );
       }
       else
       {
           clear_bit( latb, soft_TX_BIT );
       }    
       delay_us( TxDel );            // bit time
   }
   set_bit( latb, soft_TX_BIT );    // Stop bit
   delay_us( TxDel );                // bit time
}//END

Link to post
Share on other sites
When clk reaches 255 clk >> 2 =64, clk4 is only 16. That is where they stick; clk2 & clk3 on 32(display max) and clk4 on 16.

 

Another thought, is Clk cast to unsigned char prior to shifting right , if so this will explain your problem? Need to consider C language and examine Compiler output to verify.

 

If so you could use an intermediary allocation to ensure high order bits are shifted prior to assignment;

 

unsigned int Clktmp = Clk >> 2;

Clk2=(unsigned char) Clktmp;

 

Beany

Link to post
Share on other sites

rfhaley,

 

I modified the code in two places (see search for "dh test").

The code can then be run under the SourceBoost simulator, with clk intially going up, then down again.

 

The values of clk2, clk3, clk4 change both up and down - no stuck value.

Please try my code on the actual hardware.

 

Regards

Dave

 

#pragma CLOCK_FREQ 20000000
#include <system.h>


#define    soft_TX_BIT    2        // Portb.2 TX bit

#define    TxDel    43            // Trim with an osc.
#define array_size 128        //     TSL1401 is 128 bit device
#define swdten        0


// Function declarations
void ReadSensor(void);            // Get input dtat from sensor
void FindMaxht(void);            // Find the brightest element
void FilterData(void);            // Enhance data
void CheckBright(void);            // Automatic gain control
void DisplayData(void);
void DrawGates();
void startpulse(void);            // Overlapping SI & CLK pulses to start TSL1401
void clkout(void);                // Regular CLK sequence for read, TSL1401
void DrawBox(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour);    // To draw a steering box
void TxChar(char TxVal);         // Display output on serial LCD


// Global Variables
unsigned char DigIn, AdRes[12], UpLink[3], DigOut, contrast;
bool ComError, CommLost, ouch, binthere, Line_Found, Echo_SD, Comms_OK, DataOK;
unsigned int maxht, photo[array_size], clk;
unsigned char min, max, maxhtLoc, maxLoc, minLoc, realc, thresh, happy, band;
unsigned char HappyL, HappyH, ThreshL, ThreshH, realcL, realcH, centerL, centerH, center;
unsigned char soft_delay, errnum, Raw;
signed char request_avg, happy_avg;    // motor runs when enough requests lean Left(+ve) or Right(-ve)
volatile bit Main_D1, Main_D2, Main_SWL, Main_SWR, Per_SWL, Per_SWR, Line_Happy;
volatile bit PLC_LampON, PLC_SD, Auto, Raw_Data;

////////////////////////////////////////////////////////////////
void main()                                    // FLF_rev7.3.c
////////////////////////////////////////////////////////////////
{
unsigned char i;

// Initialize remote variables from Per board
   thresh = 4;
   contrast = 150;
   PLC_SD = true;
   PLC_LampON = false;
   Main_SWL = true;
   Main_SWR = true;
   Per_SWL = true;
   Per_SWR = true;
   Auto = false;
// Initialize flags for good data present
   binthere = false;    
   ouch = false;
   DataOK = false;
               
   trisa = 00011111b;    // lower 5 PORT A inputs
   trisb = 11110011b;    // DON'T BUGGER UP PORTB.0 .1 .2 .3                    
   trisc = 10000000b;    // all Port C outputs but RX line
   adcon1 = 00000010b;                    // Change ADC for optical input
   adcon0 = 10000001b;                    // Read from AN0 for optical input
   clk = 50;                            // Default clock setting
   clear_bit( trisb, soft_TX_BIT );     // set tris Tx Line output
   clear_bit( latb, soft_TX_BIT );       // set Tx Line low
   set_bit( trisb, 4 );                // RB4 - switch input
   set_bit( trisb, 5 );                // RB5 - switch input
   DigOut = 0xFF;                        // Reset Per board digital outputs
   DigIn = 0xFF;                        // Reset Per board digital inputs
   happy = 4;
   band = 2;
   realc = 34;
   soft_delay = 30;
   Line_Found = false;
   Echo_SD = false;
   Comms_OK = false;
   Line_Happy = false;
   TxChar(254);        // Command prefix
   TxChar(66);            // Turn ON LCD backlight
   TxChar(0);            // Forever


while (1)
{
   ReadSensor();        // operate TSL1401 sensor and fill array
   FilterData();        // Take data array and sharpen peaks
   FindMaxht();        // Find the brightest element
   CheckBright();        // Adjust clock to keep data on LCD
   DrawGates();
   DisplayData();

}    
}    
void ReadSensor(void)
{
   volatile bit A2D_not_done@0x0FC2.2;        // bit 2 of adcon0
   unsigned char i;
// Optical Sensor DATA from AN0
// clear out old data that accumulates between reads
//
//    
   startpulse();            // generate the si & clk to start the workings
   for (i = 0; i < array_size;  i++)
   {                            
   clkout();                // clears out saturated data to /dev/null
   }
   clkout();
//                
// get new Optical Sensor data
//
   startpulse();     // Sends SI overlapping CLKOUT pulses to start reading data
   for ( i = 0; i < array_size; i++)
   {
       clkout();                // clock to next pixel
       set_bit(adcon0, 2);        // read analog input0 until adcon0.2 drops to zero
// dh test        while (A2D_not_done);    // Wait for a2d done flag to change
       photo[i] = adresh;         // store data in array 
   } 
   clkout();    
}//END

void FilterData(void)
{
// Filter Optical Data to sharpen line edges
// Using Haley Filter algorithm (c)2005
unsigned char i, j;
short sum, count, average, remove;
   // Massage data
   // Run data through filter 'j' times

   for (j=0; j <= 2; j++)
       {
           sum = 0;
           count = 0;
   // Start by getting the average value
           for (i=0; i < array_size; i++)
           {
               if (photo[i] > 0)
               {
                   sum = sum + photo[i];
                   count++;
               }
           }    // endfor i
   average = sum/count;        // average height (brightness)
   
// and by removing some signal from all
   remove = ((average >> 1)+ 6);
           for (i=0; i < array_size; i++)
           {
               if (photo[i] <= remove) 
               {
                   photo[i] = 0;
               }
           
               else
               {
                   photo[i] = (photo[i] - remove);
               }    

           }    // endfor i
       } // endfor j

}// END Filter Optical Data

void FindMaxht(void)
{
unsigned char i;
//
   maxht = 0;
   for (i = 0; i < array_size; i++)
   {                                // Find the brightest element
       if (photo[i] > maxht) 
       {
           maxht = photo[i];
           maxhtLoc = i;
       }
   }
       maxLoc = maxhtLoc + 6;        //    Look near brightest only
       minLoc = maxhtLoc - 6;
       
}    // END FindMaxht

void CheckBright(void)
{
//
{	// dh test
	static bit down = 0;
	if( (clk > 600 || down) && clk > 10 ) 
	{
		down = true;
		clk -=10;
		return;
	}	
	down = false;
}

   if (maxht > 150) clk = clk - 40;        // WAAY Too Bright
   if (maxht > 60) clk = clk - 20;            // Far Too Bright
   if (maxht > 45) clk = clk - 10;            // Too Bright
   if (maxht > 30) clk = clk - 4;            // a bit Too Bright
   if (maxht < 24) clk = clk + 4;            // a bit Too Dim
   if (maxht < 15) clk = clk + 7;            // Too Dim
   if (maxht < 10) clk = clk + 10;            // Much Too Dim
   if (clk < 5) 
   {
       ouch = true;
   }        // Limit clock high speed for A2D
   else
   {
       ouch = false;        // OK when clk rises
   }

}//END CheckBright

void DrawGates()
{
   ouch = false;
   TxChar(254);                        // Command prefix
   TxChar(88);                            // Clear screen
//
//    Display Control gates for motor ON & OFF locations on LCD    

// Aids for dimwitted programmer    
//    centerH = maxhtLoc + 2;
//    centerL = maxhtLoc - 2;
//    realcL = realc - 1;
//    realcH = realc + 1;
//////////////////////////////////////////////////////////////////////////////////
////
unsigned char    clk2 = (clk >> 2);        // HELP!!!
                           // if clk exceeds 255 clk2 & clk3
unsigned char    clk3 = (clk >> 3);        // will remain at 32 even when clk drops down.
                           // When clk returns to normal values my LCD image
unsigned char    clk4 = (clk >> 4);        // is fine. When I reset, the feedback 'bugs' drop
                           // back to normal and the display is stable (before & after)
   

   DrawBox(0,clk4,3,clk4+1,1);        // Clk 'bug'    set last digit 
   DrawBox(4,clk3,7,clk3+1,1);        // Clk 'bug'    to 0 to hide bugs
   DrawBox(8,clk2,10,clk2+1,1);    // Clk 'bug'

}    //END DrawGates

void DisplayData(void)
{
unsigned char i;

   for (i = minLoc; i <= maxLoc; i++)
   {
       if (photo[i] > 0)        // Don't bother displaying zeroes
       {
           TxChar(254);        // Command prefix
           TxChar(108);        // draw a line
           TxChar(i);            // from x-location
           TxChar(photo[i]);    // height = measured data
           TxChar(i);            // vertical line at x
           TxChar(0);            // reference location y=0
       }
   }
}//END DisplayData

void TxChar(char TxVal)
{
   unsigned char i;

   clear_bit( latb, soft_TX_BIT ); // Start bit
   delay_us( TxDel );                // bit time

   for (i=0; i<8; i++)
   {
       if (test_bit( TxVal, i ))        // Set TX line to bit of TxVal
       {
           set_bit( latb, soft_TX_BIT );
       }
       else
       {
           clear_bit( latb, soft_TX_BIT );
       }    
       delay_us( TxDel );            // bit time
   }
   set_bit( latb, soft_TX_BIT );    // Stop bit
   delay_us( TxDel );                // bit time
}//END

void DrawBox(unsigned char x1,unsigned char y1, unsigned char x2, unsigned char y2, unsigned char colour) // To draw control gates on LCD
{
   TxChar(254);                // Command prefix
   TxChar(114);                // draw a box
   TxChar(colour);
   TxChar(x1);    
   TxChar(y1);                
   TxChar(x2);    
   TxChar(y2);
}//END

void startpulse(void)     // bit bang an overlapping clock
{                                                //                  _____
   set_bit(portc,1);          //  SI is a pulse on portc.1      __|    |__
   delay_us(clk);            //    generate  quarter wave delay      _____                    
   set_bit(portc,0);        //  clk is delayed portc.0      _____|    |__
   delay_us(clk);                                
   clear_bit(portc,1);
   delay_us(clk); 
   clear_bit(portc,0);
   delay_us(clk);            //     
}//END

void clkout(void)    // bit bang one full clock cycle
{
   set_bit(portc,0);        // one pulse up
   delay_us(clk);            //
   clear_bit(portc,0);        // one down
   delay_us(clk);            // generates a full clock cycle 
}

Link to post
Share on other sites

Thanks Dave but No. I used your 600 as well as 300. 300 causes a loop that simply counts the clk down to 10 and restarts. I think 600 was too big for another line that limits the clock.

 

 

BeanBrain had me all excited but I couldn't get that int/char stuff to change anything. When the signal rises & falls at clk<255 all is well. After clk has passed 255, clk2&3 stick. If clk4 gets to 32 it sticks as well. I tried keeping all info sent to the display <32, no help, besides my photo is often above 32.

Still trying

Link to post
Share on other sites

rfhaley,

BeanBrain had me all excited but I couldn't get that int/char stuff to change anything. When the signal rises & falls at clk<255 all is well. After clk has passed 255, clk2&3 stick. If clk4 gets to 32 it sticks as well. I tried keeping all info sent to the display <32, no help, besides my photo is often above 32.

Still trying

How do you know that clk2, clk3 and clk4 stick?

Maybe something is going wrong with the display update?

 

Regards

Dave

Link to post
Share on other sites

I thought of that too. Usually clk4 will continue to work after clk2&3 are stuck because I haven't dimmed things too far.

   DrawBox(0,clk4,3,clk4+1,1);        // Clk 'bug'    set last digit 
  DrawBox(4,clk3,7,clk3+1,1);        // Clk 'bug'    to 0 to hide bugs
  DrawBox(8,clk2,10,clk2+1,1);    // Clk 'bug'

Is the way it is in my code. How can two of three fail to update when they run in sequence?

I think I'll limit clk to 255 and leave it except as an exercise in the inner workings of compilers.

Link to post
Share on other sites

rfhaley,

I thought of that too. Usually clk4 will continue to work after clk2&3 are stuck because I haven't dimmed things too far.

   DrawBox(0,clk4,3,clk4+1,1);        // Clk 'bug'    set last digit 
  DrawBox(4,clk3,7,clk3+1,1);        // Clk 'bug'    to 0 to hide bugs
  DrawBox(8,clk2,10,clk2+1,1);    // Clk 'bug'

Is the way it is in my code. How can two of three fail to update when they run in sequence?

I think I'll limit clk to 255 and leave it except as an exercise in the inner workings of compilers.

Its sounds bizzare, I can't see how a variable could get stuck, therefore it makes me think the update to display gets stuck rather than the value itself. Consider outputing the value another way, eg direct onto a port.

Also consider something like this:

    ....
   if( myInput )
   {
       clk2  = 0;
       clk3  = 0;
       clk4  = 0;
    }
  DrawBox(0,clk4,3,clk4+1,1);        // Clk 'bug'    set last digit 
  DrawBox(4,clk3,7,clk3+1,1);        // Clk 'bug'    to 0 to hide bugs
  DrawBox(8,clk2,10,clk2+1,1);    // Clk 'bug'

When its gets stuck, turn the input on and the value will be zero while the input is on, its is stuck going to be something todo with drawbox.

 

Regards

Dave

Link to post
Share on other sites

OK it drops the bugs to a value when I enable my switch. DrawBox is just a set of LCD commands to display a rectangle. i also tried the code instead of the function DrawBox.

I turned the bugs on ear so they can traverse the 122 pixels across the LCD. The bugs Do Not stick they just seem to pick up an offset of about 64-84(hard to guess). They could not drop below 32 and appear to move in the vertical axis before because of the 32 pixel high display.

The bugs move left/right properly until clk>>4 reaches 16 then they get a lower bound. Reset or closing the switch will shake them loose.

Reset causes the bugs to return to normal function if they are in range.

My switch sends the bugs to 2 then they climb back up to a silly value when the switch is released. I say climb because they are taking several cycles of my code to stabilize.

Link to post
Share on other sites

rfhaley,

OK it drops the bugs to a value when I enable my switch. DrawBox is just  a set of LCD commands to display a rectangle. i also tried the code instead of the function DrawBox.

I turned the bugs on ear so they can traverse the 122 pixels across the LCD. The bugs Do Not stick they just seem to pick up an offset of about 64-84(hard to guess).  They could not drop below 32 and appear to move in the vertical axis before because of the 32 pixel high display.

The bugs move left/right properly until clk>>4 reaches 16 then they get a lower bound. Reset or closing the switch will shake them loose.

Reset causes the bugs to return to normal function if they are in range.

My switch sends the bugs to 2 then they climb back up to a silly value when the switch is released. I say climb because they are taking several cycles of my code to stabilize.

Maybe the clk value is not changing as you expect, what about:

   ....
  if( myInput )
  {
      clk  = 0;
   }
   
   unsigned char    clk2 = (clk >> 2);        // HELP!!!
                          // if clk exceeds 255 clk2 & clk3
   unsigned char    clk3 = (clk >> 3);        // will remain at 32 even when clk drops down.
                          // When clk returns to normal values my LCD image
   unsigned char    clk4 = (clk >> 4);        // is fine. When I reset, the feedback 'bugs' drop
                          // back to normal and the display is stable (before & after)
  
  DrawBox(0,clk4,3,clk4+1,1);        // Clk 'bug'    set last digit 
  DrawBox(4,clk3,7,clk3+1,1);        // Clk 'bug'    to 0 to hide bugs
  DrawBox(8,clk2,10,clk2+1,1);    // Clk 'bug'

This will force clk to zero and allow you to see if your 'bugs' follow.

 

Regards

Dave

Link to post
Share on other sites

Very kinky! Clicking my switch sends clk to 20 and the bugs reset to normal function. I renamed clk to clock so I have seen every instance but it still seems like 'the variable formerly known as'clk has an overlap in global/local scope.

 

I passed clock to the function and made it local, DrawGates(int clk) called by DrawGates(clock); Now the bugs drop but return to the offset condition. It seems as though clock exists in two states in the main program.

 

Is there a problem with sending an unsigned int to TxChar( char)? How can I chop a 16bit variable into an 8bit?

Link to post
Share on other sites
Very kinky! Clicking my switch sends clk to 20 and the bugs reset to normal function. I renamed clk to clock so I have seen every instance but it still seems like 'the variable formerly known as'clk has an overlap in global/local scope.
If this is so it should be evident in the asm code. By looking at the variables addresses, the global should exist at address not used by any other variables. Send a bad asm file to support@sourceboost.com and I'll take a quick look.

 

I passed clock to the function and made it local, DrawGates(int clk) called by DrawGates(clock); Now the bugs drop but return to the offset condition. It seems as though clock exists in two states in the main program.

 

Is there a problem with sending an unsigned int to TxChar( char)? How can I chop a 16bit variable into an 8bit?

This should not cause a problem, you just lose the top 8 bits. If you want to prevent the warning generated by the compiler you can tell it this is what you want to do explicitly by "casting" the value to an 8 bit using:

TxChar( (char) myvar );

 

Regards

Dave

Link to post
Share on other sites

rfhaley,

 

Looking at the assembler output there is no evidence of clk's memory space being overwritten with another variables data :huh:.

 

I would suggest that your control of the clk variable is bad.

The clk variable looks like its acting as an integrator or the maxht variable, so its a function of the maxht value and time.

If maxht < 30, clk stays as it is, or goes up in value. Somehow maxht must be staying < 30, which it will when the brightness is in the correct range.

 

So I would say the algorithm is wrong - or maybe I don't understand what its meant to be doing.

 

BTW: You think that clk has the correct because the image is correct, but you are using clk as the argument to the delay_us function, which has an 8 bit argument and you are trying to pass a 16bit argument, so you will get a delay that is only the bottom 8 bits of clk value - ie upper bits maybe set and you would not know looking at the delay.

 

Have fun.

 

Regards

Dave

Link to post
Share on other sites

rfhaley,

 

I think your function CheckBright() is not correct:

void CheckBright(void)
{
//
   if (maxht > 150) clk = clk - 40;        // WAAY Too Bright
   if (maxht > 60) clk = clk - 20;            // Far Too Bright
   if (maxht > 45) clk = clk - 10;            // Too Bright
   if (maxht > 30) clk = clk - 4;            // a bit Too Bright
   if (maxht < 24) clk = clk + 4;            // a bit Too Dim
   if (maxht < 15) clk = clk + 7;            // Too Dim
   if (maxht < 10) clk = clk + 10;            // Much Too Dim
   if (clk < 5) 
   {
       ouch = true;
   }        // Limit clock high speed for A2D
   else
   {
       ouch = false;        // OK when clk rises
   }

}//END CheckBright

You don't check clk against under or overflow. Your initial value of clk is 50. If maxht>30 eventualy clk will underflow and have a large value. And if maxht<24 clk will increase but it will take a much longer time to overflow.

Link to post
Share on other sites
rfhaley,

 

I think your function CheckBright() is not correct:

void CheckBright(void)
{
//
   if (maxht > 150) clk = clk - 40;        // WAAY Too Bright
   if (maxht > 60) clk = clk - 20;            // Far Too Bright
   if (maxht > 45) clk = clk - 10;            // Too Bright
   if (maxht > 30) clk = clk - 4;            // a bit Too Bright
   if (maxht < 24) clk = clk + 4;            // a bit Too Dim
   if (maxht < 15) clk = clk + 7;            // Too Dim
   if (maxht < 10) clk = clk + 10;            // Much Too Dim
   if (clk < 5) 
   {
       ouch = true;
   }        // Limit clock high speed for A2D
   else
   {
       ouch = false;        // OK when clk rises
   }

}//END CheckBright

You don't check clk against under or overflow. Your initial value of clk is 50. If maxht>30 eventualy clk will underflow and have a large value. And if maxht<24 clk will increase but it will take a much longer time to overflow.

CheckBright will only change clk once for each loop.

Each time clk is altered the entire program loop runs again so I get a corrected image and a new value for maxht. Above: if (clk<5), ouch will display an error and stop controlling the motors. Elsewhere clk is given an upper bound, some versions were as small as if(clk>0x01FF) clk=0x01FF;

Thanks for looking

Link to post
Share on other sites

Bang On Dave! I'll bet the light integration delay suddenly goes from 255us to 1us as clk increases. clk would act like a ramp instead of a linear delay.

As clk comes back down past that boundary the sudden shift from nice image to totally blinded will send my sensor nuts. Who knows what happens to maxht then?

A 16bit delay might be in order.

I will let you know, thanks.

Link to post
Share on other sites

I cobbled together a 16 bit delay for my sensor and :huh: ZING! :lol:

void delay16_us()
{
unsigned char i, HiB;
HiB = 0;
HIBYTE(HiB,clk);
if (HiB > 0)
{
   for (i=1; i <= HiB; i++)
   {
      delay_us(0xFD);	// just a number near FF		
   }	
}
else
{
   delay_us(clk);			
}	
}

Problem solved :huh:

That wasn't tough enough so I made my sensor data the full 10bits from the A2D. Now I need some tuning on sensitivity settings but I feel so much better. Thanks to all for looking at least. B)

Link to post
Share on other sites

You may need to do some bounds checking in this function:

 

void FindMaxht(void)
{
unsigned char i;
//
  maxht = 0;
  for (i = 0; i < array_size; i++)
  {                                // Find the brightest element
      if (photo[i] > maxht) 
      {
          maxht = photo[i];
          maxhtLoc = i;
      }
  }
      maxLoc = maxhtLoc + 6;        //    Look near brightest only
      minLoc = maxhtLoc - 6;
      
}    // END FindMaxht

If maxhtLoc is between 0 and 5 then minLoc will be set outside of the photo array.

 

If maxhtLoc is between array_size-5 and array_size then maxLoc will be set outside of the photo array.

Link to post
Share on other sites

Good point, Thanks.

Now, when the light suddenly increases (I yank open the iris) the program crashes badly and produces about one second chunks of garbage. I will adjust the brightness coefficients and the bounds too I guess.

One f-stop equals a doubling of light so I changed my simple addition to clk into multiplication for large variances. Here are my present settings.

void CheckBright(void)
{
//
// all display bits raised by *4 in V7.4
// using 10 bit A2D data in photo[i]
//	shifted 2 bits right for display on 32 pixel display
if (maxht > 2000) clk /= 32;		// AIEEE!
if (maxht > 960) clk /= 16;		// WAAY Too Bright
if (maxht > 480) clk /=8;		// Far Too Bright
if (maxht > 240) clk /=4;		// Too Bright
if (maxht > 160) clk -=8;
if (maxht > 120) clk -=4;		// a bit Too Bright
if (maxht < 100) clk +=2;		// a bit Too Dim
if (maxht < 60) clk +=4;		// Too Dim
if (maxht < 32) clk *=2;		// Much Too Dim
if (maxht < 12) clk *=4;
if (clk < 5) 
{
	ouch = true;
}		// Limit clk high speed for A2D
else
{
	ouch = false;		// OK when clk rises
}
if (clk > 0x6FFF)clk= 0x0FFF;
}//END CheckBright

Notice that my display values have increased by >>2. This is a result of using 10 bit data. To display I drop the two least significant bits to display 8bit data.

The first change I intend is to reduce the upper changes.

Link to post
Share on other sites

All better. The multiple if statements can overlap and add together so I reduced them. Example: maxht > 2000 subtracts 100,60,45,25,8 & 4. Clk is also given a lower bound (it must have gotten lost somewhere).

void CheckBright(void)
{
//
// all display bits raised by *4 in V7.4
// using 10 bit A2D data in photo[i]
//	shifted 2 bits right for display on 32 pixel display
if (maxht > 2000) clk -= 100;	// AIEEE!
if (maxht > 960) clk -= 60;		// WAAY Too Bright
if (maxht > 480) clk -= 45;		// Far Too Bright
if (maxht > 240) clk -= 25;		// Too Bright
if (maxht > 160) clk -= 8;
if (maxht > 120) clk -= 4;		// a bit Too Bright
if (maxht < 100) clk += 2;		// a bit Too Dim
if (maxht < 60) clk += 5;		// Too Dim
if (maxht < 32) clk += 10;		// Much Too Dim
if (maxht < 12) clk += 20;
if ((clk <= 5) || (clk >= 0xEFFF))
{
	ouch = true;
	clk = 5;
}		// Limit clk high speed for A2D
else
{
	ouch = false;		// OK when clk rises
}
if (clk > 0xEFFF)clk = 0xEFFF;
}//END CheckBright

 

 

I also revisited the sensor code I wrote about 18 months ago when I was just starting out. Now it clocks the sensor at what I calculate as full speed. I clear the saturated data that has been exposing during the rest of my loop, delay one integration period 100us*clk and then read the fresh data at full speed.

This required another 16 bit delay function.

// Optical Sensor DATA from AN0
// clear out old data that accumulates between reads
//
//	
startpulse(10);			// generate the si &clkto start the workings
for (i = 0; i < array_size;  i++)
{							
ckout();				// clears out saturated data to /dev/null
}
ckout();				// *** THESE CLKOUT ADD UP TO INTEGRATION TIME
//				
// get new Optical Sensor data ** CAN BE DONE QUICKLY USING CKOUT
//
       delay16_100us();  // INTEGRATION TIMER TO EXPOSE SENSOR CORRECTLY
//
startpulse(10); 	// Sends SI overlapping CLKOUT pulses to start reading data
for ( i = 0; i < array_size; i++)
{
	ckout();				// clk to next pixel
	set_bit(adcon0, 2);		// read analog input0 until adcon0.2 drops to zero
	while (A2D_not_done);	// Wait for a2d done flag to change
	MAKESHORT(tmp,adresl,adresh);	// store data in array 
	photo[i] = tmp;
} 
ckout();	
}//END

Problem solved. out

Link to post
Share on other sites

I am a little confused by your CheckBright function.

 

void CheckBright(void)
{
//
// all display bits raised by *4 in V7.4
// using 10 bit A2D data in photo[i]
//    shifted 2 bits right for display on 32 pixel display
   if (maxht > 2000) clk -= 100;    // AIEEE!
   if (maxht > 960) clk -= 60;        // WAAY Too Bright
   if (maxht > 480) clk -= 45;        // Far Too Bright
   if (maxht > 240) clk -= 25;        // Too Bright
   if (maxht > 160) clk -= 8;
   if (maxht > 120) clk -= 4;        // a bit Too Bright
   if (maxht < 100) clk += 2;        // a bit Too Dim
   if (maxht < 60) clk += 5;        // Too Dim
   if (maxht < 32) clk += 10;        // Much Too Dim
   if (maxht < 12) clk += 20;
   if ((clk <= 5) || (clk >= 0xEFFF))
   {
       ouch = true;
       clk = 5;
   }        // Limit clk high speed for A2D
   else
   {
       ouch = false;        // OK when clk rises
   }
   if (clk > 0xEFFF)clk = 0xEFFF;
}//END CheckBright

It looks like when maxht is 2001 or more then clk gets 100 subtracted from it, then 60, then 45, then 25, then 8, then 4.

 

When it all done a total of 242 is subtracted from clk.

 

Is this what you wanted to happen?

 

Seems like that same kind of thing hapnens on the "too dim" side as well.

Link to post
Share on other sites

Yes, but I must remember that the number I choose to subtract is only one of the parts being subtracted. The farther I am from displaying 0-32 the faster I want to respond. Even with these strange numbers it can take 2 seconds to stabilize. When clk is low my loop runs about 10/sec. Any faster and my LCD fades into grey on white. When the light is dimmer the integration time is longer to collect more light so I loop around slower; as low as 2/sec.

Maybe if I had one process reading samples and another displaying? Novo rtos?

Still my serial display seems to be the limiting code. A parallel display would solve a lot but I would need more silicon than the EZ provides.

Has anybody tried a 'Pic Module'?

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...