![]() |
Why it works with an underscore?
I have a code written up for my own custom encoder involving optical sensors, yes its a optical encoder, using quadrature.
My question is why the compiler will find a syntax error if I didn't use an underscore in my variables. For instance, I have this before: ------------------------------------------------------------- /*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/ unsigned char Sen1; unsigned char Sen2; unsigned char Sen3; unsigned char Sen4; unsigned char Sen5; ------------------------------------------------------------- along with ------------------------------------------------------------- void Process_Data_From_Local_IO(void) { Sen1 = rc_dig_in05; Sen2 = rc_dig_in06; Sen3 = rc_dig_in07; Sen4 = rc_dig_in08; Sen5 = rc_dig_in09; after I changed it to: ------------------------------------------------------------- /*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/ unsigned char Sen_1; unsigned char Sen_2; unsigned char Sen_3; unsigned char Sen_4; unsigned char Sen_5; ------------------------------------------------------------- void Process_Data_From_Local_IO(void) { Sen_1 = rc_dig_in05; Sen_2 = rc_dig_in06; Sen_3 = rc_dig_in07; Sen_4 = rc_dig_in08; Sen_5 = rc_dig_in09; ------------------------------------------------------------- Im new at programming so im open to harassment. ************************************************** *************** Another question is how do you set a value under certan conditions in programming? For instance, I have 5 sensors like the above. When all 5 sensors reads a certain encoding for example all 0's how do I set this reading to a specific digit, so I can later call up on again. This makes it easier for changing later due to so many sensor reading combinations. The idea im getting at is something like: if (rc_dig_in01 = 0,rc_dig_in02 = 0,rc_dig_in03 = 0,rc_dig_in04 = 0,rc_dig_in05 = 0) == 10 if (rc_dig_in01 = 0,rc_dig_in02 = 0,rc_dig_in03 = 0,rc_dig_in14 = 0,rc_dig_in15 = 1) == 20 and after all these are set, I can have another routine that can use those numbers: if (20) turn on solenoid 3 etc etc. |
Re: Why it works with an underscore?
Welcome to the quirkiness of the MCC18 compiler!
The compiler is known to choke for no apparent reason. Personally, I think it's a catch-all. Something goes wrong and it tosses a syntax error. |
Re: Why it works with an underscore?
#define is your best friend in MPLAB . . or at least your cool kinda crazy uncle
as in #define optical1 rc_dig_in05 as for your if statements commas are wrong you want ANDs(&&) so its if(blah == 0 && other == 0 && batman == 0) ohh also remember that = is assignment and == is compare |
Re: Why it works with an underscore?
Quote:
Nothing hurts more than to discover that a single = in an if statement actual assigns that value to that variable, rather than comparing it. I don't know why the underscore thing would be an issue; I know MPLAB tends to blow up on variables with spaces, but single words have always worked fine for me. It might have something to do with the fact you're using numbers in the name; you might need so many letters in your variable before you can use a number. |
Re: Why it works with an underscore?
Quote:
What a #define does is essentially does a find-replace on your code before it actually compiles, replacing all of 'optical1' (in this example) with 'rc_dig_in05'. It makes your code more readable because reading 'optical1' makes more sense than 'rc_dig_in05'. It uses no extra memory because you're still ACTUALLY using the already-declared rc_dig_in05 variable instead of making a new one. Further, if you #define all your stuff in the same place, it makes for a VERY useful section of code that definitively tells you what all your outputs/inputs are. Before I started using #defines to rename all my inputs/outputs, I dreaded the day when someone would ask "hey Bongle, what does the first optical sensor plug into?". You might answer something, then find out during a match you were wrong. This way, you just go to the .h where you #defined everything and say "oh, optical1 is defined to rc_dig_in05, so it goes on digital input 5". Finally, doing it that way might get around the silly MCC18 error you have right now :) As an example in real life, here's our #define section from 2006. We put it all in ifi_aliases.h at the bottom. Code:
#define turretpan pwm04 // turret left/right motion |
Re: Why it works with an underscore?
Quote:
Quote:
if ((rc_dig_in01 == 0) && (rc_dig_in02 == 0) && (rc_dig_in03 == 0) && (rc_dig_in04 == 0) && (rc_dig_in05 == 0)) { outputvariable = 10; } This follows the C syntax rule: if (expression) statement; (SINGLE statement) if (expression) { statement; statement; ... } (BLOCK of statements) There are other ways of writing this as well, but unless you are very experienced with C and the rules of operator precedence, liberal use of round brackets around each sub-expression will guarantee the multiple statements are evaluated in the manner and the order you expect. As Stuart said, it is a very common error to use if (rc_dig_01 = 0) rather than (rc_dig_01 == 0). The first form ASSIGNS the value 0 to rc_dig_01, the second COMPARES rc_dig_01 with 0. |
Re: Why it works with an underscore?
Ok, I see where my mistakes are, thanks a lot for all the help =D. I'll go edit my code right now.
|
Re: Why it works with an underscore?
Do I #define a name that I want to use and then in the routines use them there?
Can I: #define *Sensor_variable read* results in turning on solenoid 1 and 4 and 5 then later if this happens: if ((Sen_1 == 1) && (Sen_2 == 1) && (Sen_3 == 1) && (Sen_4 == 1) && (Sen_5 == 1)) { Sensor_variable read; } This way I can activate certain solenoids when my 5 sensors reads all 1's its soooo confusing...still trying to make the encoder work. |
Re: Why it works with an underscore?
#defines are very simple.
At their simplest (you can do a lot of wierd stuff with them, but that's for another day), you have: #define <text to replace> <text to replace with> So if you did #define *Sensor_variable read* Then anytime you typed "*Sensor_variable", it would replace it with "read*". Unless you didn't mean the asterisks to be there, then it would do the same thing without the asterisks. This means you can do things like #define test pwm01; The preprocessor (thing that processes everything that starts with #) doesn't care WHAT you put after the first argument to a define, it will go to the end of the line and replace all instances of "test" with "pwm01;". Note that the semicolon is in there. That means that if you wrote test = 5; Then after the preprocessor was done, it'd look like pwm01; = 5; // compile error woo-hoo because it replaced "test" with "pwm01;". So be careful of what you put as the second argument to #define, or else it might not make sense. For a good example of #defines, take a look at the given code in ifi_aliases.h. The entire file is IFI just re-defining big ugly expressions as easy-to-use things like pwm01, pwm02, rc_dig_in01, etc. You just need to do the same thing. |
Re: Why it works with an underscore?
Is it possible to define something and have a set of commands built into it?
Something like this? #define Setting_1 ((solenoid1 = 1) && (Solenoid2 = 0) && (solenoid3 = 1) && (solenoid4 = 0) && (solenoid5 = 0) && (solenoid6 = 0)); will this allow me to do.... if (Sensors_are_online); { Setting_1 } basically if the sensor receives a signal, it would turn on setting_1 which is to turn solenoid 1 and solenoid 3 on. |
Re: Why it works with an underscore?
Quote:
By the way, you don't need a semicolon after the if (Sensors_are_online) statement. In general, any sort of construct that uses curly braces does not have a semicolon for itself. Rather, the individual statements within the braces have semicolons at the end of them. |
Re: Why it works with an underscore?
NVM that last one I got it figured out, it was just a simple ";" mistake, I added an extra ; at the end of the text to replace.
Alright heres the new problem... I have a bunch of if statements and they rely on a bunch of sensors, when these sensors read a certain set of digital values it would turn on certain solenoids, correct, but! if these digital values from the sensors changed (knowing this from printf), the solenoids stay the same. They do not change with the input:eek: so I'm guessing that I'm doing something wrong with the if statements. I have a lot of if's and in the very bottom on all the if statements, there would be an else if statement to eliminate any other undefined sensor readings. any suggestions to what I'm doing wrong? ************************************************** ************ Ah! yes, I found the mistakes there, I've been reading the powerpoint tutorials from IFI and it got me confused. I start putting ; and brackets all over the place....I'll remember it for next time. |
Re: Why it works with an underscore?
You can also use #define in your header files
#ifndef header_h__ #define header_h_ stuff stuff stuff #endif Then if you put #include "header.h" more then once it will say hey! header_h__ is already defined stupid! you can't define it again!! and just exit........:eek: |
Re: Why it works with an underscore?
Quote:
You could use a switch loop. **Somebody please correct me if I am wrong, I don't remember is switch is only C++ or c too. |
Re: Why it works with an underscore?
Quote:
But don't do it with a #define. What you're probably looking for is a function that will do what you want. Code:
void Setting_1(void) |
Re: Why it works with an underscore?
Quote:
Code:
/* Setting_1 - Turn on solenoids 1&3 only */Some additional advice for you and others reading this thread:
|
Re: Why it works with an underscore?
I'll also point out that #defines, although pretty useful in some cases, can make code very hard to read, which is important if you ever have someone helping you with it.
For example, your Setting_1 thing affects a LOT of variables, but someone coming along and reading the code would have no idea. They'd see "Setting_1;". It wouldn't look like a function and it wouldn't have any apparent assignments, but because of the #define it actually affects 6 different variables. At the very least, you should have the #define named such that it is apparent it changes something. One of my coworkers at Sony really likes making complicated #defines. They make code REALLY hard to read until he explains what each one does. Code:
((solenoid1 = 1) && (Solenoid2 = 0) && (solenoid3 = 1) && (solenoid4 = 0) && (solenoid5 = 0) && (solenoid6 = 0));What follows below is completely tangential and is only for added knowledge *Depending on the compiler, it may short-circuit the condition statement if one of the arguments in an && block is false. Since ALL conditions must be true for your condition to work out (because they are all anded together), then as soon as it encounters one that returns zero (Solenoid2 = 0) it may exit the condition and return zero. Basically, when your program is run, it will do this: Assigns solenoid1 = 1 (result: 1) Assigns solenoid2 = 0 (result: 0) **ANDS the first two expressions together (result: 0 && 1 is 0) Assigns solenoid3 = 1 (result: 1) ANDS the third expression with result from first 2 (result: 0 && 1 is 0) Assigns solenoid4 = 0 (result: 0) ANDS the fourth expression with result from first 3 (result: 0 && 0 is 0) Assigns solenoid5 = 0 (result: 0) ANDS the fifth expression with result from first 4 (result: 0 && 0 is 0) Assigns solenoid6 = 0 (result: 0) ANDS the sixth expression with result from first 5 (result: 0 && 0 is 0) At **, the program KNOWS that the final result is going to be zero because one condition in a series of logical ands resulted in zero, so depending on the compiler, it might just save time and skip doing the rest. |
Re: Why it works with an underscore?
It compiles now, but its still not responding to the changes in the sensors. If one of the sensors changed signals and this setting is defined as setting_2 below, it does not change the settings for the solenoids.
This is how im using the codes: #define Setting_1 solenoid1 = 1;solenoid2 = 0; solenoid3 = 1;solenoid4 = 0; solenoid5 = 0; solenoid6 = 1 #define Setting_2 solenoid1 = 0;solenoid2 = 1; solenoid3 = 0;solenoid4 = 1; solenoid5 = 1; solenoid6 = 0 if ((Senor1 = 1) && (Sensor2 = 1) && (Sensor3 = 1) && (Sensor4 = 1) && (Sensor5 = 1)) { Setting_1; } if ((Senor1 = 1) && (Sensor2 = 1) && (Sensor3 = 1) && (Sensor4 = 1) && (Sensor5 = 0)) { Setting_2; } :confused: |
Re: Why it works with an underscore?
Quote:
(x==y) returns a true or false value based on the equality of x and y, but (x=y), like you have here, returns whatever y is equal to, which in this case is 1 (or 0 for one of them) (0 represents false, and anything besides 0 represents true). Therefore you're always entering the first if statement because all of the conditions always return "1", whereas the second one is never reached because "sensor5=0" always returns 0. Hope this was helpful. |
Re: Why it works with an underscore?
Wonderful! That makes sense, I've been reminded of this before and again have forgotten. Thanks for the help!:D
|
| All times are GMT -5. The time now is 20:47. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi