CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

polling
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
spudtheimpaler



Joined: 16 Mar 2005
Posts: 6
Location: Birmingham University

View user's profile Send private message

polling
PostPosted: Wed Mar 16, 2005 7:37 am     Reply with quote

Hi all. I am having some serious trouble with what should be a very simple problem.

I am in a group trying to design a line following robot for a university project. We have three sensors which are active low on the line and high off the line (Due to inverting op-amp amplification) so when we input we should have a variable

sensorValue = input_d();

sensorValue being 0x05 (101) if moving forward along the line, 0x01 (001)if it is turning right and need to turn left, and 0x04 (100) if we need to turn right. As such, i wrote the simple code below to test the sensors.

Code:

////////////////////////////////
//
//
//  EE2G2 Robot Code
//  Group 29
//  possible_interupt_code.c
//  10/03/05
//  Auther: Mitchell Kent
//  Editors:
//
//
//  This is code to try out the motor lookup tables routines
//
//
////////////////////////////////

#include <16F877.h>
#use delay(clock=10000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT
#define FOREVER 1
const int LOOKUPTABLE_F[8] = { 0xcc, 0x44, 0x66, 0x22, 0x33, 0x11, 0x99, 0x88 };
const int LOOKUPTABLE_L[16] = { 0xcc, 0xc4, 0x46, 0x42, 0x63, 0x61, 0x29, 0x28, 0x3c, 0x34, 0x16, 0x12, 0x93, 0x91, 0x89, 0x88 }; //This code should run the right wheel twice for every once of the left, thus turning right overall.};
const int LOOKUPTABLE_R[16] = { 0xcc, 0x4c, 0x64, 0x24, 0x36, 0x16, 0x92, 0x82, 0xc3, 0x43, 0x61, 0x21, 0x39, 0x19, 0x98, 0x88 }; //This code should run the left wheel twice for every once of the right, thus turning right overall.
const int LOOKUPTABLE_FULL_F[4] = { 0x66, 0x33, 0x99, 0xcc };
const int LOOKUPTABLE_FULL_R[8] = { 0x66, 0x36, 0x93, 0xc3, 0x69, 0x39, 0x9c, 0xcc };
const int LOOKUPTABLE_FULL_L[8] = { 0x66, 0x63, 0x39, 0x3c, 0x96, 0x93, 0xc9, 0xcc  };

volatile int sensorValue = 0x01;

int index = 0;


main()
{

   output_high(PIN_A0);
   delay_ms(5);




      while( 1 )
      {
         sensorValue=0x00;
         sensorValue=input_d();
         delay_cycles(1);



               if(sensorValue == 0x01)
               {
                  //Move Right
                  for(index = 0; index<8; index++)  //loop throughout the table
                  {
                     output_c(LOOKUPTABLE_FULL_R[index]); //Use the right direction lookup table
                     delay_ms(150);

                  }
               }

              else if(sensorValue == 0x05)
              {
                //Move forwards
                 for(index = 0; index<4; index++)
                 {
                    output_c(LOOKUPTABLE_FULL_F[index]);  //Use the lookup table that sends both motors at the same pace
                    delay_ms(150);
                 }
              }
             
               else if(sensorValue == 0x04 )
               {
                  //Move Left
                  for(index = 0; index<8; index++)
                  {
                     output_c(LOOKUPTABLE_FULL_L[index]);  ////Use the left direction lookup table
                     delay_ms(150);

                  }
               }



               else{ output_c(0xFF); delay_ms(4); } //I'll expliain this lines purpose shortly

               output_low(PIN_B0);
               delay_ms(4);

 

  } //Exit while(1) loop


}// Exit Main


This appeared to work fine at first but showed odd behaviour. When the sensorValue was forward 0x05 the stepper motors (or leds showing stepper motor movement) moved as they should, the same left, and the same right. BUT after going forwards, then left, then right, then forwards (which all worked as expected) on turn left again the leds would indicate the pic was entering the last else state (output_d(0xFF)) And this happens reliably every time. you can go forwards, left, forwards, left, forwards, left, infinitely it would appear with expected behaviour, but once you turn right, it will never again go into the turn left else if statement.

Does anyone have an explanation for this odd behaviour? It isnt the chip, as i have tried on three different PIC16F877s all with the same effect.

I have tried if statements alone, else ifs, while loops, my current attempt is

Code:
////////////////////////////////
//
//
//  EE2G2 Robot Code
//  Group 29
//  possible_interupt_code.c
//  10/03/05
//  Auther: Mitchell Kent
//  Editors:
//
//
//  This is code to try out the motor lookup tables routines
//
//
////////////////////////////////

#include <16F877.h>
#use delay(clock=10000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT
#define FOREVER 1
const int LOOKUPTABLE_F[8] = {0xcc, 0x44, 0x66, 0x22, 0x33, 0x11, 0x99, 0x88 };
const int LOOKUPTABLE_L[16] = { 0xcc, 0xc4, 0x46, 0x42, 0x63, 0x61, 0x29, 0x28, 0x3c, 0x34, 0x16, 0x12, 0x93, 0x91, 0x89, 0x88 }; //This code should run the right wheel twice for every once of the left, thus turning right overall.};
const int LOOKUPTABLE_R[16] = { 0xcc, 0x4c, 0x64, 0x24, 0x36, 0x16, 0x92, 0x82, 0xc3, 0x43, 0x61, 0x21, 0x39, 0x19, 0x98, 0x88 }; //This code should run the left wheel twice for every once of the right, thus turning right overall.
const int LOOKUPTABLE_FULL_F[4] = { 0x66, 0x33, 0x99, 0xcc };
const int LOOKUPTABLE_FULL_R[8] = { 0x66, 0x36, 0x93, 0xc3, 0x69, 0x39, 0x9c, 0xcc };
const int LOOKUPTABLE_FULL_L[8] = { 0x66, 0x63, 0x39, 0x3c, 0x96, 0x93, 0xc9, 0xcc  };

volatile int sensorValue = 0x01; //Make them volatile so a change in interrupt ALSO means a change in main
int index = 0;



main()
{
   setup_adc_ports( NO_ANALOGS );
   output_high(PIN_A0);
   delay_ms(5);

 
   while(1)
   {


               output_d(0xFF);  //Vain attempt at flushing the input port
               delay_cycles(1);
               output_d(0x00);
               delay_cycles(1);
               set_tris_d(0xFF);





         delay_cycles(1);
         output_high(PIN_B0);



               if(!input(PIN_D1))
               {
                  if(!input(PIN_D0))
                  {
                     //Move Right
                     for(index = 0; index<16; index++)  //loop throughout the table
                     {
                        output_c(LOOKUPTABLE_R[index]); //Use the right direction lookup table
                        delay_ms(50);

                     }
                  }

                  else if(!input(PIN_D2))
                  {
                                    //Move Left
                     for(index = 0; index<16; index++)
                     {
                        output_c(LOOKUPTABLE_L[index]);  //Use the left direction lookup table
                        delay_ms(50);

                     }
                  }

                  else
                  {
                     //Move Forwards
                     for(index = 0; index<8; index++)
                     {
                        output_c(LOOKUPTABLE_F[index]);  //Use the lookup table that sends both motors at the same pace
                        delay_ms(50);
                     }
                  }
               }

               else{ output_c(0xFF); delay_ms(500); output_d(0x00); delay_ms(500); }

               output_d(0xFF);  //vain attempt to flush variable
               delay_cycles(1);
               output_d(0x00);
               delay_cycles(1);
               set_tris_d(0xFF);





               output_low(PIN_B0);
               delay_ms(4);

   } //Exit while(1) loop


}// Exit Main


Can you see the desperation forming?

If there is anyone who can see any flaws in the code i would greatly appreciate it. I am desperate!

Many thanks

Mitch

PIC16f877
using 10MHz external crystal
inputs on port d outputs port c
Id tell you which compiler version im using, but cant find it in the help menu etc but its pcw c compiler ide on the top bar.

PS Is it common to have so much trouble posting here? I've had an error screen on preview posting in excess of ten times already, ive logged out and back in and everything!
Ttelmah
Guest







PostPosted: Wed Mar 16, 2005 8:05 am     Reply with quote

Are you sure about your return values?. Personally, I'd have expected that you might (in the 'turn right' example), see '011', sometimes instead of 001, depending on the responses of the sensors, and the width of the line. Remember that even if you have 'tested' the sensors with a meter, the responses at speed may well differ. Your 'turn' algorithm, is also quite violent, so the motion will not be smooth, and may make the tendency to overshoot worse.
My suspicion is that the sensitivity of the right and left sensors differs a little, and you are getting to this sort of 'unexpected' behaviour in one direction. This then results in hitting the last state.
I'd suggest testing with a switch statement like:
[code]
switch (sensorValue) {
case 0b001:
case 0b011:
//Here 'right'

break
case 0b101:
//Here straight

break;
case 0b100:
case 0b110:
//Here left

break;
}
You could also add tests for the 010 state (you have found a second line!), and the 111 state (you are off the line). Do this, rather tan adding a 'default', since the compiler will generate a faster 'table based' switch, if just the required states are present. You could consider seperating the '011', and '001' states, and turning more violently in one case.

Best Wishes
Guest








Try this
PostPosted: Wed Mar 16, 2005 8:08 am     Reply with quote

Your test with else if is not too clearl, As I read it a switch will do the same thing.
If this does not work I'd check the sensor values.

main()
{
output_high(PIN_A0);
delay_ms(5);

while( 1 )
{
sensorValue=0x00;
sensorValue=input_d();
delay_cycles(1);

switch(sensorValue)
{
case 0X01: // Move Right
for(index = 0; index<8; index++) //loop throughout the table
{
output_c(LOOKUPTABLE_FULL_R[index]); //Use the right direction lookup table
delay_ms(150);
}
break;
case 0x05: // Move forwards
for(index = 0; index<4; index++)
{
output_c(LOOKUPTABLE_FULL_F[index]); //Use the lookup table that sends both motors at the same pace
delay_ms(150);
}
break;
case 0x04: // Move Left
for(index = 0; index<8; index++)
{
output_c(LOOKUPTABLE_FULL_L[index]); ////Use the left direction lookup table
delay_ms(150);

}
break;
deafult:
output_c(0xFF); delay_ms(4);
break;
}

output_low(PIN_B0);
delay_ms(4);

} //Exit while(1) loop

}// Exit Main
spudtheimpaler



Joined: 16 Mar 2005
Posts: 6
Location: Birmingham University

View user's profile Send private message

PostPosted: Wed Mar 16, 2005 8:15 am     Reply with quote

At present we are manually setting the sensors to give 0 or 1 values, IE the sensors aren't even plugged into the output, we're just using high/ low values - This way we know the input going in is what we expect.
I have plans for adding a more violent turn on the more extreme cases but i wanted to try and keep it simple whilst i was debugging the problem above.

So basically we know what the inputs are (which will eventually be from the sensors), was just windering why it was not entering the else if(sensorValue == 0x04), (when we know the sensor value SHOULD be 0x04 cause we are inputting it manually) when it should be.

I will however take you advice and write it in a switch(sensorValue){ case: setup - i didn't know this was valid in PIC C.


Thank you for looking over it, greatly appreciated!

Mitch
GRR!
Guest







PostPosted: Wed Mar 16, 2005 8:54 am     Reply with quote

GRR! Even with the switch clause the thing is not doing as its told :(

When we start the pic up in a particular state (by state, i'm referring to the different sensor setups) the apt switch case is implemented. If you then change the state, the correct case is implemented, but after that, if another change is made, kupput, the thing does something random. Well its not entirely random - if we do something in the default case, this is implemented, but there is no association between a known sensor state and what it is doing.
Guest








PostPosted: Wed Mar 16, 2005 9:10 am     Reply with quote

spudtheimpaler wrote:
At present we are manually setting the sensors to give 0 or 1 values, IE the sensors aren't even plugged into the output, we're just using high/ low values - This way we know the input going in is what we expect.
I have plans for adding a more violent turn on the more extreme cases but i wanted to try and keep it simple whilst i was debugging the problem above.

So basically we know what the inputs are (which will eventually be from the sensors), was just windering why it was not entering the else if(sensorValue == 0x04), (when we know the sensor value SHOULD be 0x04 cause we are inputting it manually) when it should be.

I will however take you advice and write it in a switch(sensorValue){ case: setup - i didn't know this was valid in PIC C.

Thank you for looking over it, greatly appreciated!

Mitch

How are you setting the sensor values ?
If it's by a mechanical switch you may get all sorts of values as the switch bounces.

The (code) switch will only respond to the case Value: and of course the default everytime there is no valid case.
Which is why I suggested using the switch.

I did not check your lookup table values because I don't know what they really do. Could you have a bad value ?

I'd say the Sensor of lookup table is to be investigated.
You say you are in a panic mode. Sometimes it helps to leave it alone got do somthing else and come back to it with a fresh mind.
Good luck.
Please report the problem, I harte it when people come here for help and never tell me what the solution was.

Hans W
_Spudtheimpaler
Guest







In response
PostPosted: Wed Mar 16, 2005 9:33 am     Reply with quote

Hi, thanks for looking over it.

I am setting the sensor values by putting (or not putting! ) a 5v wire directly into the input port. Also i knwo the lookup tables are correct because we have had the leds flashing / stepper motors stepping as they should.
The problem arises after number of certain orders of inputs are detected. Ie sensor setup is set to one case value, then a different case value, then returned to the original case value. The first two changes are implemented by the case switch, but the third is not.
I think the problem lies with the value "sensorValue". Though why input_d(); would work the first few times and not others i dont understand, and within the loop prior to input_d(); i am putting sensorValue(0x00);

Tis most confuzzling.

Promise to post my solution, though i have spent about 3 days on it now.

Ta

Mitch
_spudtheimpaler
Guest







hmmm
PostPosted: Wed Mar 16, 2005 9:48 am     Reply with quote

right

I have just tested this code

Code:
#include <16F877.h>
#use delay(clock=4000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT, NOLVP

int sensorValue =0x00;

main(void)
{
      set_tris_d(0xFF);
      set_tris_e(0x00);
      disable_interrupts(global);
      SETUP_ADC_PORTS(no_analogs);
     

   while(1)
   {
      sensorValue = input_d();
      delay_cycles(1);
      output_e(sensorValue);
      delay_cycles(1);
   }

}


And it is the sensorValue variable that is causing the trouble. The input_d() isn't always reading the sensorValue right or there is something happening within the chip screwing it up, but i cant think what! I mean look at the code, thats it in its entirety - so WHY is it screwing up? What am i missing? surely we can thave 3 busted chips?!
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Mar 16, 2005 10:21 am     Reply with quote

As told you Hans W, we need to know the hardware details of
the sensors that you mention.

I modiffied a little your code to enable you "to see" if the the sensors are
giving a unstable signal. I assume you have a set of Leds connected in
the output monitoring what is going on, you will see them blinking
accordingly.

Code:

#include <16F877.h>
#use delay(clock=4000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOLVP
#zero_ram
#use fast_io(d)
#use fast_io(e)

static int8 sensorValue;

main(void)
{
   set_tris_d(0xFF);
   set_tris_e(0x00);
   disable_interrupts(global);
   SETUP_ADC_PORTS(no_analogs);
     

   while(1)
     {
      sensorValue = input_d();
      delay_ms(80);
      output_e(sensorValue);
      delay_ms(80);
     }

}


Humberto
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Wed Mar 16, 2005 10:27 am     Reply with quote

Instead of reading port d and assigning what is read to a variable, why not double or even triple-check the portd reading?

What you're doing:

variable = input_d();

What I'd do:
Code:

no_match = TRUE;

while (no_match) {
   variable = input_d();
   delay_ms(15); // wait
   old_variable = variable;
   variable = input_d();
   if (variable == old_variable) {
      no_match = FALSE;
   }
}


Once this runs you can be reasonable sure that there isn't any input "bounce". Give it a shot and see what happens.
Guest








PostPosted: Wed Mar 16, 2005 11:31 am     Reply with quote

sensorValue=input_d();

did you mask off the bits you do not need before entering the switch? you are only using d0-d2. AND it with 0x07

switch(sensorValue&0x07)
_Spudtheimpaler
Guest







Definately something to try!
PostPosted: Wed Mar 16, 2005 11:49 am     Reply with quote

Hi,

I am not actually using any sensors. The program is designed for sensors, but at present we are jsut using 5v wires to touch the pins.

I am just trying the code newguy gave me

Code:
no_match = TRUE;

while (no_match) {
   variable = input_d();
   delay_ms(15); // wait
   old_variable = variable;
   variable = input_d();
   if (variable == old_variable) {
      no_match = FALSE;
   }
}



To no avail :(

Its still reading the input when i put 5v on the input pins, but still outputting the high values for extended periods.

I'll try and draw a diagram



Quote:


INPUT | OUTPUT

O O O O O O // all inputs outputs low

O O O O O O // Touch input with 5v
|
|

O X O O X O // Input goes high so output shows high
|
|

O O O O X O // Input goes low by removing the cable
//But output remains high for aprx 6-8 seconds.



I haven't yet added #zero_ram
#use fast_io(d)
#use fast_io(e)

because i'm nto sure what they do... what do they do?

I'll keep on posting though i've been on this all day now to no avail, so i'll be going home soon

Cheers

Mitch
edit
Guest







PostPosted: Wed Mar 16, 2005 11:51 am     Reply with quote

In the "quote" section above the

|
|

was set up for the middle O but the board stripped the leading spaces.

just so you know
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: Definately something to try!
PostPosted: Wed Mar 16, 2005 12:29 pm     Reply with quote

_Spudtheimpaler wrote:

Its still reading the input when i put 5v on the input pins, but still outputting the high values for extended periods.


Do you have pull down resistors or do you just assume the input will float low when power is removed.
_Spudtheimpaler
Guest







eeerrrrrrrr......
PostPosted: Wed Mar 16, 2005 2:43 pm     Reply with quote

I am assuming that when i take off the 5v from the input pins, it reads the pin as 0V... Is there some dissipation issues? does it take some time for the input voltage to leave the pin and are there resistor setups that will make this quicker? I've not been doing pic programming for all that long and whenever we have done it at uni before we are given a pre-fabricated board to test all our stuff on... This project was designed to "make us teach ourselves" and so this would be the infuriatingly simple kind of thing that i could miss...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group