Hello Everyone, I'm working on a rather large program for a corn planter for the upcoming planting season. For the sake of keeping the post short, I will try to only post the stuff relevant to the problem. i need to feed a PWM into the old school planter monitor and in the past I have just sent a constant signal to trick it into thinking i'm traveling at 3.5 mph I have deemed this "dummy mode" this year I have added a rotary encoder to the drive shaft to get shaft speed using the video on rotary encoders posted by drone bot. it is working great. I'm calling that "live mode" I want to be able to switch between dummy mode and live mode using a switch attached to a digital pin. Currently wired to trigger a high that would put me in live mode with a pull down resistor when the switch is off to keep the pin grounded forcing a low. Now to the problem. My program is stuck in live mode even when the pin is reading a low.
here is the portion of code I have. I'm using a TFT screen to display the output. the code below is in the void loop. this is the only code in the program that affects these variables so i'm not going to post the rest of the program, since this is already a super long post.
speed mode is an int, speedmode1 is a string so i can print it to the tft.
// Code for determining dummy mode/live mode
speedmode = digitalRead(9);
speedmode1 = speedmode;
myGLCD.setFont(SmallFont);
myGLCD.print( speedmode1 , 350, 50); // 0 = dummy mode and 1 = live mode --when switch is off, this is showing a 0 on the tft screen which is what i expect the pin is reading low. I assume this should trigger the dummy mode code below, but it doesn't.
if (speedmode = 0) {
dummymode ();
myGLCD.print(("DummyMode"),10, 200);
}
if (speedmode = 1){ --- this is getting triggered even if the switch is off.
livemode();
myGLCD.print(("livemode"),10,200);
}
a few other things to note. If I turn the toggle switch on then the speedmode1 variable switches from a 0 to a 1 and when i turn the switch off the speedmode1 variable switches back to a 0. So this is telling me that my digital pin is reading the switching as a 0 and a 1.
Does anyone know why my if statements are only acting as if speed mode is 1?? I have tried several things, and I will admit i'm at a loss.
My program is stuck in live mode even when the pin is reading a low.
here is the portion of code I have. I'm using a TFT screen to display the output. the code below is in the void loop. this is the only code in the program that affects these variables so i'm not going to post the rest of the program, since this is already a super long post.
speed mode is an int, speedmode1 is a string so i can print it to the tft.
if (speedmode = 0) {
dummymode ();
myGLCD.print(("DummyMode"),10, 200);
}if (speedmode = 1){ --- this is getting triggered even if the switch is off.
livemode();
myGLCD.print(("livemode"),10,200);
}
You are using an arithmetic operator (equals aka "=") where a logical operator (equals aka "==") is required.
So where you say "speed mode = 0)" it actually assigns the value 0 to speed mode, similarly it sets the value to 1 in the following test.
change the lines to
if (speedmode == 0) {
and
if (speedmode == 1) {
And try it again.
I had a psychic girlfriend but she left me before we met.
It's not stupid, it's extremely common. That's why it's easy to spot 🙂
I'm glad you're back on track.
I had a psychic girlfriend but she left me before we met.
@will Thank you so much!!!!! What a simple and stupid mistake. My programing is rusty, and apparently my frustration wasn't helping me think clearly.
I really appreciate it.
Been there, done that, bought the t-shirt many, many times! You are not alone! 😀
Honestly, I was zero'ed in on the harder part of the build to the point I overlooked the simple stuff. I probably will make a post show casing this lovely gadget when i'm done. it goes hand in hand with an old john deere computrak 200 planter monitor. To get seed population they used a radar sensor that was mounted to the planter, and my neighbor bought the planter that was missing it's radar sensor. Deere wanted something like $2900 for it, and I told him i could find a better/cheaper solution, so i have been working on this. The hard part i was focusing on was getting the pwm from Arduino just right going into the signal pin of the deere monitor so that the speed it read from the PWM was accurate.
@will Thank you so much!!!!! What a simple and stupid mistake. My programing is rusty, and apparently my frustration wasn't helping me think clearly.
I really appreciate it.
We had a discussion on this silent semantic error not too long ago.
When programming, if you can get into the habit of putting the literal to the left hand side of the operator, the compiler won't let you get away with it, because you can't assign to a literal - It will stop compiling and therefore alert you to the error immediately:
// Will not compile... if (1 = speedmode) { }
Cheers
@frogandtoad I don't recall ever seeing that, it's bloody brilliant! Our schools and textbooks need to change how they teach.
Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting
@frogandtoad I don't recall ever seeing that, it's bloody brilliant! Our schools and textbooks need to change how they teach.
It's a tip I picked up over the years - Simple yet effective.
Cheers
@frogandtoad So if i'm understanding you correctly. you are saying that in a comparison statement like this, you can put the literal to the right or left? ie. 1 == speedmode or speedmode == 1 would work the same way, but by doing 1 == speedmode the compiler will catch the error if one of the = is missing?
@frogandtoad So if i'm understanding you correctly. you are saying that in a comparison statement like this, you can put the literal to the right or left? ie. 1 == speedmode or speedmode == 1 would work the same way, but by doing 1 == speedmode the compiler will catch the error if one of the = is missing?
That's exactly what he is saying. 👍
Since "a equals b" implies "b equals a", the order of the values tested doesn't matter. So "b==1" and "1==b" are both meaningful and will always return the same result of the test
However, you can only assign a value to a variable, not to a literal value, so
b = 1; makes sense because we're filling the hole known as b with the value 1 but
1 = b is nonsense.
You can't assign a new value to a literal because "1" already has a distinct literal value that can't be modified.
Note that the compiler should also prevent you from assigning to a const value so:
const int myConst = 5;
if (const=6)
should also result in a nastygram from the compiler.
I had a psychic girlfriend but she left me before we met.
@will Good 2nd point Will. This is why it is important to call a variable by it's full nbame so to speak when declaring them. If it is in fact a constant then declaring it 'const' will stop you from making a mistake.
Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting
@fastrunner08 A good way to code it is simply:
if ( speedMode ) {
true condition here
}
else {
false here
}
Using:
if ( ! speedMode ) returns true when the condition if false
In the c language, any non-zero value is "true" and integer zero is false. Doesn't matter the data type of what you're testing. If you have a character value and test
if (myCharHere)
You will get true unless the value has been assigned to zero. Not the character representing zero, the number zero, like:
myCharhere = 0;
Don't use the == operator unless you need to check for a specific value, other than true or false. For example you might use if (myChar == 'j') This tests for the specific character 'j'
If you need to check a specific integer you can use if ( i == 99 ) Now the test is false for all values of i except 99
When the value is inherently boolean, such as the digital read, always use :
if (thingToTest)
You simply don't need the == operator at all.
You can't assign a new value to a literal because "1" already has a distinct literal value that can't be modified.
Note that the compiler should also prevent you from assigning to a const value so:
const int myConst = 5;
if (const=6)
should also result in a nastygram from the compiler.
Sorry for the late reply, was late and had to get some sleep.
@will has provided an excellent explanation - I'd just add that, a literal (if it wasn't already clear), is actually a constant! For example, 1 = 42? huh? How can we assign 42 to 1? We can't, because 1 is not a variable - it is actually a fixed constant set at compile time.
HTH,
Cheers